# coding: utf-8

# (C) Copyright IBM Corp. 2025.
#
# 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.99.0-d27cee72-20250129-204831

"""
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 BinaryIO, Dict, List, Optional
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 DirectLinkV1(BaseService):
    """The Direct Link V1 service."""

    DEFAULT_SERVICE_URL = 'https://directlink.cloud.ibm.com/v1'
    DEFAULT_SERVICE_NAME = 'direct_link'

    @classmethod
    def new_instance(
        cls,
        version: str,
        service_name: str = DEFAULT_SERVICE_NAME,
    ) -> 'DirectLinkV1':
        """
        Return a new client for the Direct Link 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 2019-12-13 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 service.

        :param str version: Requests the version of the API as a date in the format
               `YYYY-MM-DD`. Any date from 2019-12-13 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

    #########################
    # Gateways
    #########################

    def list_gateways(
        self,
        **kwargs,
    ) -> DetailedResponse:
        """
        List gateways.

        List all Direct Link gateways in this account.  Gateways in other accounts with
        connections to networks in this account are also returned.

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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_gateway(
        self,
        gateway_template: 'GatewayTemplate',
        **kwargs,
    ) -> DetailedResponse:
        """
        Create gateway.

        Creates a Direct Link gateway based on the supplied template.

        :param GatewayTemplate gateway_template: The Direct Link Gateway template.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Gateway` object
        """

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

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete gateway.

        Delete a Direct Link gateway.

        :param str id: Direct Link 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_gateway',
        )
        headers.update(sdk_headers)

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

        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 = '/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_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Get gateway.

        Retrieve a Direct Link gateway.

        :param str id: Direct Link 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 `GetGatewayResponse` 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_gateway',
        )
        headers.update(sdk_headers)

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

        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 = '/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_gateway(
        self,
        id: str,
        gateway_patch_template: 'GatewayPatchTemplate',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update gateway.

        Update a Direct Link gateway.

        :param str id: Direct Link gateway identifier.
        :param GatewayPatchTemplate gateway_patch_template: The Direct Link 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 `Gateway` object
        """

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

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

        data = json.dumps(gateway_patch_template)
        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 = '/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 create_gateway_action(
        self,
        id: str,
        *,
        action: Optional[str] = None,
        as_prepends: Optional[List['AsPrependTemplate']] = None,
        authentication_key: Optional['AuthenticationKeyIdentity'] = None,
        bfd_config: Optional['GatewayBfdConfigActionTemplate'] = None,
        connection_mode: Optional[str] = None,
        default_export_route_filter: Optional[str] = None,
        default_import_route_filter: Optional[str] = None,
        export_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        global_: Optional[bool] = None,
        import_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        metered: Optional[bool] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        updates: Optional[List['GatewayActionTemplateUpdatesItem']] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Approve or reject change requests.

        Approve or reject a gateway's current oustanding change request.
        This API is only used for provider created Direct Link Connect gateways to approve
        or reject specific changes initiated from a provider portal.

        :param str id: Direct Link Connect gateway identifier.
        :param str action: (optional) Action request.
        :param List[AsPrependTemplate] as_prepends: (optional) Applicable for
               create_gateway_approve requests to create AS Prepends. Contains an array of
               AS Prepend configuration information.
        :param AuthenticationKeyIdentity authentication_key: (optional)
        :param GatewayBfdConfigActionTemplate bfd_config: (optional) Applicable for
               create_gateway_approve requests to select the gateway's BFD configuration
               information.
        :param str connection_mode: (optional) Applicable for
               create_gateway_approve requests to select the type of services this gateway
               is attached to. Mode transit indicates this gateway will be attached to
               Transit Gateway Service and direct means this gateway will be attached to
               vpc or classic connection. If unspecified on create_gateway_approve,
               default value direct is used. The list of enumerated values for this
               property may expand in the future. Code and processes using this field must
               tolerate unexpected values.
        :param str default_export_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param str default_import_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param List[GatewayTemplateRouteFilter] export_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param bool global_: (optional) Applicable for create_gateway_approve
               requests to select the gateway's routing option. Gateways with global
               routing (`true`) can connect to networks outside of their associated
               region.
        :param List[GatewayTemplateRouteFilter] import_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param bool metered: (optional) Applicable for create_gateway_approve
               requests to select the gateway's metered billing option.  When `true`
               gateway usage is billed per gigabyte.  When `false` there is no per
               gigabyte usage charge, instead a flat rate is charged for the gateway.
        :param ResourceGroupIdentity resource_group: (optional) Set for
               create_gateway_approve requests to select the gateway's resource group.  If
               unspecified on create_gateway_approve, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        :param List[GatewayActionTemplateUpdatesItem] updates: (optional) Specify
               attribute updates being approved or rejected, update_attributes_approve and
               update_attributes_reject actions must provide an updates field that matches
               the gateway's current pending changes.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `Gateway` object
        """

        if not id:
            raise ValueError('id must be provided')
        if as_prepends is not None:
            as_prepends = [convert_model(x) for x in as_prepends]
        if authentication_key is not None:
            authentication_key = convert_model(authentication_key)
        if bfd_config is not None:
            bfd_config = convert_model(bfd_config)
        if export_route_filters is not None:
            export_route_filters = [convert_model(x) for x in export_route_filters]
        if import_route_filters is not None:
            import_route_filters = [convert_model(x) for x in import_route_filters]
        if resource_group is not None:
            resource_group = convert_model(resource_group)
        if updates is not None:
            updates = [convert_model(x) for x in updates]
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_gateway_action',
        )
        headers.update(sdk_headers)

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

        data = {
            'action': action,
            'as_prepends': as_prepends,
            'authentication_key': authentication_key,
            'bfd_config': bfd_config,
            'connection_mode': connection_mode,
            'default_export_route_filter': default_export_route_filter,
            'default_import_route_filter': default_import_route_filter,
            'export_route_filters': export_route_filters,
            'global': global_,
            'import_route_filters': import_route_filters,
            'metered': metered,
            'resource_group': resource_group,
            'updates': updates,
        }
        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 = '/gateways/{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_gateway_completion_notice(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Get completion notice.

        Retrieve a Direct Link Dedicated gateway's completion notice.

        :param str id: Direct Link Dedicated 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 `BinaryIO` 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='list_gateway_completion_notice',
        )
        headers.update(sdk_headers)

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

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

        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}/completion_notice'.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_gateway_completion_notice(
        self,
        id: str,
        *,
        upload: Optional[BinaryIO] = None,
        upload_content_type: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create completion notice.

        Upload a Direct Link Dedicated gateway completion notice.

        :param str id: Direct Link Dedicated gateway identifier.
        :param BinaryIO upload: (optional) Completion notice PDF file.
        :param str upload_content_type: (optional) The content type of upload.
        :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='create_gateway_completion_notice',
        )
        headers.update(sdk_headers)

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

        form_data = []
        if upload:
            form_data.append(('upload', (None, upload, upload_content_type or 'application/octet-stream')))

        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 = '/gateways/{id}/completion_notice'.format(**path_param_dict)
        request = self.prepare_request(
            method='PUT',
            url=url,
            headers=headers,
            params=params,
            files=form_data,
        )

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

    def list_gateway_letter_of_authorization(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Get letter of authorization.

        Retrieve a Direct Link Dedicated gateway's Letter of Authorization.

        :param str id: Direct Link Dedicated 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 `BinaryIO` 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='list_gateway_letter_of_authorization',
        )
        headers.update(sdk_headers)

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

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

        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}/letter_of_authorization'.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_gateway_statistics(
        self,
        id: str,
        type: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Gateway statistics/debug information.

        Retrieve gateway statistics or debug information.  Specify statistic to retrieve
        using required `type` query parameter.

        :param str id: Direct Link gateway identifier.
        :param str type: Specify statistic to retrieve.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `GatewayStatisticCollection` object
        """

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

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

        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 = '/gateways/{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 get_gateway_status(
        self,
        id: str,
        *,
        type: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Gateway status information.

        Retrieve gateway status.  Specify status to retrieve using required `type` query
        parameter.

        :param str id: Direct Link gateway identifier.
        :param str type: (optional) Specify status to retrieve.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `GatewayStatusCollection` 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_gateway_status',
        )
        headers.update(sdk_headers)

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

        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 = '/gateways/{id}/status'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

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

    #########################
    # Gateway AS Prepends
    #########################

    def list_gateway_as_prepends(
        self,
        gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List AS Prepends.

        Retrieve all AS Prepends for the specified Direct Link gateway.

        :param str gateway_id: Direct Link 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 `AsPrependCollection` object
        """

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

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

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

        path_param_keys = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/as_prepends'.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_gateway_as_prepends(
        self,
        gateway_id: str,
        if_match: str,
        *,
        as_prepends: Optional[List['AsPrependPrefixArrayTemplate']] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Replace existing AS Prepends.

        Replace the given set of AS prepends on the specified gateway.  Existing resources
        may be reused when the individual AS Prepend item is unchanged.

        :param str gateway_id: Direct Link gateway identifier.
        :param str if_match: If present, the request will fail if the specified
               ETag value does not match the resource's current ETag value.
        :param List[AsPrependPrefixArrayTemplate] as_prepends: (optional) array of
               AS Prepend configuration information.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `AsPrependCollection` object
        """

        if not gateway_id:
            raise ValueError('gateway_id must be provided')
        if not if_match:
            raise ValueError('if_match must be provided')
        if as_prepends is not None:
            as_prepends = [convert_model(x) for x in as_prepends]
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='replace_gateway_as_prepends',
        )
        headers.update(sdk_headers)

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

        data = {
            'as_prepends': as_prepends,
        }
        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 = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/as_prepends'.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

    #########################
    # Gateway Export Route Filters
    #########################

    def list_gateway_export_route_filters(
        self,
        gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List export route filters.

        List all export route filters that influence the export routes advertised to the
        on premises network and learned from attached virtual connections of the Direct
        Link gateway.
        The first export route filter an export route matches will determine whether the
        route is permitted or denied to be advertised by the Direct Link gateway. Route
        filter order is determined by the filter's `before` field.
        If an export route does not match any of the export route filters, the route is
        subject to the `default_export_route_filter` of the direct link.

        :param str gateway_id: Direct Link 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 `ExportRouteFilterCollection` object
        """

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

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

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

        path_param_keys = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/export_route_filters'.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_gateway_export_route_filter(
        self,
        gateway_id: str,
        action: str,
        prefix: str,
        *,
        before: Optional[str] = None,
        ge: Optional[int] = None,
        le: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create an export route filter.

        Create a new export route filter to be configured on the Direct Link gateway.
        This call can result in an implicit update to another route filter's `before`
        field.
        If the request's route filter template does not contain a `before` field, the
        created filter will be added to the end of of the list. The filter previously at
        the end of the list will have it's `before` field set to the created route filter.
        If the request's route filter template contains a `before` field, the created
        filter will be added directly before that specified route filter. If the specified
        route filter has a preceding route filter, that filter's `before` field is updated
        to the created route filter.

        :param str gateway_id: Direct Link gateway identifier.
        :param str action: Determines whether routes that match the prefix-set will
               be allowed (permit) or rejected (deny) through the filter.
        :param str prefix: IP prefix representing an address and mask length of the
               prefix-set.
        :param str before: (optional) Identifier of the next route filter
               considered if a route does not match the current filter. This property
               builds the ordering among route filters and follows semantics:
               - When before is an identifier of a route filter that exists and is in the
               same collection, a route will first attempt to match on the current filter
               before preceding to the filter referenced in this property.
               - When a filter is created with before that matches another filter in the
               same collection, the existing filter will take precedence. The before of
               the existing filter will be updated to refer to the newly created filter.
               The newly created filter will refer to the route filter identified by the
               provided before.
               - When a filter is created without a before, it takes the lowest
               precedence. The existing filter of lowest precedence will be updated to
               refer to the newly created filter.
        :param int ge: (optional) The minimum matching length of the prefix-set
               (mnemonic for greater than or equal to).
        :param int le: (optional) The maximum matching length of the prefix-set
               (mnemonic for less than or equal 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 `RouteFilter` object
        """

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

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

        data = {
            'action': action,
            'prefix': prefix,
            'before': before,
            'ge': ge,
            'le': le,
        }
        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 = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/export_route_filters'.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_gateway_export_route_filters(
        self,
        gateway_id: str,
        if_match: str,
        *,
        export_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Replace existing export route filters.

        Replace all existing export route filters configured on the Direct Link gateway.

        :param str gateway_id: Direct Link gateway identifier.
        :param str if_match: If present, the request will fail if the specified
               ETag value does not match the resource's current ETag value.
        :param List[GatewayTemplateRouteFilter] export_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ExportRouteFilterCollection` object
        """

        if not gateway_id:
            raise ValueError('gateway_id must be provided')
        if not if_match:
            raise ValueError('if_match must be provided')
        if export_route_filters is not None:
            export_route_filters = [convert_model(x) for x in export_route_filters]
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='replace_gateway_export_route_filters',
        )
        headers.update(sdk_headers)

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

        data = {
            'export_route_filters': export_route_filters,
        }
        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 = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/export_route_filters'.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_gateway_export_route_filter(
        self,
        gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Remove export route filter from Direct Link gateway.

        Delete an export route filter.
        Deleting an export route filter will implicitly update the preceding filter's
        `before` field to the filter that follows the deleted filter. The preceding filter
        will result with an empty `before` field if there is no filter following the
        deleted route filter.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: Identifier of an import route filter.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not gateway_id:
            raise ValueError('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_gateway_export_route_filter',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/export_route_filters/{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_gateway_export_route_filter(
        self,
        gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves the specified Direct Link gateway export route filter.

        Retrieve an export route filter from the Direct Link gateway.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: Identifier of an import route filter.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RouteFilter` object
        """

        if not gateway_id:
            raise ValueError('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_gateway_export_route_filter',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/export_route_filters/{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_gateway_export_route_filter(
        self,
        gateway_id: str,
        id: str,
        update_route_filter_template: 'UpdateRouteFilterTemplate',
        **kwargs,
    ) -> DetailedResponse:
        """
        Updates the specified Direct Link gateway export route filter.

        Update an export route filter from the Direct Link gateway.
        Updating a route filter's `before` field will result in implicit updates to other
        route filters' `before` fields.
        Considering the updated filter prior to the update, the preceding route filter's
        `before` field will be set to the filter following the updating route filter, if
        present. Otherwise it is set to empty.
        Considering the updated filter after the update, if the new filter following the
        updated filter has an existing filter preceding it, that preceding filter's
        `before` field will be set to the updated filter.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: Identifier of an import route filter.
        :param UpdateRouteFilterTemplate update_route_filter_template: The export
               route filter update template.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RouteFilter` object
        """

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

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

        data = json.dumps(update_route_filter_template)
        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 = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/export_route_filters/{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

    #########################
    # Gateway Import Route Filters
    #########################

    def list_gateway_import_route_filters(
        self,
        gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List import route filters.

        List all import route filters that influence the import routes learned from the on
        premises network.
        The first import route filter an import route matches will determine whether the
        route is permitted or denied to be learned by the Direct Link gateway. Route
        filter order is determined by the filter's `before` field.
        If an import route does not match any of the import route filters, the route is
        subject to the `default_import_route_filter` of the direct link.

        :param str gateway_id: Direct Link 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 `ImportRouteFilterCollection` object
        """

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

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

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

        path_param_keys = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/import_route_filters'.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_gateway_import_route_filter(
        self,
        gateway_id: str,
        action: str,
        prefix: str,
        *,
        before: Optional[str] = None,
        ge: Optional[int] = None,
        le: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create an import route filter.

        Create a new import route filter to be configured on the Direct Link gateway.
        This call can result in an implicit update to another route filter's `before`
        field.
        If the request's route filter template does not contain a `before` field, the
        created filter will be added to the end of of the list. The filter previously at
        the end of the list will have it's `before` field set to the created route filter.
        If the request's route filter template contains a `before` field, the created
        filter will be added directly before that specified route filter. If the specified
        route filter has a preceding route filter, that filter's `before` field is updated
        to the created route filter.

        :param str gateway_id: Direct Link gateway identifier.
        :param str action: Determines whether routes that match the prefix-set will
               be allowed (permit) or rejected (deny) through the filter.
        :param str prefix: IP prefix representing an address and mask length of the
               prefix-set.
        :param str before: (optional) Identifier of the next route filter
               considered if a route does not match the current filter. This property
               builds the ordering among route filters and follows semantics:
               - When before is an identifier of a route filter that exists and is in the
               same collection, a route will first attempt to match on the current filter
               before preceding to the filter referenced in this property.
               - When a filter is created with before that matches another filter in the
               same collection, the existing filter will take precedence. The before of
               the existing filter will be updated to refer to the newly created filter.
               The newly created filter will refer to the route filter identified by the
               provided before.
               - When a filter is created without a before, it takes the lowest
               precedence. The existing filter of lowest precedence will be updated to
               refer to the newly created filter.
        :param int ge: (optional) The minimum matching length of the prefix-set
               (mnemonic for greater than or equal to).
        :param int le: (optional) The maximum matching length of the prefix-set
               (mnemonic for less than or equal 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 `RouteFilter` object
        """

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

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

        data = {
            'action': action,
            'prefix': prefix,
            'before': before,
            'ge': ge,
            'le': le,
        }
        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 = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/import_route_filters'.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_gateway_import_route_filters(
        self,
        gateway_id: str,
        if_match: str,
        *,
        import_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Replace existing import route filters.

        Replace all existing import route filters configured on the Direct Link gateway.

        :param str gateway_id: Direct Link gateway identifier.
        :param str if_match: If present, the request will fail if the specified
               ETag value does not match the resource's current ETag value.
        :param List[GatewayTemplateRouteFilter] import_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `ImportRouteFilterCollection` object
        """

        if not gateway_id:
            raise ValueError('gateway_id must be provided')
        if not if_match:
            raise ValueError('if_match must be provided')
        if import_route_filters is not None:
            import_route_filters = [convert_model(x) for x in import_route_filters]
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='replace_gateway_import_route_filters',
        )
        headers.update(sdk_headers)

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

        data = {
            'import_route_filters': import_route_filters,
        }
        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 = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/import_route_filters'.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_gateway_import_route_filter(
        self,
        gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Remove import route filter from Direct Link gateway.

        Delete an import route filter.
        Deleting an import route filter will implicitly update the preceding filter's
        `before` field to the filter that follows the deleted filter. The preceding filter
        will result with an empty `before` field if there is no filter following the
        deleted route filter.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: Identifier of an import route filter.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

        if not gateway_id:
            raise ValueError('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_gateway_import_route_filter',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/import_route_filters/{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_gateway_import_route_filter(
        self,
        gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves the specified Direct Link gateway import route filter.

        Retrieve an import route filter from the Direct Link gateway.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: Identifier of an import route filter.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RouteFilter` object
        """

        if not gateway_id:
            raise ValueError('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_gateway_import_route_filter',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/import_route_filters/{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_gateway_import_route_filter(
        self,
        gateway_id: str,
        id: str,
        update_route_filter_template: 'UpdateRouteFilterTemplate',
        **kwargs,
    ) -> DetailedResponse:
        """
        Updates the specified Direct Link gateway import route filter.

        Update an import route filter from the Direct Link gateway.
        Updating a route filter's `before` field will result in implicit updates to other
        route filters' `before` fields.
        Considering the updated filter prior to the update, the preceding route filter's
        `before` field will be set to the filter following the updating route filter, if
        present. Otherwise it is set to empty.
        Considering the updated filter after the update, if the new filter following the
        updated filter has an existing filter preceding it, that preceding filter's
        `before` field will be set to the updated filter.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: Identifier of an import route filter.
        :param UpdateRouteFilterTemplate update_route_filter_template: The import
               route filter update template.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RouteFilter` object
        """

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

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

        data = json.dumps(update_route_filter_template)
        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 = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/import_route_filters/{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

    #########################
    # Gateway MACsec
    #########################

    def unset_gateway_macsec(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Unset MACsec configuration.

        Removes the MACsec configuration from a direct link, disabling the features.

        :param str id: Direct Link 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='unset_gateway_macsec',
        )
        headers.update(sdk_headers)

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

        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 = '/gateways/{id}/macsec'.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_gateway_macsec(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Get MACsec configuration.

        Retrieve the MACsec configuration of a direct link.

        :param str id: Direct Link 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 `GatewayMacsec` 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_gateway_macsec',
        )
        headers.update(sdk_headers)

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

        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 = '/gateways/{id}/macsec'.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_gateway_macsec(
        self,
        id: str,
        gateway_macsec_patch: 'GatewayMacsecPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update MACsec configuration.

        Updates the MACsec configuration on a direct link.

        :param str id: Direct Link gateway identifier.
        :param GatewayMacsecPatch gateway_macsec_patch: The MACsec configuration
               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 `GatewayMacsec` object
        """

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

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

        data = json.dumps(gateway_macsec_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 = '/gateways/{id}/macsec'.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 set_gateway_macsec(
        self,
        id: str,
        active: bool,
        caks: List['GatewayMacsecCakPrototype'],
        sak_rekey: 'SakRekeyPrototype',
        security_policy: str,
        *,
        window_size: Optional[int] = None,
        if_match: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Set MACsec configuration.

        Sets the MACsec configuration on a direct link, enabling the feature.

        :param str id: Direct Link gateway identifier.
        :param bool active: Determines if the MACsec feature should initially be
               active (true) or inactive (false) for a gateway.
        :param List[GatewayMacsecCakPrototype] caks: List of all connectivity
               association keys (CAKs) to be associated associated with the MACsec feature
               on a direct link.
               There must be at least one CAK with `session`: `primary`. There can be at
               most one CAK with `session`: `fallback`
               All CAKs must reference a unique key.
        :param SakRekeyPrototype sak_rekey: Determines how SAK rekeying occurs. It
               is either timer based or based on the amount of used packet numbers.
        :param str security_policy: Determines how packets without MACsec headers
               are handled.
               `must_secure` - Packets without MACsec headers are dropped. This policy
               should be used to prefer security over network availability.
               `should_secure` - Packets without MACsec headers are allowed. This policy
               should be used to prefer network availability over security.
        :param int window_size: (optional) The window size determines the number of
               frames in a window for replay protection.
               Replay protection is used to counter replay attacks. Frames within a window
               size can be out of order and are not replay protected.
        :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.
               `If-Match` is required when the resource exists and has an 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 `GatewayMacsec` object
        """

        if not id:
            raise ValueError('id must be provided')
        if active is None:
            raise ValueError('active must be provided')
        if caks is None:
            raise ValueError('caks must be provided')
        if sak_rekey is None:
            raise ValueError('sak_rekey must be provided')
        if security_policy is None:
            raise ValueError('security_policy must be provided')
        caks = [convert_model(x) for x in caks]
        sak_rekey = convert_model(sak_rekey)
        headers = {
            'If-Match': if_match,
        }
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='set_gateway_macsec',
        )
        headers.update(sdk_headers)

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

        data = {
            'active': active,
            'caks': caks,
            'sak_rekey': sak_rekey,
            'security_policy': security_policy,
            'window_size': window_size,
        }
        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 = '/gateways/{id}/macsec'.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_gateway_macsec_caks(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List MACsec CAKs.

        List the CAKs associated with the MACsec configuration of a direct link.

        :param str id: Direct Link 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 `GatewayMacsecCakCollection` 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_gateway_macsec_caks',
        )
        headers.update(sdk_headers)

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

        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 = '/gateways/{id}/macsec/caks'.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_gateway_macsec_cak(
        self,
        id: str,
        key: 'HpcsKeyIdentity',
        name: str,
        session: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create MACsec CAK.

        Creates a CAK associated with the MACsec configuration of a direct link.

        :param str id: Direct Link gateway identifier.
        :param HpcsKeyIdentity key: A [Hyper Protect Crypto Service Standard
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
        :param str name: The name identifies the connectivity association key (CAK)
               within the MACsec key chain.
               The CAK's `name` must be a hexadecimal string of even lengths between 2 to
               64 inclusive.
               This value, along with the material of the `key`, must match on the MACsec
               peers.
        :param str session: The intended session the key will be used to secure.
               If the `primary` MACsec session fails due to a key/key name mismatch on the
               peers, the `fallback` session can take over.
               There must be a `primary` session CAK. A `fallback` CAK is optional.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `GatewayMacsecCak` object
        """

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

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

        data = {
            'key': key,
            'name': name,
            'session': session,
        }
        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 = '/gateways/{id}/macsec/caks'.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_gateway_macsec_cak(
        self,
        id: str,
        cak_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete MACsec CAK.

        Deletes the CAK from the MACsec configuration of a direct link.

        :param str id: Direct Link gateway identifier.
        :param str cak_id: MACsec CAK 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')
        if not cak_id:
            raise ValueError('cak_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_gateway_macsec_cak',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['id', 'cak_id']
        path_param_values = self.encode_path_vars(id, cak_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{id}/macsec/caks/{cak_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_gateway_macsec_cak(
        self,
        id: str,
        cak_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Get MACsec CAK.

        Get a MACsec CAK by its identifier.

        :param str id: Direct Link gateway identifier.
        :param str cak_id: MACsec CAK identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `GatewayMacsecCak` object
        """

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

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

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

        path_param_keys = ['id', 'cak_id']
        path_param_values = self.encode_path_vars(id, cak_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{id}/macsec/caks/{cak_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_gateway_macsec_cak(
        self,
        id: str,
        cak_id: str,
        gateway_macsec_cak_patch: 'GatewayMacsecCakPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update MACsec CAK.

        Updates the CAK on the MACsec configuration of a direct link.

        :param str id: Direct Link gateway identifier.
        :param str cak_id: MACsec CAK identifier.
        :param GatewayMacsecCakPatch gateway_macsec_cak_patch: The MACsec CAK
               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 `GatewayMacsecCak` object
        """

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

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

        data = json.dumps(gateway_macsec_cak_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', 'cak_id']
        path_param_values = self.encode_path_vars(id, cak_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{id}/macsec/caks/{cak_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

    #########################
    # Gateway Route Reports
    #########################

    def list_gateway_route_reports(
        self,
        gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List route reports.

        Retrieve all route reports for the specified Direct Link gateway.

        :param str gateway_id: Direct Link 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 `RouteReportCollection` object
        """

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

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

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

        path_param_keys = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/route_reports'.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_gateway_route_report(
        self,
        gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Request a route report.

        Request route report generation.  While report generation is in progress,
        additional requests to generate a report are ignored and return the current
        pending report. While `status` is `pending`, `gateway_routes`, `on_prem_routes`,
        `virtual_connection_routes`, and `overlapping_routes` will be empty arrays. These
        fields will be filled when the `status` enters the `complete` status.  Call
        `get_gateway_route_report` with the pending route report's `id` to check on the
        current status of the report.

        :param str gateway_id: Direct Link 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 `RouteReport` object
        """

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

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

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

        path_param_keys = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/route_reports'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
        )

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

    def delete_gateway_route_report(
        self,
        gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete route report.

        Delete a route report.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: Route report 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 gateway_id:
            raise ValueError('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_gateway_route_report',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/route_reports/{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_gateway_route_report(
        self,
        gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieve route report.

        Retrieve a route report.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: Route report identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `RouteReport` object
        """

        if not gateway_id:
            raise ValueError('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_gateway_route_report',
        )
        headers.update(sdk_headers)

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

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

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

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

    #########################
    # Virtual Connections
    #########################

    def list_gateway_virtual_connections(
        self,
        gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List virtual connections.

        List a gateway's virtual connections.   For gateway in other account with virtual
        connections that connect to network in this account.  Only virtual connections
        that connect to this account are returned.

        :param str gateway_id: Direct Link 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 `GatewayVirtualConnectionCollection` object
        """

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

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

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

        path_param_keys = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/virtual_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_gateway_virtual_connection(
        self,
        gateway_id: str,
        name: str,
        type: str,
        *,
        network_id: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Create virtual connection.

        Create a virtual connection to the specified network.

        :param str gateway_id: Direct Link gateway identifier.
        :param str name: The user-defined name for this virtual connection.
               Virtual connection names are unique within a gateway.  This is the name of
               the virtual connection itself, the network being connected may have its own
               name attribute.
        :param str type: The type of virtual connection.
        :param str network_id: (optional) Unique identifier of the target network.
               For type=vpc virtual connections this is the CRN of the target VPC.  This
               field does not apply to type=classic connections.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `GatewayVirtualConnection` object
        """

        if not gateway_id:
            raise ValueError('gateway_id must be provided')
        if name is None:
            raise ValueError('name 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_gateway_virtual_connection',
        )
        headers.update(sdk_headers)

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

        data = {
            'name': name,
            'type': type,
            'network_id': network_id,
        }
        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 = ['gateway_id']
        path_param_values = self.encode_path_vars(gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/virtual_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_gateway_virtual_connection(
        self,
        gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Delete virtual connection.

        Delete the virtual connection.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: The virtual 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 gateway_id:
            raise ValueError('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_gateway_virtual_connection',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/virtual_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_gateway_virtual_connection(
        self,
        gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Get virtual connection.

        Retrieve a virtual connection.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: The virtual 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 `GatewayVirtualConnection` object
        """

        if not gateway_id:
            raise ValueError('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_gateway_virtual_connection',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/virtual_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_gateway_virtual_connection(
        self,
        gateway_id: str,
        id: str,
        gateway_virtual_connection_patch_template: 'GatewayVirtualConnectionPatchTemplate',
        **kwargs,
    ) -> DetailedResponse:
        """
        Update virtual connection.

        Update a virtual connection.

        :param str gateway_id: Direct Link gateway identifier.
        :param str id: The virtual connection identifier.
        :param GatewayVirtualConnectionPatchTemplate
               gateway_virtual_connection_patch_template: The virtual connection patch
               template.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `GatewayVirtualConnection` object
        """

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

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

        data = json.dumps(gateway_virtual_connection_patch_template)
        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 = ['gateway_id', 'id']
        path_param_values = self.encode_path_vars(gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/gateways/{gateway_id}/virtual_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

    #########################
    # Offering Information
    #########################

    def list_offering_type_locations(
        self,
        offering_type: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List available locations.

        Retrieve the list of valid locations for the specified Direct Link offering.

        :param str offering_type: The Direct Link offering type.  Current supported
               values are `"dedicated"` and `"connect"`.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LocationCollection` object
        """

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

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

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

        path_param_keys = ['offering_type']
        path_param_values = self.encode_path_vars(offering_type)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/offering_types/{offering_type}/locations'.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_offering_type_location_cross_connect_routers(
        self,
        offering_type: str,
        location_name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List routers.

        Retrieve location specific cross connect router information.  Only valid for
        offering_type=dedicated locations.

        :param str offering_type: The Direct Link offering type.  Current supported
               values are `"dedicated"` and `"connect"`.
        :param str location_name: The name of the Direct Link location.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `LocationCrossConnectRouterCollection` object
        """

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

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

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

        path_param_keys = ['offering_type', 'location_name']
        path_param_values = self.encode_path_vars(offering_type, location_name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/offering_types/{offering_type}/locations/{location_name}/cross_connect_routers'.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_offering_type_speeds(
        self,
        offering_type: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        List speed options.

        List the available Direct Link speeds.

        :param str offering_type: The Direct Link offering type.  Current supported
               values are `"dedicated"` and `"connect"`.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `OfferingSpeedCollection` object
        """

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

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

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

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

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

    #########################
    # Ports
    #########################

    def list_ports(
        self,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        location_name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        List ports.

        Retrieve list of available Direct Link connect ports.  These ports can be used to
        create Direct Link connect gateways.

        :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 str location_name: (optional) Direct Link location short 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 `PortCollection` object
        """

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

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

        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
            del kwargs['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_port(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Get port.

        Retrieve Direct Link Connect provider port.

        :param str id: The 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 `Port` 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_port',
        )
        headers.update(sdk_headers)

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

        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 = '/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


class GetGatewayStatisticsEnums:
    """
    Enums for get_gateway_statistics parameters.
    """

    class Type(str, Enum):
        """
        Specify statistic to retrieve.
        """

        MACSEC_MKA_SESSION = 'macsec_mka_session'
        MACSEC_POLICY = 'macsec_policy'
        MACSEC_MKA_STATISTICS = 'macsec_mka_statistics'
        BFD_SESSION = 'bfd_session'


class GetGatewayStatusEnums:
    """
    Enums for get_gateway_status parameters.
    """

    class Type(str, Enum):
        """
        Specify status to retrieve.
        """

        BGP = 'bgp'
        BFD = 'bfd'
        LINK = 'link'


class ListOfferingTypeLocationsEnums:
    """
    Enums for list_offering_type_locations parameters.
    """

    class OfferingType(str, Enum):
        """
        The Direct Link offering type.  Current supported values are `"dedicated"` and
        `"connect"`.
        """

        DEDICATED = 'dedicated'
        CONNECT = 'connect'


class ListOfferingTypeLocationCrossConnectRoutersEnums:
    """
    Enums for list_offering_type_location_cross_connect_routers parameters.
    """

    class OfferingType(str, Enum):
        """
        The Direct Link offering type.  Current supported values are `"dedicated"` and
        `"connect"`.
        """

        DEDICATED = 'dedicated'
        CONNECT = 'connect'


class ListOfferingTypeSpeedsEnums:
    """
    Enums for list_offering_type_speeds parameters.
    """

    class OfferingType(str, Enum):
        """
        The Direct Link offering type.  Current supported values are `"dedicated"` and
        `"connect"`.
        """

        DEDICATED = 'dedicated'
        CONNECT = 'connect'


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


class AsPrepend:
    """
    Gateway AS Prepend object.

    :param datetime created_at: (optional) The date and time resource was created.
    :param str id: (optional) The unique identifier for this AS Prepend.
    :param int length: (optional) Number of times the ASN to appended to the AS
          Path.
    :param str policy: (optional) Route type this AS Prepend applies to.
    :param str prefix: (optional) Deprecated: Comma separated list of prefixes this
          AS Prepend applies to.  If empty, this applies to all prefixes.
    :param List[str] specific_prefixes: (optional) Array of prefixes this AS Prepend
          applies to. This parameter is not returned when AS Prepend applies to all
          prefixes.  Note that ordering is not significant and may differ from request
          order.
    :param datetime updated_at: (optional) The date and time resource was last
          updated.
    """

    def __init__(
        self,
        *,
        created_at: Optional[datetime] = None,
        id: Optional[str] = None,
        length: Optional[int] = None,
        policy: Optional[str] = None,
        prefix: Optional[str] = None,
        specific_prefixes: Optional[List[str]] = None,
        updated_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a AsPrepend object.

        :param datetime created_at: (optional) The date and time resource was
               created.
        :param str id: (optional) The unique identifier for this AS Prepend.
        :param int length: (optional) Number of times the ASN to appended to the AS
               Path.
        :param str policy: (optional) Route type this AS Prepend applies to.
        :param str prefix: (optional) Deprecated: Comma separated list of prefixes
               this AS Prepend applies to.  If empty, this applies to all prefixes.
        :param List[str] specific_prefixes: (optional) Array of prefixes this AS
               Prepend applies to. This parameter is not returned when AS Prepend applies
               to all prefixes.  Note that ordering is not significant and may differ from
               request order.
        :param datetime updated_at: (optional) The date and time resource was last
               updated.
        """
        self.created_at = created_at
        self.id = id
        self.length = length
        self.policy = policy
        self.prefix = prefix
        self.specific_prefixes = specific_prefixes
        self.updated_at = updated_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AsPrepend':
        """Initialize a AsPrepend object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        if (length := _dict.get('length')) is not None:
            args['length'] = length
        if (policy := _dict.get('policy')) is not None:
            args['policy'] = policy
        if (prefix := _dict.get('prefix')) is not None:
            args['prefix'] = prefix
        if (specific_prefixes := _dict.get('specific_prefixes')) is not None:
            args['specific_prefixes'] = specific_prefixes
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        return cls(**args)

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

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

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

    class PolicyEnum(str, Enum):
        """
        Route type this AS Prepend applies to.
        """

        IMPORT = 'import'
        EXPORT = 'export'



class AsPrependCollection:
    """
    array of AS Prepends.

    :param List[AsPrependEntry] as_prepends: (optional) array of AS Prepend
          information.
    """

    def __init__(
        self,
        *,
        as_prepends: Optional[List['AsPrependEntry']] = None,
    ) -> None:
        """
        Initialize a AsPrependCollection object.

        :param List[AsPrependEntry] as_prepends: (optional) array of AS Prepend
               information.
        """
        self.as_prepends = as_prepends

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

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

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

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

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


class AsPrependEntry:
    """
    AS Prepends API object.

    :param datetime created_at: (optional) The date and time resource was created.
    :param str id: (optional) The unique identifier for this AS Prepend.
    :param int length: (optional) Number of times the ASN to appended to the AS
          Path.
    :param str policy: (optional) Route type this AS Prepend applies to.
    :param List[str] specific_prefixes: (optional) Array of prefixes this AS Prepend
          applies to. This parameter is not returned when AS Prepend applies to all
          prefixes.  Note that ordering is not significant and may differ from request
          order.
    :param datetime updated_at: (optional) The date and time resource was last
          updated.
    """

    def __init__(
        self,
        *,
        created_at: Optional[datetime] = None,
        id: Optional[str] = None,
        length: Optional[int] = None,
        policy: Optional[str] = None,
        specific_prefixes: Optional[List[str]] = None,
        updated_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a AsPrependEntry object.

        :param datetime created_at: (optional) The date and time resource was
               created.
        :param str id: (optional) The unique identifier for this AS Prepend.
        :param int length: (optional) Number of times the ASN to appended to the AS
               Path.
        :param str policy: (optional) Route type this AS Prepend applies to.
        :param List[str] specific_prefixes: (optional) Array of prefixes this AS
               Prepend applies to. This parameter is not returned when AS Prepend applies
               to all prefixes.  Note that ordering is not significant and may differ from
               request order.
        :param datetime updated_at: (optional) The date and time resource was last
               updated.
        """
        self.created_at = created_at
        self.id = id
        self.length = length
        self.policy = policy
        self.specific_prefixes = specific_prefixes
        self.updated_at = updated_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'AsPrependEntry':
        """Initialize a AsPrependEntry object from a json dictionary."""
        args = {}
        if (created_at := _dict.get('created_at')) is not None:
            args['created_at'] = string_to_datetime(created_at)
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        if (length := _dict.get('length')) is not None:
            args['length'] = length
        if (policy := _dict.get('policy')) is not None:
            args['policy'] = policy
        if (specific_prefixes := _dict.get('specific_prefixes')) is not None:
            args['specific_prefixes'] = specific_prefixes
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        return cls(**args)

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

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

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

    class PolicyEnum(str, Enum):
        """
        Route type this AS Prepend applies to.
        """

        IMPORT = 'import'
        EXPORT = 'export'



class AsPrependPrefixArrayTemplate:
    """
    Create AS Prepend Configuration template.

    :param int length: Number of times the ASN to be prepended to the AS Path.
    :param str policy: Route type this AS Prepend applies to.
    :param List[str] specific_prefixes: (optional) Array of prefixes this AS Prepend
          applies to. If this property is absent, the AS Prepend applies to all prefixes.
          Note that ordering is not significant and may differ from request order.
    """

    def __init__(
        self,
        length: int,
        policy: str,
        *,
        specific_prefixes: Optional[List[str]] = None,
    ) -> None:
        """
        Initialize a AsPrependPrefixArrayTemplate object.

        :param int length: Number of times the ASN to be prepended to the AS Path.
        :param str policy: Route type this AS Prepend applies to.
        :param List[str] specific_prefixes: (optional) Array of prefixes this AS
               Prepend applies to. If this property is absent, the AS Prepend applies to
               all prefixes.  Note that ordering is not significant and may differ from
               request order.
        """
        self.length = length
        self.policy = policy
        self.specific_prefixes = specific_prefixes

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

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

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

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

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

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

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

    class PolicyEnum(str, Enum):
        """
        Route type this AS Prepend applies to.
        """

        IMPORT = 'import'
        EXPORT = 'export'



class AsPrependTemplate:
    """
    Create AS Prepend Configuration template.

    :param int length: Number of times the ASN to be prepended to the AS Path.
    :param str policy: Route type this AS Prepend applies to.
    :param str prefix: (optional) Deprecated: Comma separated list of prefixes this
          AS Prepend applies to.  Maximum of 10 prefixes.  If not specified, this AS
          Prepend applies to all prefixes.
    :param List[str] specific_prefixes: (optional) Array of prefixes this AS Prepend
          applies to. If this property is absent, the AS Prepend applies to all prefixes.
    """

    def __init__(
        self,
        length: int,
        policy: str,
        *,
        prefix: Optional[str] = None,
        specific_prefixes: Optional[List[str]] = None,
    ) -> None:
        """
        Initialize a AsPrependTemplate object.

        :param int length: Number of times the ASN to be prepended to the AS Path.
        :param str policy: Route type this AS Prepend applies to.
        :param str prefix: (optional) Deprecated: Comma separated list of prefixes
               this AS Prepend applies to.  Maximum of 10 prefixes.  If not specified,
               this AS Prepend applies to all prefixes.
        :param List[str] specific_prefixes: (optional) Array of prefixes this AS
               Prepend applies to. If this property is absent, the AS Prepend applies to
               all prefixes.
        """
        self.length = length
        self.policy = policy
        self.prefix = prefix
        self.specific_prefixes = specific_prefixes

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

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

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

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

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

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

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

    class PolicyEnum(str, Enum):
        """
        Route type this AS Prepend applies to.
        """

        IMPORT = 'import'
        EXPORT = 'export'



class AuthenticationKeyIdentity:
    """
    AuthenticationKeyIdentity.

    """

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

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


class AuthenticationKeyReference:
    """
    AuthenticationKeyReference.

    """

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

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


class CrossConnectRouter:
    """
    Cross Connect Router details.

    :param List[str] capabilities: (optional) List of capabilities for this router.
          Listed `MacsecCapability` values indicate the router is associated with switch
          ports with that capability, and is able to provision direct links with that
          capability. Multiple `MacsecCapability` values may be listed.
    :param str router_name: (optional) The name of the Router.
    :param int total_connections: (optional) Count of existing Direct Link Dedicated
          gateways on this router for this account.
    """

    def __init__(
        self,
        *,
        capabilities: Optional[List[str]] = None,
        router_name: Optional[str] = None,
        total_connections: Optional[int] = None,
    ) -> None:
        """
        Initialize a CrossConnectRouter object.

        :param List[str] capabilities: (optional) List of capabilities for this
               router.
               Listed `MacsecCapability` values indicate the router is associated with
               switch ports with that capability, and is able to provision direct links
               with that capability. Multiple `MacsecCapability` values may be listed.
        :param str router_name: (optional) The name of the Router.
        :param int total_connections: (optional) Count of existing Direct Link
               Dedicated gateways on this router for this account.
        """
        self.capabilities = capabilities
        self.router_name = router_name
        self.total_connections = total_connections

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

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

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

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

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

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

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


class ExportRouteFilterCollection:
    """
    Collection of export route filters.

    :param List[RouteFilter] export_route_filters: Array of export route filters.
    """

    def __init__(
        self,
        export_route_filters: List['RouteFilter'],
    ) -> None:
        """
        Initialize a ExportRouteFilterCollection object.

        :param List[RouteFilter] export_route_filters: Array of export route
               filters.
        """
        self.export_route_filters = export_route_filters

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

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

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

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


class Gateway:
    """
    gateway.

    :param List[AsPrepend] as_prepends: (optional) array of AS Prepend information.
    :param AuthenticationKeyReference authentication_key: (optional)
    :param GatewayBfdConfig bfd_config: (optional) BFD configuration information.
    :param int bgp_asn: Customer BGP ASN.
    :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR is deprecated
          and no longer recognized by the Direct Link APIs.
          See bgp_cer_cidr and bgp_ibm_cidr fields instead for IP related information.
          Deprecated field bgp_base_cidr will be removed from the API specification after
          15-MAR-2021.
    :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
    :param int bgp_ibm_asn: (optional) IBM BGP ASN.
    :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 datetime bgp_status_updated_at: (optional) Date and time bgp status was
          updated.
    :param str carrier_name: (optional) Carrier name.  Only set for type=dedicated
          gateways.
    :param GatewayChangeRequest change_request: (optional) Changes pending approval
          for provider managed Direct Link Connect gateways.
    :param str completion_notice_reject_reason: (optional) Reason for completion
          notice rejection.  Only included on type=dedicated gateways with a rejected
          completion notice.
    :param str connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param datetime created_at: The date and time resource was created.
    :param str crn: The CRN (Cloud Resource Name) of this gateway.
    :param bool cross_account: Indicates whether this gateway is cross account
          gateway.
    :param str cross_connect_router: (optional) Cross connect router. Only included
          on type=dedicated gateways.
    :param str customer_name: (optional) Customer name.  Only set for type=dedicated
          gateways.
    :param str default_export_route_filter: The default directional route filter
          action that applies to routes that do not match any directional route filters.
    :param str default_import_route_filter: The default directional route filter
          action that applies to routes that do not match any directional route filters.
    :param bool global_: Gateways with global routing (`true`) can connect to
          networks outside their associated region.
    :param str id: The unique identifier of this gateway.
    :param str link_status: (optional) Gateway link status.  Only included on
          type=dedicated gateways. The list of enumerated values for this property may
          expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    :param datetime link_status_updated_at: (optional) Date and time link status was
          updated.
    :param str location_display_name: Gateway location long name.
    :param str location_name: Gateway location.
    :param GatewayMacsecReference macsec: (optional) MACsec configuration
          information of a Direct Link gateway.
    :param str macsec_capability: (optional) Indicates the direct link's MACsec
          capability. It must match one of the MACsec related `capabilities` of the
          `cross_connect_router`.
          Only included on type=dedicated direct links.
          - non_macsec: The direct link does not support MACsec.
          - macsec: The direct link supports MACsec. The MACsec feature must be enabled.
          - macsec_optional: The direct link supports MACsec. The MACsec feature is not
          required and can be enabled after direct link creation.
    :param bool metered: Metered billing option.  When `true` gateway usage is
          billed per gigabyte.  When `false` there is no per gigabyte usage charge,
          instead a flat rate is charged for the 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.
          See `operational_status_reasons[]` for possible remediation of the `failed`
          `operational_status`.
    :param List[GatewayStatusReason] operational_status_reasons: Context for certain
          values of `operational_status`.
    :param str patch_panel_completion_notice: (optional) Gateway patch panel
          complete notification from implementation team.
    :param GatewayPortReference port: (optional) Port information for type=connect
          gateways.
    :param bool provider_api_managed: (optional) Indicates whether gateway changes
          must be made via a provider portal.
    :param ResourceGroupReference resource_group: (optional) Resource group
          reference.
    :param int speed_mbps: Gateway speed in megabits per second.
    :param str type: Offering type. The list of enumerated values for this property
          may expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    :param int vlan: (optional) VLAN configured for this gateway. If there is no
          vlan configured for the gateway, the vlan will be absent. This property will
          also be absent if this gateway's `crn` is in another account.
    """

    def __init__(
        self,
        bgp_asn: int,
        created_at: datetime,
        crn: str,
        cross_account: bool,
        default_export_route_filter: str,
        default_import_route_filter: str,
        global_: bool,
        id: str,
        location_display_name: str,
        location_name: str,
        metered: bool,
        name: str,
        operational_status: str,
        operational_status_reasons: List['GatewayStatusReason'],
        speed_mbps: int,
        type: str,
        *,
        as_prepends: Optional[List['AsPrepend']] = None,
        authentication_key: Optional['AuthenticationKeyReference'] = None,
        bfd_config: Optional['GatewayBfdConfig'] = None,
        bgp_base_cidr: Optional[str] = None,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_asn: Optional[int] = None,
        bgp_ibm_cidr: Optional[str] = None,
        bgp_status: Optional[str] = None,
        bgp_status_updated_at: Optional[datetime] = None,
        carrier_name: Optional[str] = None,
        change_request: Optional['GatewayChangeRequest'] = None,
        completion_notice_reject_reason: Optional[str] = None,
        connection_mode: Optional[str] = None,
        cross_connect_router: Optional[str] = None,
        customer_name: Optional[str] = None,
        link_status: Optional[str] = None,
        link_status_updated_at: Optional[datetime] = None,
        macsec: Optional['GatewayMacsecReference'] = None,
        macsec_capability: Optional[str] = None,
        patch_panel_completion_notice: Optional[str] = None,
        port: Optional['GatewayPortReference'] = None,
        provider_api_managed: Optional[bool] = None,
        resource_group: Optional['ResourceGroupReference'] = None,
        vlan: Optional[int] = None,
    ) -> None:
        """
        Initialize a Gateway object.

        :param int bgp_asn: Customer BGP ASN.
        :param datetime created_at: The date and time resource was created.
        :param str crn: The CRN (Cloud Resource Name) of this gateway.
        :param bool cross_account: Indicates whether this gateway is cross account
               gateway.
        :param str default_export_route_filter: The default directional route
               filter action that applies to routes that do not match any directional
               route filters.
        :param str default_import_route_filter: The default directional route
               filter action that applies to routes that do not match any directional
               route filters.
        :param bool global_: Gateways with global routing (`true`) can connect to
               networks outside their associated region.
        :param str id: The unique identifier of this gateway.
        :param str location_display_name: Gateway location long name.
        :param str location_name: Gateway location.
        :param bool metered: Metered billing option.  When `true` gateway usage is
               billed per gigabyte.  When `false` there is no per gigabyte usage charge,
               instead a flat rate is charged for the 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.
               See `operational_status_reasons[]` for possible remediation of the `failed`
               `operational_status`.
        :param List[GatewayStatusReason] operational_status_reasons: Context for
               certain values of `operational_status`.
        :param int speed_mbps: Gateway speed in megabits per second.
        :param str type: Offering type. The list of enumerated values for this
               property may expand in the future. Code and processes using this field
               must tolerate unexpected values.
        :param List[AsPrepend] as_prepends: (optional) array of AS Prepend
               information.
        :param AuthenticationKeyReference authentication_key: (optional)
        :param GatewayBfdConfig bfd_config: (optional) BFD configuration
               information.
        :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR is
               deprecated and no longer recognized by the Direct Link APIs.
               See bgp_cer_cidr and bgp_ibm_cidr fields instead for IP related
               information.
               Deprecated field bgp_base_cidr will be removed from the API specification
               after 15-MAR-2021.
        :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
        :param int bgp_ibm_asn: (optional) IBM BGP ASN.
        :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 datetime bgp_status_updated_at: (optional) Date and time bgp status
               was updated.
        :param str carrier_name: (optional) Carrier name.  Only set for
               type=dedicated gateways.
        :param GatewayChangeRequest change_request: (optional) Changes pending
               approval for provider managed Direct Link Connect gateways.
        :param str completion_notice_reject_reason: (optional) Reason for
               completion notice rejection.  Only included on type=dedicated gateways with
               a rejected completion notice.
        :param str connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str cross_connect_router: (optional) Cross connect router. Only
               included on type=dedicated gateways.
        :param str customer_name: (optional) Customer name.  Only set for
               type=dedicated gateways.
        :param str link_status: (optional) Gateway link status.  Only included on
               type=dedicated gateways. The list of enumerated values for this property
               may expand in the future. Code and processes using this field  must
               tolerate unexpected values.
        :param datetime link_status_updated_at: (optional) Date and time link
               status was updated.
        :param GatewayMacsecReference macsec: (optional) MACsec configuration
               information of a Direct Link gateway.
        :param str macsec_capability: (optional) Indicates the direct link's MACsec
               capability. It must match one of the MACsec related `capabilities` of the
               `cross_connect_router`.
               Only included on type=dedicated direct links.
               - non_macsec: The direct link does not support MACsec.
               - macsec: The direct link supports MACsec. The MACsec feature must be
               enabled.
               - macsec_optional: The direct link supports MACsec. The MACsec feature is
               not required and can be enabled after direct link creation.
        :param str patch_panel_completion_notice: (optional) Gateway patch panel
               complete notification from implementation team.
        :param GatewayPortReference port: (optional) Port information for
               type=connect gateways.
        :param bool provider_api_managed: (optional) Indicates whether gateway
               changes must be made via a provider portal.
        :param ResourceGroupReference resource_group: (optional) Resource group
               reference.
        :param int vlan: (optional) VLAN configured for this gateway. If there is
               no vlan configured for the gateway, the vlan will be absent. This property
               will also be absent if this gateway's `crn` is in another account.
        """
        self.as_prepends = as_prepends
        self.authentication_key = authentication_key
        self.bfd_config = bfd_config
        self.bgp_asn = bgp_asn
        self.bgp_base_cidr = bgp_base_cidr
        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.bgp_status_updated_at = bgp_status_updated_at
        self.carrier_name = carrier_name
        self.change_request = change_request
        self.completion_notice_reject_reason = completion_notice_reject_reason
        self.connection_mode = connection_mode
        self.created_at = created_at
        self.crn = crn
        self.cross_account = cross_account
        self.cross_connect_router = cross_connect_router
        self.customer_name = customer_name
        self.default_export_route_filter = default_export_route_filter
        self.default_import_route_filter = default_import_route_filter
        self.global_ = global_
        self.id = id
        self.link_status = link_status
        self.link_status_updated_at = link_status_updated_at
        self.location_display_name = location_display_name
        self.location_name = location_name
        self.macsec = macsec
        self.macsec_capability = macsec_capability
        self.metered = metered
        self.name = name
        self.operational_status = operational_status
        self.operational_status_reasons = operational_status_reasons
        self.patch_panel_completion_notice = patch_panel_completion_notice
        self.port = port
        self.provider_api_managed = provider_api_managed
        self.resource_group = resource_group
        self.speed_mbps = speed_mbps
        self.type = type
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'Gateway':
        """Initialize a Gateway object from a json dictionary."""
        args = {}
        if (as_prepends := _dict.get('as_prepends')) is not None:
            args['as_prepends'] = [AsPrepend.from_dict(v) for v in as_prepends]
        if (authentication_key := _dict.get('authentication_key')) is not None:
            args['authentication_key'] = authentication_key
        if (bfd_config := _dict.get('bfd_config')) is not None:
            args['bfd_config'] = GatewayBfdConfig.from_dict(bfd_config)
        if (bgp_asn := _dict.get('bgp_asn')) is not None:
            args['bgp_asn'] = bgp_asn
        else:
            raise ValueError('Required property \'bgp_asn\' not present in Gateway JSON')
        if (bgp_base_cidr := _dict.get('bgp_base_cidr')) is not None:
            args['bgp_base_cidr'] = bgp_base_cidr
        if (bgp_cer_cidr := _dict.get('bgp_cer_cidr')) is not None:
            args['bgp_cer_cidr'] = bgp_cer_cidr
        if (bgp_ibm_asn := _dict.get('bgp_ibm_asn')) is not None:
            args['bgp_ibm_asn'] = bgp_ibm_asn
        if (bgp_ibm_cidr := _dict.get('bgp_ibm_cidr')) is not None:
            args['bgp_ibm_cidr'] = bgp_ibm_cidr
        if (bgp_status := _dict.get('bgp_status')) is not None:
            args['bgp_status'] = bgp_status
        if (bgp_status_updated_at := _dict.get('bgp_status_updated_at')) is not None:
            args['bgp_status_updated_at'] = string_to_datetime(bgp_status_updated_at)
        if (carrier_name := _dict.get('carrier_name')) is not None:
            args['carrier_name'] = carrier_name
        if (change_request := _dict.get('change_request')) is not None:
            args['change_request'] = change_request
        if (completion_notice_reject_reason := _dict.get('completion_notice_reject_reason')) is not None:
            args['completion_notice_reject_reason'] = completion_notice_reject_reason
        if (connection_mode := _dict.get('connection_mode')) is not None:
            args['connection_mode'] = connection_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 Gateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in Gateway JSON')
        if (cross_account := _dict.get('cross_account')) is not None:
            args['cross_account'] = cross_account
        else:
            raise ValueError('Required property \'cross_account\' not present in Gateway JSON')
        if (cross_connect_router := _dict.get('cross_connect_router')) is not None:
            args['cross_connect_router'] = cross_connect_router
        if (customer_name := _dict.get('customer_name')) is not None:
            args['customer_name'] = customer_name
        if (default_export_route_filter := _dict.get('default_export_route_filter')) is not None:
            args['default_export_route_filter'] = default_export_route_filter
        else:
            raise ValueError('Required property \'default_export_route_filter\' not present in Gateway JSON')
        if (default_import_route_filter := _dict.get('default_import_route_filter')) is not None:
            args['default_import_route_filter'] = default_import_route_filter
        else:
            raise ValueError('Required property \'default_import_route_filter\' not present in Gateway JSON')
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        else:
            raise ValueError('Required property \'global\' not present in Gateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Gateway JSON')
        if (link_status := _dict.get('link_status')) is not None:
            args['link_status'] = link_status
        if (link_status_updated_at := _dict.get('link_status_updated_at')) is not None:
            args['link_status_updated_at'] = string_to_datetime(link_status_updated_at)
        if (location_display_name := _dict.get('location_display_name')) is not None:
            args['location_display_name'] = location_display_name
        else:
            raise ValueError('Required property \'location_display_name\' not present in Gateway JSON')
        if (location_name := _dict.get('location_name')) is not None:
            args['location_name'] = location_name
        else:
            raise ValueError('Required property \'location_name\' not present in Gateway JSON')
        if (macsec := _dict.get('macsec')) is not None:
            args['macsec'] = GatewayMacsecReference.from_dict(macsec)
        if (macsec_capability := _dict.get('macsec_capability')) is not None:
            args['macsec_capability'] = macsec_capability
        if (metered := _dict.get('metered')) is not None:
            args['metered'] = metered
        else:
            raise ValueError('Required property \'metered\' not present in Gateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in Gateway JSON')
        if (operational_status := _dict.get('operational_status')) is not None:
            args['operational_status'] = operational_status
        else:
            raise ValueError('Required property \'operational_status\' not present in Gateway JSON')
        if (operational_status_reasons := _dict.get('operational_status_reasons')) is not None:
            args['operational_status_reasons'] = [GatewayStatusReason.from_dict(v) for v in operational_status_reasons]
        else:
            raise ValueError('Required property \'operational_status_reasons\' not present in Gateway JSON')
        if (patch_panel_completion_notice := _dict.get('patch_panel_completion_notice')) is not None:
            args['patch_panel_completion_notice'] = patch_panel_completion_notice
        if (port := _dict.get('port')) is not None:
            args['port'] = GatewayPortReference.from_dict(port)
        if (provider_api_managed := _dict.get('provider_api_managed')) is not None:
            args['provider_api_managed'] = provider_api_managed
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        else:
            raise ValueError('Required property \'speed_mbps\' not present in Gateway JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in Gateway JSON')
        if (vlan := _dict.get('vlan')) is not None:
            args['vlan'] = vlan
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'as_prepends') and self.as_prepends is not None:
            as_prepends_list = []
            for v in self.as_prepends:
                if isinstance(v, dict):
                    as_prepends_list.append(v)
                else:
                    as_prepends_list.append(v.to_dict())
            _dict['as_prepends'] = as_prepends_list
        if hasattr(self, 'authentication_key') and self.authentication_key is not None:
            if isinstance(self.authentication_key, dict):
                _dict['authentication_key'] = self.authentication_key
            else:
                _dict['authentication_key'] = self.authentication_key.to_dict()
        if hasattr(self, 'bfd_config') and self.bfd_config is not None:
            if isinstance(self.bfd_config, dict):
                _dict['bfd_config'] = self.bfd_config
            else:
                _dict['bfd_config'] = self.bfd_config.to_dict()
        if hasattr(self, 'bgp_asn') and self.bgp_asn is not None:
            _dict['bgp_asn'] = self.bgp_asn
        if hasattr(self, 'bgp_base_cidr') and self.bgp_base_cidr is not None:
            _dict['bgp_base_cidr'] = self.bgp_base_cidr
        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, 'bgp_status_updated_at') and self.bgp_status_updated_at is not None:
            _dict['bgp_status_updated_at'] = datetime_to_string(self.bgp_status_updated_at)
        if hasattr(self, 'carrier_name') and self.carrier_name is not None:
            _dict['carrier_name'] = self.carrier_name
        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, 'completion_notice_reject_reason') and self.completion_notice_reject_reason is not None:
            _dict['completion_notice_reject_reason'] = self.completion_notice_reject_reason
        if hasattr(self, 'connection_mode') and self.connection_mode is not None:
            _dict['connection_mode'] = self.connection_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, 'cross_account') and self.cross_account is not None:
            _dict['cross_account'] = self.cross_account
        if hasattr(self, 'cross_connect_router') and self.cross_connect_router is not None:
            _dict['cross_connect_router'] = self.cross_connect_router
        if hasattr(self, 'customer_name') and self.customer_name is not None:
            _dict['customer_name'] = self.customer_name
        if hasattr(self, 'default_export_route_filter') and self.default_export_route_filter is not None:
            _dict['default_export_route_filter'] = self.default_export_route_filter
        if hasattr(self, 'default_import_route_filter') and self.default_import_route_filter is not None:
            _dict['default_import_route_filter'] = self.default_import_route_filter
        if hasattr(self, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'link_status') and self.link_status is not None:
            _dict['link_status'] = self.link_status
        if hasattr(self, 'link_status_updated_at') and self.link_status_updated_at is not None:
            _dict['link_status_updated_at'] = datetime_to_string(self.link_status_updated_at)
        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, 'macsec') and self.macsec is not None:
            if isinstance(self.macsec, dict):
                _dict['macsec'] = self.macsec
            else:
                _dict['macsec'] = self.macsec.to_dict()
        if hasattr(self, 'macsec_capability') and self.macsec_capability is not None:
            _dict['macsec_capability'] = self.macsec_capability
        if hasattr(self, 'metered') and self.metered is not None:
            _dict['metered'] = self.metered
        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, 'operational_status_reasons') and self.operational_status_reasons is not None:
            operational_status_reasons_list = []
            for v in self.operational_status_reasons:
                if isinstance(v, dict):
                    operational_status_reasons_list.append(v)
                else:
                    operational_status_reasons_list.append(v.to_dict())
            _dict['operational_status_reasons'] = operational_status_reasons_list
        if hasattr(self, 'patch_panel_completion_notice') and self.patch_panel_completion_notice is not None:
            _dict['patch_panel_completion_notice'] = self.patch_panel_completion_notice
        if hasattr(self, 'port') and self.port is not None:
            if isinstance(self.port, dict):
                _dict['port'] = self.port
            else:
                _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, '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, '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 Gateway object."""
        return json.dumps(self.to_dict(), indent=2)

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

    def __ne__(self, other: 'Gateway') -> 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 ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class DefaultExportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class DefaultImportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class LinkStatusEnum(str, Enum):
        """
        Gateway link status.  Only included on type=dedicated gateways. The list of
        enumerated values for this property may expand in the future. Code and processes
        using this field  must tolerate unexpected values.
        """

        DOWN = 'down'
        UP = 'up'


    class MacsecCapabilityEnum(str, Enum):
        """
        Indicates the direct link's MACsec capability. It must match one of the MACsec
        related `capabilities` of the `cross_connect_router`.
        Only included on type=dedicated direct links.
        - non_macsec: The direct link does not support MACsec.
        - macsec: The direct link supports MACsec. The MACsec feature must be enabled.
        - macsec_optional: The direct link supports MACsec. The MACsec feature is not
        required and can be enabled after direct link creation.
        """

        NON_MACSEC = 'non_macsec'
        MACSEC = 'macsec'
        MACSEC_OPTIONAL = 'macsec_optional'


    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.
        See `operational_status_reasons[]` for possible remediation of the `failed`
        `operational_status`.
        """

        AWAITING_COMPLETION_NOTICE = 'awaiting_completion_notice'
        AWAITING_LOA = 'awaiting_loa'
        CONFIGURING = 'configuring'
        CREATE_PENDING = 'create_pending'
        CREATE_REJECTED = 'create_rejected'
        COMPLETION_NOTICE_APPROVED = 'completion_notice_approved'
        COMPLETION_NOTICE_RECEIVED = 'completion_notice_received'
        COMPLETION_NOTICE_REJECTED = 'completion_notice_rejected'
        DELETE_PENDING = 'delete_pending'
        LOA_ACCEPTED = 'loa_accepted'
        LOA_CREATED = 'loa_created'
        LOA_REJECTED = 'loa_rejected'
        PROVISIONED = 'provisioned'
        FAILED = 'failed'


    class TypeEnum(str, Enum):
        """
        Offering type. The list of enumerated values for this property may expand in the
        future. Code and processes using this field  must tolerate unexpected values.
        """

        CONNECT = 'connect'
        DEDICATED = 'dedicated'



class GatewayActionTemplateUpdatesItem:
    """
    GatewayActionTemplateUpdatesItem.

    """

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

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


class GatewayBfdConfig:
    """
    BFD configuration information.

    :param str bfd_status: (optional) Gateway BFD 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 datetime bfd_status_updated_at: (optional) Date and time bfd status was
          updated.
    :param int interval: Minimum interval in milliseconds at which the local routing
          device transmits hello packets and then expects to receive a reply from a
          neighbor with which it has established a BFD session.
    :param int multiplier: The number of hello packets not received by a neighbor
          that causes the originating interface to be declared down.
    """

    def __init__(
        self,
        interval: int,
        multiplier: int,
        *,
        bfd_status: Optional[str] = None,
        bfd_status_updated_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a GatewayBfdConfig object.

        :param int interval: Minimum interval in milliseconds at which the local
               routing device transmits hello packets and then expects to receive a reply
               from a neighbor with which it has established a BFD session.
        :param int multiplier: The number of hello packets not received by a
               neighbor that causes the originating interface to be declared down.
        :param str bfd_status: (optional) Gateway BFD 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 datetime bfd_status_updated_at: (optional) Date and time bfd status
               was updated.
        """
        self.bfd_status = bfd_status
        self.bfd_status_updated_at = bfd_status_updated_at
        self.interval = interval
        self.multiplier = multiplier

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

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

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

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

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

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

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

    class BfdStatusEnum(str, Enum):
        """
        Gateway BFD status. The list of enumerated values for this property may expand in
        the future. Code and processes using this field must tolerate unexpected values.
        """

        INIT = 'init'
        UP = 'up'
        DOWN = 'down'



class GatewayBfdConfigActionTemplate:
    """
    Applicable for create_gateway_approve requests to select the gateway's BFD
    configuration information.

    :param int interval: Minimum interval in milliseconds at which the local routing
          device transmits hello packets and then expects to receive a reply from a
          neighbor with which it has established a BFD session.
    :param int multiplier: (optional) The number of hello packets not received by a
          neighbor that causes the originating interface to be declared down.
    """

    def __init__(
        self,
        interval: int,
        *,
        multiplier: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayBfdConfigActionTemplate object.

        :param int interval: Minimum interval in milliseconds at which the local
               routing device transmits hello packets and then expects to receive a reply
               from a neighbor with which it has established a BFD session.
        :param int multiplier: (optional) The number of hello packets not received
               by a neighbor that causes the originating interface to be declared down.
        """
        self.interval = interval
        self.multiplier = multiplier

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

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

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

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

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

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

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


class GatewayBfdConfigTemplate:
    """
    BFD configuration information.

    :param int interval: Minimum interval in milliseconds at which the local routing
          device transmits hello packets and then expects to receive a reply from a
          neighbor with which it has established a BFD session.
    :param int multiplier: (optional) The number of hello packets not received by a
          neighbor that causes the originating interface to be declared down.
    """

    def __init__(
        self,
        interval: int,
        *,
        multiplier: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayBfdConfigTemplate object.

        :param int interval: Minimum interval in milliseconds at which the local
               routing device transmits hello packets and then expects to receive a reply
               from a neighbor with which it has established a BFD session.
        :param int multiplier: (optional) The number of hello packets not received
               by a neighbor that causes the originating interface to be declared down.
        """
        self.interval = interval
        self.multiplier = multiplier

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

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

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

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

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

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

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


class GatewayBfdPatchTemplate:
    """
    BFD configuration information.

    :param int interval: (optional) Minimum interval in milliseconds at which the
          local routing device transmits hello packets and then expects to receive a reply
          from a neighbor with which it has established a BFD session.
          To clear the BFD configuration patch its interval to 0.
    :param int multiplier: (optional) The number of hello packets not received by a
          neighbor that causes the originating interface to be declared down.
    """

    def __init__(
        self,
        *,
        interval: Optional[int] = None,
        multiplier: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayBfdPatchTemplate object.

        :param int interval: (optional) Minimum interval in milliseconds at which
               the local routing device transmits hello packets and then expects to
               receive a reply from a neighbor with which it has established a BFD
               session.
               To clear the BFD configuration patch its interval to 0.
        :param int multiplier: (optional) The number of hello packets not received
               by a neighbor that causes the originating interface to be declared down.
        """
        self.interval = interval
        self.multiplier = multiplier

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

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

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

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

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

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

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


class GatewayChangeRequest:
    """
    GatewayChangeRequest.

    """

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

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


class GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItem:
    """
    GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItem.

    """

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

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


class GatewayCollection:
    """
    List of gateways.

    :param List[GatewayCollectionGatewaysItem] gateways: Collection of Direct Link
          gateways.
    """

    def __init__(
        self,
        gateways: List['GatewayCollectionGatewaysItem'],
    ) -> None:
        """
        Initialize a GatewayCollection object.

        :param List[GatewayCollectionGatewaysItem] gateways: Collection of Direct
               Link gateways.
        """
        self.gateways = gateways

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

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

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

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

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


class GatewayCollectionGatewaysItem:
    """
    GatewayCollectionGatewaysItem.

    """

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

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


class GatewayMacsec:
    """
    MACsec configuration information of a Direct Link gateway.

    :param bool active: Indicates if the MACsec feature is currently active (true)
          or inactive (false) for a gateway.
    :param str cipher_suite: The cipher suite used in generating the security
          association key (SAK).
    :param int confidentiality_offset: The confidentiality offset determines the
          number of octets in an Ethernet frame that are not encrypted.
    :param datetime created_at: The date and time the resource was created.
    :param int key_server_priority: Used in the MACsec Key Agreement (MKA) protocol
          to determine which peer acts as the key server.
          Lower values indicate a higher preference to be the key server.
          The MACsec configuration on the direct link will always set this value to 255.
    :param SakRekey sak_rekey: Determines how SAK rekeying occurs. It is either
          timer based or based on the amount of used packet numbers.
    :param str security_policy: Determines how packets without MACsec headers are
          handled.
          `must_secure` - Packets without MACsec headers are dropped. This policy should
          be used to prefer security over network availability.
          `should_secure` - Packets without MACsec headers are allowed. This policy should
          be used to prefer network availability over security.
    :param str status: Current status of MACsec on this direct link.
          Status `offline` is returned when MACsec is inactive and during direct link
          creation.
          Status `deleting` is returned when MACsec during removal of MACsec from the
          direct link and during direct link deletion.
          See `status_reasons[]` for possible remediation of the `failed` `status`.
    :param List[GatewayMacsecStatusReason] status_reasons: Context for certain
          values of `status`.
    :param datetime updated_at: The date and time the resource was last updated.
    :param int window_size: The window size determines the number of frames in a
          window for replay protection.
          Replay protection is used to counter replay attacks. Frames within a window size
          can be out of order and are not replay protected.
    """

    def __init__(
        self,
        active: bool,
        cipher_suite: str,
        confidentiality_offset: int,
        created_at: datetime,
        key_server_priority: int,
        sak_rekey: 'SakRekey',
        security_policy: str,
        status: str,
        status_reasons: List['GatewayMacsecStatusReason'],
        updated_at: datetime,
        window_size: int,
    ) -> None:
        """
        Initialize a GatewayMacsec object.

        :param bool active: Indicates if the MACsec feature is currently active
               (true) or inactive (false) for a gateway.
        :param str cipher_suite: The cipher suite used in generating the security
               association key (SAK).
        :param int confidentiality_offset: The confidentiality offset determines
               the number of octets in an Ethernet frame that are not encrypted.
        :param datetime created_at: The date and time the resource was created.
        :param int key_server_priority: Used in the MACsec Key Agreement (MKA)
               protocol to determine which peer acts as the key server.
               Lower values indicate a higher preference to be the key server.
               The MACsec configuration on the direct link will always set this value to
               255.
        :param SakRekey sak_rekey: Determines how SAK rekeying occurs. It is either
               timer based or based on the amount of used packet numbers.
        :param str security_policy: Determines how packets without MACsec headers
               are handled.
               `must_secure` - Packets without MACsec headers are dropped. This policy
               should be used to prefer security over network availability.
               `should_secure` - Packets without MACsec headers are allowed. This policy
               should be used to prefer network availability over security.
        :param str status: Current status of MACsec on this direct link.
               Status `offline` is returned when MACsec is inactive and during direct link
               creation.
               Status `deleting` is returned when MACsec during removal of MACsec from the
               direct link and during direct link deletion.
               See `status_reasons[]` for possible remediation of the `failed` `status`.
        :param List[GatewayMacsecStatusReason] status_reasons: Context for certain
               values of `status`.
        :param datetime updated_at: The date and time the resource was last
               updated.
        :param int window_size: The window size determines the number of frames in
               a window for replay protection.
               Replay protection is used to counter replay attacks. Frames within a window
               size can be out of order and are not replay protected.
        """
        self.active = active
        self.cipher_suite = cipher_suite
        self.confidentiality_offset = confidentiality_offset
        self.created_at = created_at
        self.key_server_priority = key_server_priority
        self.sak_rekey = sak_rekey
        self.security_policy = security_policy
        self.status = status
        self.status_reasons = status_reasons
        self.updated_at = updated_at
        self.window_size = window_size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayMacsec':
        """Initialize a GatewayMacsec 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 GatewayMacsec JSON')
        if (cipher_suite := _dict.get('cipher_suite')) is not None:
            args['cipher_suite'] = cipher_suite
        else:
            raise ValueError('Required property \'cipher_suite\' not present in GatewayMacsec JSON')
        if (confidentiality_offset := _dict.get('confidentiality_offset')) is not None:
            args['confidentiality_offset'] = confidentiality_offset
        else:
            raise ValueError('Required property \'confidentiality_offset\' not present in GatewayMacsec 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 GatewayMacsec JSON')
        if (key_server_priority := _dict.get('key_server_priority')) is not None:
            args['key_server_priority'] = key_server_priority
        else:
            raise ValueError('Required property \'key_server_priority\' not present in GatewayMacsec JSON')
        if (sak_rekey := _dict.get('sak_rekey')) is not None:
            args['sak_rekey'] = sak_rekey
        else:
            raise ValueError('Required property \'sak_rekey\' not present in GatewayMacsec JSON')
        if (security_policy := _dict.get('security_policy')) is not None:
            args['security_policy'] = security_policy
        else:
            raise ValueError('Required property \'security_policy\' not present in GatewayMacsec JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in GatewayMacsec JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [GatewayMacsecStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in GatewayMacsec 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 GatewayMacsec JSON')
        if (window_size := _dict.get('window_size')) is not None:
            args['window_size'] = window_size
        else:
            raise ValueError('Required property \'window_size\' not present in GatewayMacsec JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayMacsec object from 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, 'cipher_suite') and self.cipher_suite is not None:
            _dict['cipher_suite'] = self.cipher_suite
        if hasattr(self, 'confidentiality_offset') and self.confidentiality_offset is not None:
            _dict['confidentiality_offset'] = self.confidentiality_offset
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'key_server_priority') and self.key_server_priority is not None:
            _dict['key_server_priority'] = self.key_server_priority
        if hasattr(self, 'sak_rekey') and self.sak_rekey is not None:
            if isinstance(self.sak_rekey, dict):
                _dict['sak_rekey'] = self.sak_rekey
            else:
                _dict['sak_rekey'] = self.sak_rekey.to_dict()
        if hasattr(self, 'security_policy') and self.security_policy is not None:
            _dict['security_policy'] = self.security_policy
        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, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'window_size') and self.window_size is not None:
            _dict['window_size'] = self.window_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 GatewayMacsec object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class CipherSuiteEnum(str, Enum):
        """
        The cipher suite used in generating the security association key (SAK).
        """

        GCM_AES_XPN_256 = 'gcm_aes_xpn_256'


    class SecurityPolicyEnum(str, Enum):
        """
        Determines how packets without MACsec headers are handled.
        `must_secure` - Packets without MACsec headers are dropped. This policy should be
        used to prefer security over network availability.
        `should_secure` - Packets without MACsec headers are allowed. This policy should
        be used to prefer network availability over security.
        """

        MUST_SECURE = 'must_secure'
        SHOULD_SECURE = 'should_secure'


    class StatusEnum(str, Enum):
        """
        Current status of MACsec on this direct link.
        Status `offline` is returned when MACsec is inactive and during direct link
        creation.
        Status `deleting` is returned when MACsec during removal of MACsec from the direct
        link and during direct link deletion.
        See `status_reasons[]` for possible remediation of the `failed` `status`.
        """

        INIT = 'init'
        PENDING = 'pending'
        OFFLINE = 'offline'
        SECURED = 'secured'
        FAILED = 'failed'
        DELETING = 'deleting'



class GatewayMacsecCak:
    """
    A connectivity association key (CAK) used in the MACsec Key Agreement (MKA) protocol.
    MACsec CAKs consist of both a name and key. The CAK's `name` must be a hexadecimal
    string of even lengths between 2 to 64 inclusive. The CAK's `key` must be a [Hyper
    Protect Crypto Service Standard
    Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) type=standard
    with key material a hexadecimal string exactly 64 characters in length.

    :param GatewayMacsecCakActiveDelta active_delta: (optional) This field will be
          present when the `status` of the MACsec CAK is `rotating` or `inactive`. It may
          be present when the CAK `status` is `failed`.
          This object denotes the MACsec CAK's values prior to beginning a CAK rotation
          and represents the previous key still configured in the direct link's MACsec key
          chain.
          This object will be removed when the MACsec CAK rotation completes, indicating
          that the previous key has been removed from the key chain, and the current CAK's
          values are in use.
    :param datetime created_at: The date and time the resource was created.
    :param str id: The unique identifier for this connectivity association key
          (CAK).
    :param HpcsKeyReference key: A reference to a [Hyper Protect Crypto Service
          Standard Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
    :param str name: The name identifies the connectivity association key (CAK)
          within the MACsec key chain.
          The CAK's `name` must be a hexadecimal string of even lengths between 2 to 64
          inclusive.
          This value, along with the material of the `key`, must match on the MACsec
          peers.
    :param str session: The intended session the key will be used to secure.
          If the `primary` MACsec session fails due to a key/key name mismatch on the
          peers, the `fallback` session can take over.
          There must be a `primary` session CAK. A `fallback` CAK is optional.
    :param str status: Current status of the CAK.
          Status `operational` is returned when the CAK is configured successfully.
          Status `rotating` is returned during a key rotation. The CAK defined by
          `active_delta` is still configured on the device and could be securing the
          MACsec session. In the case of a primary CAK, the status will be `rotating` for
          a period of time while waiting for the MACsec session to be secured with the new
          CAK. After that time, the CAK will either enter `active` or `inactive` status.
          Status `active` is returned when the CAK is configured successfully and is
          currently used to secure the MACsec session.
          Status `inactive` is returned when the CAK is configured successfully, but is
          not currently used to secure the MACsec session. The CAK may enter `rotating`
          status, and ultimately the `active` status, if it is found to be used to secure
          the MACsec session. The CAK may never leave this status on its own (e.g. if
          there is a key/key name mismatch). You are allowed to patch the CAK in this
          state to start the rotation procedure again.
          Status `failed` is returned when the CAK cannot be configured. To recover, first
          resolve any issues with your HPCS key, then patch this CAK with the same or new
          key. Alternatively, you can delete this CAK if used for the `fallback` session.
    :param datetime updated_at: The date and time the resource was last updated.
    """

    def __init__(
        self,
        created_at: datetime,
        id: str,
        key: 'HpcsKeyReference',
        name: str,
        session: str,
        status: str,
        updated_at: datetime,
        *,
        active_delta: Optional['GatewayMacsecCakActiveDelta'] = None,
    ) -> None:
        """
        Initialize a GatewayMacsecCak object.

        :param datetime created_at: The date and time the resource was created.
        :param str id: The unique identifier for this connectivity association key
               (CAK).
        :param HpcsKeyReference key: A reference to a [Hyper Protect Crypto Service
               Standard
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
        :param str name: The name identifies the connectivity association key (CAK)
               within the MACsec key chain.
               The CAK's `name` must be a hexadecimal string of even lengths between 2 to
               64 inclusive.
               This value, along with the material of the `key`, must match on the MACsec
               peers.
        :param str session: The intended session the key will be used to secure.
               If the `primary` MACsec session fails due to a key/key name mismatch on the
               peers, the `fallback` session can take over.
               There must be a `primary` session CAK. A `fallback` CAK is optional.
        :param str status: Current status of the CAK.
               Status `operational` is returned when the CAK is configured successfully.
               Status `rotating` is returned during a key rotation. The CAK defined by
               `active_delta` is still configured on the device and could be securing the
               MACsec session. In the case of a primary CAK, the status will be `rotating`
               for a period of time while waiting for the MACsec session to be secured
               with the new CAK. After that time, the CAK will either enter `active` or
               `inactive` status.
               Status `active` is returned when the CAK is configured successfully and is
               currently used to secure the MACsec session.
               Status `inactive` is returned when the CAK is configured successfully, but
               is not currently used to secure the MACsec session. The CAK may enter
               `rotating` status, and ultimately the `active` status, if it is found to be
               used to secure the MACsec session. The CAK may never leave this status on
               its own (e.g. if there is a key/key name mismatch). You are allowed to
               patch the CAK in this state to start the rotation procedure again.
               Status `failed` is returned when the CAK cannot be configured. To recover,
               first resolve any issues with your HPCS key, then patch this CAK with the
               same or new key. Alternatively, you can delete this CAK if used for the
               `fallback` session.
        :param datetime updated_at: The date and time the resource was last
               updated.
        :param GatewayMacsecCakActiveDelta active_delta: (optional) This field will
               be present when the `status` of the MACsec CAK is `rotating` or `inactive`.
               It may be present when the CAK `status` is `failed`.
               This object denotes the MACsec CAK's values prior to beginning a CAK
               rotation and represents the previous key still configured in the direct
               link's MACsec key chain.
               This object will be removed when the MACsec CAK rotation completes,
               indicating that the previous key has been removed from the key chain, and
               the current CAK's values are in use.
        """
        self.active_delta = active_delta
        self.created_at = created_at
        self.id = id
        self.key = key
        self.name = name
        self.session = session
        self.status = status
        self.updated_at = updated_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayMacsecCak':
        """Initialize a GatewayMacsecCak object from a json dictionary."""
        args = {}
        if (active_delta := _dict.get('active_delta')) is not None:
            args['active_delta'] = GatewayMacsecCakActiveDelta.from_dict(active_delta)
        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 GatewayMacsecCak JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in GatewayMacsecCak JSON')
        if (key := _dict.get('key')) is not None:
            args['key'] = HpcsKeyReference.from_dict(key)
        else:
            raise ValueError('Required property \'key\' not present in GatewayMacsecCak JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in GatewayMacsecCak JSON')
        if (session := _dict.get('session')) is not None:
            args['session'] = session
        else:
            raise ValueError('Required property \'session\' not present in GatewayMacsecCak JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in GatewayMacsecCak 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 GatewayMacsecCak JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayMacsecCak object from 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_delta') and self.active_delta is not None:
            if isinstance(self.active_delta, dict):
                _dict['active_delta'] = self.active_delta
            else:
                _dict['active_delta'] = self.active_delta.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, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'key') and self.key is not None:
            if isinstance(self.key, dict):
                _dict['key'] = self.key
            else:
                _dict['key'] = self.key.to_dict()
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'session') and self.session is not None:
            _dict['session'] = self.session
        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 GatewayMacsecCak object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class SessionEnum(str, Enum):
        """
        The intended session the key will be used to secure.
        If the `primary` MACsec session fails due to a key/key name mismatch on the peers,
        the `fallback` session can take over.
        There must be a `primary` session CAK. A `fallback` CAK is optional.
        """

        PRIMARY = 'primary'
        FALLBACK = 'fallback'


    class StatusEnum(str, Enum):
        """
        Current status of the CAK.
        Status `operational` is returned when the CAK is configured successfully.
        Status `rotating` is returned during a key rotation. The CAK defined by
        `active_delta` is still configured on the device and could be securing the MACsec
        session. In the case of a primary CAK, the status will be `rotating` for a period
        of time while waiting for the MACsec session to be secured with the new CAK. After
        that time, the CAK will either enter `active` or `inactive` status.
        Status `active` is returned when the CAK is configured successfully and is
        currently used to secure the MACsec session.
        Status `inactive` is returned when the CAK is configured successfully, but is not
        currently used to secure the MACsec session. The CAK may enter `rotating` status,
        and ultimately the `active` status, if it is found to be used to secure the MACsec
        session. The CAK may never leave this status on its own (e.g. if there is a
        key/key name mismatch). You are allowed to patch the CAK in this state to start
        the rotation procedure again.
        Status `failed` is returned when the CAK cannot be configured. To recover, first
        resolve any issues with your HPCS key, then patch this CAK with the same or new
        key. Alternatively, you can delete this CAK if used for the `fallback` session.
        """

        OPERATIONAL = 'operational'
        ROTATING = 'rotating'
        ACTIVE = 'active'
        INACTIVE = 'inactive'
        FAILED = 'failed'



class GatewayMacsecCakActiveDelta:
    """
    This field will be present when the `status` of the MACsec CAK is `rotating` or
    `inactive`. It may be present when the CAK `status` is `failed`.
    This object denotes the MACsec CAK's values prior to beginning a CAK rotation and
    represents the previous key still configured in the direct link's MACsec key chain.
    This object will be removed when the MACsec CAK rotation completes, indicating that
    the previous key has been removed from the key chain, and the current CAK's values are
    in use.

    :param HpcsKeyReference key: A reference to a [Hyper Protect Crypto Service
          Standard Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
    :param str name: The name identifies the connectivity association key (CAK)
          within the MACsec key chain.
          The CAK's `name` must be a hexadecimal string of even lengths between 2 to 64
          inclusive.
          This value, along with the material of the `key`, must match on the MACsec
          peers.
    :param str status: Current status of the CAK.
          Status `operational` is returned when the CAK is configured successfully.
          Status `rotating` is returned during a key rotation. The CAK defined by
          `active_delta` is still configured on the device and could be securing the
          MACsec session. In the case of a primary CAK, the status will be `rotating` for
          a period of time while waiting for the MACsec session to be secured with the new
          CAK. After that time, the CAK will either enter `active` or `inactive` status.
          Status `active` is returned when the CAK is configured successfully and is
          currently used to secure the MACsec session.
          Status `inactive` is returned when the CAK is configured successfully, but is
          not currently used to secure the MACsec session. The CAK may enter `rotating`
          status, and ultimately the `active` status, if it is found to be used to secure
          the MACsec session. The CAK may never leave this status on its own (e.g. if
          there is a key/key name mismatch). You are allowed to patch the CAK in this
          state to start the rotation procedure again.
          Status `failed` is returned when the CAK cannot be configured. To recover, first
          resolve any issues with your HPCS key, then patch this CAK with the same or new
          key. Alternatively, you can delete this CAK if used for the `fallback` session.
    """

    def __init__(
        self,
        key: 'HpcsKeyReference',
        name: str,
        status: str,
    ) -> None:
        """
        Initialize a GatewayMacsecCakActiveDelta object.

        :param HpcsKeyReference key: A reference to a [Hyper Protect Crypto Service
               Standard
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
        :param str name: The name identifies the connectivity association key (CAK)
               within the MACsec key chain.
               The CAK's `name` must be a hexadecimal string of even lengths between 2 to
               64 inclusive.
               This value, along with the material of the `key`, must match on the MACsec
               peers.
        :param str status: Current status of the CAK.
               Status `operational` is returned when the CAK is configured successfully.
               Status `rotating` is returned during a key rotation. The CAK defined by
               `active_delta` is still configured on the device and could be securing the
               MACsec session. In the case of a primary CAK, the status will be `rotating`
               for a period of time while waiting for the MACsec session to be secured
               with the new CAK. After that time, the CAK will either enter `active` or
               `inactive` status.
               Status `active` is returned when the CAK is configured successfully and is
               currently used to secure the MACsec session.
               Status `inactive` is returned when the CAK is configured successfully, but
               is not currently used to secure the MACsec session. The CAK may enter
               `rotating` status, and ultimately the `active` status, if it is found to be
               used to secure the MACsec session. The CAK may never leave this status on
               its own (e.g. if there is a key/key name mismatch). You are allowed to
               patch the CAK in this state to start the rotation procedure again.
               Status `failed` is returned when the CAK cannot be configured. To recover,
               first resolve any issues with your HPCS key, then patch this CAK with the
               same or new key. Alternatively, you can delete this CAK if used for the
               `fallback` session.
        """
        self.key = key
        self.name = name
        self.status = status

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

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

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

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

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

    class StatusEnum(str, Enum):
        """
        Current status of the CAK.
        Status `operational` is returned when the CAK is configured successfully.
        Status `rotating` is returned during a key rotation. The CAK defined by
        `active_delta` is still configured on the device and could be securing the MACsec
        session. In the case of a primary CAK, the status will be `rotating` for a period
        of time while waiting for the MACsec session to be secured with the new CAK. After
        that time, the CAK will either enter `active` or `inactive` status.
        Status `active` is returned when the CAK is configured successfully and is
        currently used to secure the MACsec session.
        Status `inactive` is returned when the CAK is configured successfully, but is not
        currently used to secure the MACsec session. The CAK may enter `rotating` status,
        and ultimately the `active` status, if it is found to be used to secure the MACsec
        session. The CAK may never leave this status on its own (e.g. if there is a
        key/key name mismatch). You are allowed to patch the CAK in this state to start
        the rotation procedure again.
        Status `failed` is returned when the CAK cannot be configured. To recover, first
        resolve any issues with your HPCS key, then patch this CAK with the same or new
        key. Alternatively, you can delete this CAK if used for the `fallback` session.
        """

        OPERATIONAL = 'operational'
        ROTATING = 'rotating'
        ACTIVE = 'active'
        INACTIVE = 'inactive'
        FAILED = 'failed'



class GatewayMacsecCakCollection:
    """
    List of all connectivity association keys (CAKs) associated with the MACsec feature on
    a direct link.

    :param List[GatewayMacsecCak] caks: (optional) List of all connectivity
          association keys (CAKs) associated with the MACsec feature on a direct link.
    """

    def __init__(
        self,
        *,
        caks: Optional[List['GatewayMacsecCak']] = None,
    ) -> None:
        """
        Initialize a GatewayMacsecCakCollection object.

        :param List[GatewayMacsecCak] caks: (optional) List of all connectivity
               association keys (CAKs) associated with the MACsec feature on a direct
               link.
        """
        self.caks = caks

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

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

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

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

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


class GatewayMacsecCakPatch:
    """
    Patch fields for CAK of MACsec configuration on a direct link.
    When rotating a CAK, patch both the `name` and `key` fields simultaneously. Both must
    have new values and cannot match with another CAK. Neither `name` nor `key` is allowed
    to be patched on its own.

    :param HpcsKeyIdentity key: (optional) A [Hyper Protect Crypto Service Standard
          Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
    :param str name: (optional) The name identifies the connectivity association key
          (CAK) within the MACsec key chain.
          The CAK's `name` must be a hexadecimal string of even lengths between 2 to 64
          inclusive.
          This value, along with the material of the `key`, must match on the MACsec
          peers.
    """

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

        :param HpcsKeyIdentity key: (optional) A [Hyper Protect Crypto Service
               Standard
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
        :param str name: (optional) The name identifies the connectivity
               association key (CAK) within the MACsec key chain.
               The CAK's `name` must be a hexadecimal string of even lengths between 2 to
               64 inclusive.
               This value, along with the material of the `key`, must match on the MACsec
               peers.
        """
        self.key = key
        self.name = name

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

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

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

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

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


class GatewayMacsecCakPrototype:
    """
    The prototype for a connectivity association key (CAK) used in the MACsec Key
    Agreement (MKA) protocol.

    :param HpcsKeyIdentity key: A [Hyper Protect Crypto Service Standard
          Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
    :param str name: The name identifies the connectivity association key (CAK)
          within the MACsec key chain.
          The CAK's `name` must be a hexadecimal string of even lengths between 2 to 64
          inclusive.
          This value, along with the material of the `key`, must match on the MACsec
          peers.
    :param str session: The intended session the key will be used to secure.
          If the `primary` MACsec session fails due to a key/key name mismatch on the
          peers, the `fallback` session can take over.
          There must be a `primary` session CAK. A `fallback` CAK is optional.
    """

    def __init__(
        self,
        key: 'HpcsKeyIdentity',
        name: str,
        session: str,
    ) -> None:
        """
        Initialize a GatewayMacsecCakPrototype object.

        :param HpcsKeyIdentity key: A [Hyper Protect Crypto Service Standard
               Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).
        :param str name: The name identifies the connectivity association key (CAK)
               within the MACsec key chain.
               The CAK's `name` must be a hexadecimal string of even lengths between 2 to
               64 inclusive.
               This value, along with the material of the `key`, must match on the MACsec
               peers.
        :param str session: The intended session the key will be used to secure.
               If the `primary` MACsec session fails due to a key/key name mismatch on the
               peers, the `fallback` session can take over.
               There must be a `primary` session CAK. A `fallback` CAK is optional.
        """
        self.key = key
        self.name = name
        self.session = session

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

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

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

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

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

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

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

    class SessionEnum(str, Enum):
        """
        The intended session the key will be used to secure.
        If the `primary` MACsec session fails due to a key/key name mismatch on the peers,
        the `fallback` session can take over.
        There must be a `primary` session CAK. A `fallback` CAK is optional.
        """

        PRIMARY = 'primary'
        FALLBACK = 'fallback'



class GatewayMacsecPatch:
    """
    Patch fields for MACsec configuration of a Direct Link gateway.

    :param bool active: (optional) Sets the MACsec feature to be active (true) or
          inactive (false) for a gateway.
    :param SakRekeyPatch sak_rekey: (optional) Determines how SAK rekeying occurs.
          It is either timer based or based on the amount of used packet numbers.
    :param str security_policy: (optional) Determines how packets without MACsec
          headers are handled.
          `must_secure` - Packets without MACsec headers are dropped. This policy should
          be used to prefer security over network availability.
          `should_secure` - Packets without MACsec headers are allowed. This policy should
          be used to prefer network availability over security.
    :param int window_size: (optional) The window size determines the number of
          frames in a window for replay protection.
          Replay protection is used to counter replay attacks. Frames within a window size
          can be out of order and are not replay protected.
    """

    def __init__(
        self,
        *,
        active: Optional[bool] = None,
        sak_rekey: Optional['SakRekeyPatch'] = None,
        security_policy: Optional[str] = None,
        window_size: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayMacsecPatch object.

        :param bool active: (optional) Sets the MACsec feature to be active (true)
               or inactive (false) for a gateway.
        :param SakRekeyPatch sak_rekey: (optional) Determines how SAK rekeying
               occurs. It is either timer based or based on the amount of used packet
               numbers.
        :param str security_policy: (optional) Determines how packets without
               MACsec headers are handled.
               `must_secure` - Packets without MACsec headers are dropped. This policy
               should be used to prefer security over network availability.
               `should_secure` - Packets without MACsec headers are allowed. This policy
               should be used to prefer network availability over security.
        :param int window_size: (optional) The window size determines the number of
               frames in a window for replay protection.
               Replay protection is used to counter replay attacks. Frames within a window
               size can be out of order and are not replay protected.
        """
        self.active = active
        self.sak_rekey = sak_rekey
        self.security_policy = security_policy
        self.window_size = window_size

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

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayMacsecPatch object from 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, 'sak_rekey') and self.sak_rekey is not None:
            if isinstance(self.sak_rekey, dict):
                _dict['sak_rekey'] = self.sak_rekey
            else:
                _dict['sak_rekey'] = self.sak_rekey.to_dict()
        if hasattr(self, 'security_policy') and self.security_policy is not None:
            _dict['security_policy'] = self.security_policy
        if hasattr(self, 'window_size') and self.window_size is not None:
            _dict['window_size'] = self.window_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 GatewayMacsecPatch object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class SecurityPolicyEnum(str, Enum):
        """
        Determines how packets without MACsec headers are handled.
        `must_secure` - Packets without MACsec headers are dropped. This policy should be
        used to prefer security over network availability.
        `should_secure` - Packets without MACsec headers are allowed. This policy should
        be used to prefer network availability over security.
        """

        MUST_SECURE = 'must_secure'
        SHOULD_SECURE = 'should_secure'



class GatewayMacsecPrototype:
    """
    MACsec configuration information of a Direct Link gateway.

    :param bool active: Determines if the MACsec feature should initially be active
          (true) or inactive (false) for a gateway.
    :param List[GatewayMacsecCakPrototype] caks: List of all connectivity
          association keys (CAKs) to be associated associated with the MACsec feature on a
          direct link.
          There must be at least one CAK with `session`: `primary`. There can be at most
          one CAK with `session`: `fallback`
          All CAKs must reference a unique key.
    :param SakRekeyPrototype sak_rekey: Determines how SAK rekeying occurs. It is
          either timer based or based on the amount of used packet numbers.
    :param str security_policy: Determines how packets without MACsec headers are
          handled.
          `must_secure` - Packets without MACsec headers are dropped. This policy should
          be used to prefer security over network availability.
          `should_secure` - Packets without MACsec headers are allowed. This policy should
          be used to prefer network availability over security.
    :param int window_size: (optional) The window size determines the number of
          frames in a window for replay protection.
          Replay protection is used to counter replay attacks. Frames within a window size
          can be out of order and are not replay protected.
    """

    def __init__(
        self,
        active: bool,
        caks: List['GatewayMacsecCakPrototype'],
        sak_rekey: 'SakRekeyPrototype',
        security_policy: str,
        *,
        window_size: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayMacsecPrototype object.

        :param bool active: Determines if the MACsec feature should initially be
               active (true) or inactive (false) for a gateway.
        :param List[GatewayMacsecCakPrototype] caks: List of all connectivity
               association keys (CAKs) to be associated associated with the MACsec feature
               on a direct link.
               There must be at least one CAK with `session`: `primary`. There can be at
               most one CAK with `session`: `fallback`
               All CAKs must reference a unique key.
        :param SakRekeyPrototype sak_rekey: Determines how SAK rekeying occurs. It
               is either timer based or based on the amount of used packet numbers.
        :param str security_policy: Determines how packets without MACsec headers
               are handled.
               `must_secure` - Packets without MACsec headers are dropped. This policy
               should be used to prefer security over network availability.
               `should_secure` - Packets without MACsec headers are allowed. This policy
               should be used to prefer network availability over security.
        :param int window_size: (optional) The window size determines the number of
               frames in a window for replay protection.
               Replay protection is used to counter replay attacks. Frames within a window
               size can be out of order and are not replay protected.
        """
        self.active = active
        self.caks = caks
        self.sak_rekey = sak_rekey
        self.security_policy = security_policy
        self.window_size = window_size

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayMacsecPrototype':
        """Initialize a GatewayMacsecPrototype 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 GatewayMacsecPrototype JSON')
        if (caks := _dict.get('caks')) is not None:
            args['caks'] = [GatewayMacsecCakPrototype.from_dict(v) for v in caks]
        else:
            raise ValueError('Required property \'caks\' not present in GatewayMacsecPrototype JSON')
        if (sak_rekey := _dict.get('sak_rekey')) is not None:
            args['sak_rekey'] = sak_rekey
        else:
            raise ValueError('Required property \'sak_rekey\' not present in GatewayMacsecPrototype JSON')
        if (security_policy := _dict.get('security_policy')) is not None:
            args['security_policy'] = security_policy
        else:
            raise ValueError('Required property \'security_policy\' not present in GatewayMacsecPrototype JSON')
        if (window_size := _dict.get('window_size')) is not None:
            args['window_size'] = window_size
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayMacsecPrototype object from 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, 'caks') and self.caks is not None:
            caks_list = []
            for v in self.caks:
                if isinstance(v, dict):
                    caks_list.append(v)
                else:
                    caks_list.append(v.to_dict())
            _dict['caks'] = caks_list
        if hasattr(self, 'sak_rekey') and self.sak_rekey is not None:
            if isinstance(self.sak_rekey, dict):
                _dict['sak_rekey'] = self.sak_rekey
            else:
                _dict['sak_rekey'] = self.sak_rekey.to_dict()
        if hasattr(self, 'security_policy') and self.security_policy is not None:
            _dict['security_policy'] = self.security_policy
        if hasattr(self, 'window_size') and self.window_size is not None:
            _dict['window_size'] = self.window_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 GatewayMacsecPrototype object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class SecurityPolicyEnum(str, Enum):
        """
        Determines how packets without MACsec headers are handled.
        `must_secure` - Packets without MACsec headers are dropped. This policy should be
        used to prefer security over network availability.
        `should_secure` - Packets without MACsec headers are allowed. This policy should
        be used to prefer network availability over security.
        """

        MUST_SECURE = 'must_secure'
        SHOULD_SECURE = 'should_secure'



class GatewayMacsecReference:
    """
    MACsec configuration information of a Direct Link gateway.

    :param bool active: Indicates if the MACsec feature is currently active (true)
          or inactive (false) for a gateway.
    :param str security_policy: Determines how packets without MACsec headers are
          handled.
          `must_secure` - Packets without MACsec headers are dropped. This policy should
          be used to prefer security over network availability.
          `should_secure` - Packets without MACsec headers are allowed. This policy should
          be used to prefer network availability over security.
    :param str status: Current status of MACsec on this direct link.
          Status `offline` is returned when MACsec is inactive and during direct link
          creation.
          Status `deleting` is returned when MACsec during removal of MACsec from the
          direct link and during direct link deletion.
          See `status_reasons[]` for possible remediation of the `failed` `status`.
    :param List[GatewayMacsecStatusReason] status_reasons: Context for certain
          values of `status`.
    """

    def __init__(
        self,
        active: bool,
        security_policy: str,
        status: str,
        status_reasons: List['GatewayMacsecStatusReason'],
    ) -> None:
        """
        Initialize a GatewayMacsecReference object.

        :param bool active: Indicates if the MACsec feature is currently active
               (true) or inactive (false) for a gateway.
        :param str security_policy: Determines how packets without MACsec headers
               are handled.
               `must_secure` - Packets without MACsec headers are dropped. This policy
               should be used to prefer security over network availability.
               `should_secure` - Packets without MACsec headers are allowed. This policy
               should be used to prefer network availability over security.
        :param str status: Current status of MACsec on this direct link.
               Status `offline` is returned when MACsec is inactive and during direct link
               creation.
               Status `deleting` is returned when MACsec during removal of MACsec from the
               direct link and during direct link deletion.
               See `status_reasons[]` for possible remediation of the `failed` `status`.
        :param List[GatewayMacsecStatusReason] status_reasons: Context for certain
               values of `status`.
        """
        self.active = active
        self.security_policy = security_policy
        self.status = status
        self.status_reasons = status_reasons

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayMacsecReference':
        """Initialize a GatewayMacsecReference 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 GatewayMacsecReference JSON')
        if (security_policy := _dict.get('security_policy')) is not None:
            args['security_policy'] = security_policy
        else:
            raise ValueError('Required property \'security_policy\' not present in GatewayMacsecReference JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in GatewayMacsecReference JSON')
        if (status_reasons := _dict.get('status_reasons')) is not None:
            args['status_reasons'] = [GatewayMacsecStatusReason.from_dict(v) for v in status_reasons]
        else:
            raise ValueError('Required property \'status_reasons\' not present in GatewayMacsecReference JSON')
        return cls(**args)

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

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

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

    class SecurityPolicyEnum(str, Enum):
        """
        Determines how packets without MACsec headers are handled.
        `must_secure` - Packets without MACsec headers are dropped. This policy should be
        used to prefer security over network availability.
        `should_secure` - Packets without MACsec headers are allowed. This policy should
        be used to prefer network availability over security.
        """

        MUST_SECURE = 'must_secure'
        SHOULD_SECURE = 'should_secure'


    class StatusEnum(str, Enum):
        """
        Current status of MACsec on this direct link.
        Status `offline` is returned when MACsec is inactive and during direct link
        creation.
        Status `deleting` is returned when MACsec during removal of MACsec from the direct
        link and during direct link deletion.
        See `status_reasons[]` for possible remediation of the `failed` `status`.
        """

        INIT = 'init'
        PENDING = 'pending'
        OFFLINE = 'offline'
        SECURED = 'secured'
        FAILED = 'failed'
        DELETING = 'deleting'



class GatewayMacsecStatusReason:
    """
    A reason for the current `status`.

    :param str code: A reason code for the status:
          - `macsec_cak_failed`: At least one of the connectivity association keys (CAKs)
          associated with the MACsec configuration was unable to be configured on the
          direct link gateway. Refer to the `status` of the CAKs associated with the
          MACsec configuration to find the the source of this reason.
    :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 GatewayMacsecStatusReason object.

        :param str code: A reason code for the status:
               - `macsec_cak_failed`: At least one of the connectivity association keys
               (CAKs) associated with the MACsec configuration was unable to be configured
               on the direct link gateway. Refer to the `status` of the CAKs associated
               with the MACsec configuration to find the the source of this reason.
        :param str message: An explanation of the status reason.
        :param str more_info: (optional) Link to documentation about this status
               reason.
        """
        self.code = code
        self.message = message
        self.more_info = more_info

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayMacsecStatusReason':
        """Initialize a GatewayMacsecStatusReason 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 GatewayMacsecStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in GatewayMacsecStatusReason 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 GatewayMacsecStatusReason object from 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 GatewayMacsecStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

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

    def __ne__(self, other: 'GatewayMacsecStatusReason') -> 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:
        - `macsec_cak_failed`: At least one of the connectivity association keys (CAKs)
        associated with the MACsec configuration was unable to be configured on the direct
        link gateway. Refer to the `status` of the CAKs associated with the MACsec
        configuration to find the the source of this reason.
        """

        MACSEC_CAK_FAILED = 'macsec_cak_failed'



class GatewayPatchTemplate:
    """
    patch gateway template.

    :param AuthenticationKeyIdentity authentication_key: (optional) A reference to a
          key to use as the BGP MD5 authentication key.
          Patch to `null` to disable BGP MD5 authentication.
    :param GatewayBfdPatchTemplate bfd_config: (optional) BFD configuration
          information.
    :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 connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param str default_export_route_filter: (optional) The default directional route
          filter action that applies to routes that do not match any directional route
          filters.
    :param str default_import_route_filter: (optional) The default directional route
          filter action that applies to routes that do not match any directional route
          filters.
    :param bool global_: (optional) Gateways with global routing (`true`) can
          connect to networks outside of their associated region.
    :param str loa_reject_reason: (optional) Use this field during LOA rejection to
          provide the reason for the rejection.
          Only allowed for type=dedicated gateways.
    :param bool metered: (optional) Metered billing option.  When `true` gateway
          usage is billed per gigabyte.  When `false` there is no per gigabyte usage
          charge, instead a flat rate is charged for the gateway.
    :param str name: (optional) The unique user-defined name for this gateway.
    :param str operational_status: (optional) Gateway operational status.
          For gateways pending LOA approval, patch operational_status to the appropriate
          value to approve or reject its LOA.  When rejecting an LOA, provide reject
          reasoning in `loa_reject_reason`.
          Only allowed for type=dedicated gateways.
    :param str patch_panel_completion_notice: (optional) Gateway patch panel
          complete notification from implementation team.
    :param int speed_mbps: (optional) Gateway speed in megabits per second.
    :param int vlan: (optional) The VLAN to configure for this gateway.
          Specify `null` to remove an existing VLAN configuration.
          The gateway must have a `type` of `dedicated`.
    """

    def __init__(
        self,
        *,
        authentication_key: Optional['AuthenticationKeyIdentity'] = None,
        bfd_config: Optional['GatewayBfdPatchTemplate'] = None,
        bgp_asn: Optional[int] = None,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_cidr: Optional[str] = None,
        connection_mode: Optional[str] = None,
        default_export_route_filter: Optional[str] = None,
        default_import_route_filter: Optional[str] = None,
        global_: Optional[bool] = None,
        loa_reject_reason: Optional[str] = None,
        metered: Optional[bool] = None,
        name: Optional[str] = None,
        operational_status: Optional[str] = None,
        patch_panel_completion_notice: Optional[str] = None,
        speed_mbps: Optional[int] = None,
        vlan: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayPatchTemplate object.

        :param AuthenticationKeyIdentity authentication_key: (optional) A reference
               to a key to use as the BGP MD5 authentication key.
               Patch to `null` to disable BGP MD5 authentication.
        :param GatewayBfdPatchTemplate bfd_config: (optional) BFD configuration
               information.
        :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 connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str default_export_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param str default_import_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param bool global_: (optional) Gateways with global routing (`true`) can
               connect to networks outside of their associated region.
        :param str loa_reject_reason: (optional) Use this field during LOA
               rejection to provide the reason for the rejection.
               Only allowed for type=dedicated gateways.
        :param bool metered: (optional) Metered billing option.  When `true`
               gateway usage is billed per gigabyte.  When `false` there is no per
               gigabyte usage charge, instead a flat rate is charged for the gateway.
        :param str name: (optional) The unique user-defined name for this gateway.
        :param str operational_status: (optional) Gateway operational status.
               For gateways pending LOA approval, patch operational_status to the
               appropriate value to approve or reject its LOA.  When rejecting an LOA,
               provide reject reasoning in `loa_reject_reason`.
               Only allowed for type=dedicated gateways.
        :param str patch_panel_completion_notice: (optional) Gateway patch panel
               complete notification from implementation team.
        :param int speed_mbps: (optional) Gateway speed in megabits per second.
        :param int vlan: (optional) The VLAN to configure for this gateway.
               Specify `null` to remove an existing VLAN configuration.
               The gateway must have a `type` of `dedicated`.
        """
        self.authentication_key = authentication_key
        self.bfd_config = bfd_config
        self.bgp_asn = bgp_asn
        self.bgp_cer_cidr = bgp_cer_cidr
        self.bgp_ibm_cidr = bgp_ibm_cidr
        self.connection_mode = connection_mode
        self.default_export_route_filter = default_export_route_filter
        self.default_import_route_filter = default_import_route_filter
        self.global_ = global_
        self.loa_reject_reason = loa_reject_reason
        self.metered = metered
        self.name = name
        self.operational_status = operational_status
        self.patch_panel_completion_notice = patch_panel_completion_notice
        self.speed_mbps = speed_mbps
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayPatchTemplate':
        """Initialize a GatewayPatchTemplate object from a json dictionary."""
        args = {}
        if (authentication_key := _dict.get('authentication_key')) is not None:
            args['authentication_key'] = authentication_key
        if (bfd_config := _dict.get('bfd_config')) is not None:
            args['bfd_config'] = GatewayBfdPatchTemplate.from_dict(bfd_config)
        if (bgp_asn := _dict.get('bgp_asn')) is not None:
            args['bgp_asn'] = bgp_asn
        if (bgp_cer_cidr := _dict.get('bgp_cer_cidr')) is not None:
            args['bgp_cer_cidr'] = bgp_cer_cidr
        if (bgp_ibm_cidr := _dict.get('bgp_ibm_cidr')) is not None:
            args['bgp_ibm_cidr'] = bgp_ibm_cidr
        if (connection_mode := _dict.get('connection_mode')) is not None:
            args['connection_mode'] = connection_mode
        if (default_export_route_filter := _dict.get('default_export_route_filter')) is not None:
            args['default_export_route_filter'] = default_export_route_filter
        if (default_import_route_filter := _dict.get('default_import_route_filter')) is not None:
            args['default_import_route_filter'] = default_import_route_filter
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        if (loa_reject_reason := _dict.get('loa_reject_reason')) is not None:
            args['loa_reject_reason'] = loa_reject_reason
        if (metered := _dict.get('metered')) is not None:
            args['metered'] = metered
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (operational_status := _dict.get('operational_status')) is not None:
            args['operational_status'] = operational_status
        if (patch_panel_completion_notice := _dict.get('patch_panel_completion_notice')) is not None:
            args['patch_panel_completion_notice'] = patch_panel_completion_notice
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        if (vlan := _dict.get('vlan')) is not None:
            args['vlan'] = vlan
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayPatchTemplate object from 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_key') and self.authentication_key is not None:
            if isinstance(self.authentication_key, dict):
                _dict['authentication_key'] = self.authentication_key
            else:
                _dict['authentication_key'] = self.authentication_key.to_dict()
        if hasattr(self, 'bfd_config') and self.bfd_config is not None:
            if isinstance(self.bfd_config, dict):
                _dict['bfd_config'] = self.bfd_config
            else:
                _dict['bfd_config'] = self.bfd_config.to_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_cidr') and self.bgp_ibm_cidr is not None:
            _dict['bgp_ibm_cidr'] = self.bgp_ibm_cidr
        if hasattr(self, 'connection_mode') and self.connection_mode is not None:
            _dict['connection_mode'] = self.connection_mode
        if hasattr(self, 'default_export_route_filter') and self.default_export_route_filter is not None:
            _dict['default_export_route_filter'] = self.default_export_route_filter
        if hasattr(self, 'default_import_route_filter') and self.default_import_route_filter is not None:
            _dict['default_import_route_filter'] = self.default_import_route_filter
        if hasattr(self, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'loa_reject_reason') and self.loa_reject_reason is not None:
            _dict['loa_reject_reason'] = self.loa_reject_reason
        if hasattr(self, 'metered') and self.metered is not None:
            _dict['metered'] = self.metered
        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, 'patch_panel_completion_notice') and self.patch_panel_completion_notice is not None:
            _dict['patch_panel_completion_notice'] = self.patch_panel_completion_notice
        if hasattr(self, 'speed_mbps') and self.speed_mbps is not None:
            _dict['speed_mbps'] = self.speed_mbps
        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 GatewayPatchTemplate object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class DefaultExportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class DefaultImportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class OperationalStatusEnum(str, Enum):
        """
        Gateway operational status.
        For gateways pending LOA approval, patch operational_status to the appropriate
        value to approve or reject its LOA.  When rejecting an LOA, provide reject
        reasoning in `loa_reject_reason`.
        Only allowed for type=dedicated gateways.
        """

        LOA_ACCEPTED = 'loa_accepted'
        LOA_REJECTED = 'loa_rejected'



class GatewayPortIdentity:
    """
    Select Port Label for new type=connect gateway.

    :param str id: port id.
    """

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

        :param str id: port id.
        """
        self.id = id

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

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

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

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


class GatewayPortReference:
    """
    Port information for type=connect gateways.

    :param str id: Port Identifier.
    """

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

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

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

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

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

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


class GatewayStatistic:
    """
    Gateway statistics and debug commands.

    :param datetime created_at: Date and time data was collected.
    :param str data: statistics output.
    :param str type: statistic type.
    """

    def __init__(
        self,
        created_at: datetime,
        data: str,
        type: str,
    ) -> None:
        """
        Initialize a GatewayStatistic object.

        :param datetime created_at: Date and time data was collected.
        :param str data: statistics output.
        :param str type: statistic type.
        """
        self.created_at = created_at
        self.data = data
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayStatistic':
        """Initialize a GatewayStatistic 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 GatewayStatistic JSON')
        if (data := _dict.get('data')) is not None:
            args['data'] = data
        else:
            raise ValueError('Required property \'data\' not present in GatewayStatistic JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in GatewayStatistic JSON')
        return cls(**args)

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

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

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

    class TypeEnum(str, Enum):
        """
        statistic type.
        """

        MACSEC_MKA_SESSION = 'macsec_mka_session'
        MACSEC_POLICY = 'macsec_policy'
        MACSEC_MKA_STATISTICS = 'macsec_mka_statistics'
        BFD_SESSION = 'bfd_session'



class GatewayStatisticCollection:
    """
    gateway statistics.

    :param List[GatewayStatistic] statistics: Collection of gateway statistics.
    """

    def __init__(
        self,
        statistics: List['GatewayStatistic'],
    ) -> None:
        """
        Initialize a GatewayStatisticCollection object.

        :param List[GatewayStatistic] statistics: Collection of gateway statistics.
        """
        self.statistics = statistics

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

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

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

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

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


class GatewayStatus:
    """
    GatewayStatus.

    """

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

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


class GatewayStatusCollection:
    """
    gateway status.

    :param List[GatewayStatus] status: (optional) array of status.
    """

    def __init__(
        self,
        *,
        status: Optional[List['GatewayStatus']] = None,
    ) -> None:
        """
        Initialize a GatewayStatusCollection object.

        :param List[GatewayStatus] status: (optional) array of status.
        """
        self.status = status

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

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayStatusCollection object from 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:
            status_list = []
            for v in self.status:
                if isinstance(v, dict):
                    status_list.append(v)
                else:
                    status_list.append(v.to_dict())
            _dict['status'] = status_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 GatewayStatusCollection object."""
        return json.dumps(self.to_dict(), indent=2)

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

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


class GatewayStatusReason:
    """
    A reason for the current `operational_status`.

    :param str code: A reason code for the status:
          - `authentication_key_failed`: `authentication_key` was unable to be configured
          on the direct link gateway. To recover, first resolve any issues with your key,
          then patch the gateway with the same or new key.
    :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 GatewayStatusReason object.

        :param str code: A reason code for the status:
               - `authentication_key_failed`: `authentication_key` was unable to be
               configured on the direct link gateway. To recover, first resolve any issues
               with your key, then patch the gateway with the same or new key.
        :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) -> 'GatewayStatusReason':
        """Initialize a GatewayStatusReason 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 GatewayStatusReason JSON')
        if (message := _dict.get('message')) is not None:
            args['message'] = message
        else:
            raise ValueError('Required property \'message\' not present in GatewayStatusReason 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 GatewayStatusReason object from 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 GatewayStatusReason object."""
        return json.dumps(self.to_dict(), indent=2)

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

    def __ne__(self, other: 'GatewayStatusReason') -> 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:
        - `authentication_key_failed`: `authentication_key` was unable to be configured on
        the direct link gateway. To recover, first resolve any issues with your key, then
        patch the gateway with the same or new key.
        """

        AUTHENTICATION_KEY_FAILED = 'authentication_key_failed'



class GatewayTemplate:
    """
    Create gateway template.

    :param List[AsPrependTemplate] as_prepends: (optional) array of AS Prepend
          configuration information.
    :param AuthenticationKeyIdentity authentication_key: (optional)
    :param GatewayBfdConfigTemplate bfd_config: (optional) BFD configuration
          information.
    :param int bgp_asn: BGP ASN.
    :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR.
          Field is deprecated.  See bgp_ibm_cidr and bgp_cer_cidr for details on how to
          create a gateway using either automatic or explicit IP assignment.  Any
          bgp_base_cidr value set will be ignored.
          Deprecated field bgp_base_cidr will be removed from the API specification after
          15-MAR-2021.
    :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 explicit 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 explicit 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 connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param str default_export_route_filter: (optional) The default directional route
          filter action that applies to routes that do not match any directional route
          filters.
    :param str default_import_route_filter: (optional) The default directional route
          filter action that applies to routes that do not match any directional route
          filters.
    :param List[GatewayTemplateRouteFilter] export_route_filters: (optional) Array
          of directional route filters for a Direct Link gateway. When creating a gateway
          or replacing existing route filters, the order of the items in the array will
          set the ordering of the list of route filters.
    :param bool global_: Gateways with global routing (`true`) can connect to
          networks outside their associated region.
    :param List[GatewayTemplateRouteFilter] import_route_filters: (optional) Array
          of directional route filters for a Direct Link gateway. When creating a gateway
          or replacing existing route filters, the order of the items in the array will
          set the ordering of the list of route filters.
    :param bool metered: Metered billing option.  When `true` gateway usage is
          billed per gigabyte.  When `false` there is no per gigabyte usage charge,
          instead a flat rate is charged for the gateway.
    :param str name: The unique user-defined name for this gateway.
    :param str patch_panel_completion_notice: (optional) Gateway patch panel
          complete notification from implementation team.
    :param ResourceGroupIdentity resource_group: (optional) Resource group for this
          resource. If unspecified, the account's [default resource
          group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.
    :param int speed_mbps: Gateway speed in megabits per second.
    :param str type: Offering type.
    """

    def __init__(
        self,
        bgp_asn: int,
        global_: bool,
        metered: bool,
        name: str,
        speed_mbps: int,
        type: str,
        *,
        as_prepends: Optional[List['AsPrependTemplate']] = None,
        authentication_key: Optional['AuthenticationKeyIdentity'] = None,
        bfd_config: Optional['GatewayBfdConfigTemplate'] = None,
        bgp_base_cidr: Optional[str] = None,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_cidr: Optional[str] = None,
        connection_mode: Optional[str] = None,
        default_export_route_filter: Optional[str] = None,
        default_import_route_filter: Optional[str] = None,
        export_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        import_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        patch_panel_completion_notice: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
    ) -> None:
        """
        Initialize a GatewayTemplate object.

        :param int bgp_asn: BGP ASN.
        :param bool global_: Gateways with global routing (`true`) can connect to
               networks outside their associated region.
        :param bool metered: Metered billing option.  When `true` gateway usage is
               billed per gigabyte.  When `false` there is no per gigabyte usage charge,
               instead a flat rate is charged for the gateway.
        :param str name: The unique user-defined name for this gateway.
        :param int speed_mbps: Gateway speed in megabits per second.
        :param str type: Offering type.
        :param List[AsPrependTemplate] as_prepends: (optional) array of AS Prepend
               configuration information.
        :param AuthenticationKeyIdentity authentication_key: (optional)
        :param GatewayBfdConfigTemplate bfd_config: (optional) BFD configuration
               information.
        :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR.
               Field is deprecated.  See bgp_ibm_cidr and bgp_cer_cidr for details on how
               to create a gateway using either automatic or explicit IP assignment.  Any
               bgp_base_cidr value set will be ignored.
               Deprecated field bgp_base_cidr will be removed from the API specification
               after 15-MAR-2021.
        :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 explicit 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 explicit 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 connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str default_export_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param str default_import_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param List[GatewayTemplateRouteFilter] export_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param List[GatewayTemplateRouteFilter] import_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param str patch_panel_completion_notice: (optional) Gateway patch panel
               complete notification from implementation team.
        :param ResourceGroupIdentity resource_group: (optional) Resource group for
               this resource. If unspecified, the account's [default resource
               group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is
               used.
        """
        msg = "Cannot instantiate base class. Instead, instantiate one of the defined subclasses: {0}".format(
            ", ".join(['GatewayTemplateGatewayTypeDedicatedTemplate', 'GatewayTemplateGatewayTypeConnectTemplate'])
        )
        raise Exception(msg)

    class ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class DefaultExportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class DefaultImportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class TypeEnum(str, Enum):
        """
        Offering type.
        """

        CONNECT = 'connect'
        DEDICATED = 'dedicated'



class GatewayTemplateRouteFilter:
    """
    The route filter create template within the Direct Link gateway create template.

    :param str action: Determines whether routes that match the prefix-set will be
          allowed (permit) or rejected (deny) through the filter.
    :param int ge: (optional) The minimum matching length of the prefix-set
          (mnemonic for greater than or equal to).
    :param int le: (optional) The maximum matching length of the prefix-set
          (mnemonic for less than or equal to).
    :param str prefix: IP prefix representing an address and mask length of the
          prefix-set.
    """

    def __init__(
        self,
        action: str,
        prefix: str,
        *,
        ge: Optional[int] = None,
        le: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayTemplateRouteFilter object.

        :param str action: Determines whether routes that match the prefix-set will
               be allowed (permit) or rejected (deny) through the filter.
        :param str prefix: IP prefix representing an address and mask length of the
               prefix-set.
        :param int ge: (optional) The minimum matching length of the prefix-set
               (mnemonic for greater than or equal to).
        :param int le: (optional) The maximum matching length of the prefix-set
               (mnemonic for less than or equal to).
        """
        self.action = action
        self.ge = ge
        self.le = le
        self.prefix = prefix

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayTemplateRouteFilter':
        """Initialize a GatewayTemplateRouteFilter 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 GatewayTemplateRouteFilter JSON')
        if (ge := _dict.get('ge')) is not None:
            args['ge'] = ge
        if (le := _dict.get('le')) is not None:
            args['le'] = le
        if (prefix := _dict.get('prefix')) is not None:
            args['prefix'] = prefix
        else:
            raise ValueError('Required property \'prefix\' not present in GatewayTemplateRouteFilter JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayTemplateRouteFilter object from 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, 'ge') and self.ge is not None:
            _dict['ge'] = self.ge
        if hasattr(self, 'le') and self.le is not None:
            _dict['le'] = self.le
        if hasattr(self, 'prefix') and self.prefix is not None:
            _dict['prefix'] = self.prefix
        return _dict

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

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

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

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

    class ActionEnum(str, Enum):
        """
        Determines whether routes that match the prefix-set will be allowed (permit) or
        rejected (deny) through the filter.
        """

        PERMIT = 'permit'
        DENY = 'deny'



class GatewayVirtualConnection:
    """
    Virtual connection.

    :param datetime created_at: The date and time resource was created.
    :param str id: The unique identifier for this virtual connection.
    :param str name: The user-defined name for this virtual connection.  Virtual
          connection names are unique within a gateway.  This is the name of the virtual
          connection itself, the network being connected may have its own name attribute.
    :param str network_account: (optional) For virtual connections across two
          different IBM Cloud Accounts network_account indicates the account that owns the
          target network.
    :param str network_id: (optional) Unique identifier of the target network.  For
          type=vpc virtual connections this is the CRN of the target VPC.  This field does
          not apply to type=classic connections.
    :param str status: Status of the virtual connection.
          The list of enumerated values for this property may expand in the future. Code
          and processes using this field  must tolerate unexpected values.
    :param str type: Virtual connection type.
          The list of enumerated values for this property may expand in the future. Code
          and processes using this field  must tolerate unexpected values.
    """

    def __init__(
        self,
        created_at: datetime,
        id: str,
        name: str,
        status: str,
        type: str,
        *,
        network_account: Optional[str] = None,
        network_id: Optional[str] = None,
    ) -> None:
        """
        Initialize a GatewayVirtualConnection object.

        :param datetime created_at: The date and time resource was created.
        :param str id: The unique identifier for this virtual connection.
        :param str name: The user-defined name for this virtual connection.
               Virtual connection names are unique within a gateway.  This is the name of
               the virtual connection itself, the network being connected may have its own
               name attribute.
        :param str status: Status of the virtual connection.
               The list of enumerated values for this property may expand in the future.
               Code and processes using this field  must tolerate unexpected values.
        :param str type: Virtual connection type.
               The list of enumerated values for this property may expand in the future.
               Code and processes using this field  must tolerate unexpected values.
        :param str network_account: (optional) For virtual connections across two
               different IBM Cloud Accounts network_account indicates the account that
               owns the target network.
        :param str network_id: (optional) Unique identifier of the target network.
               For type=vpc virtual connections this is the CRN of the target VPC.  This
               field does not apply to type=classic connections.
        """
        self.created_at = created_at
        self.id = id
        self.name = name
        self.network_account = network_account
        self.network_id = network_id
        self.status = status
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayVirtualConnection':
        """Initialize a GatewayVirtualConnection 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 GatewayVirtualConnection JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in GatewayVirtualConnection JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in GatewayVirtualConnection JSON')
        if (network_account := _dict.get('network_account')) is not None:
            args['network_account'] = network_account
        if (network_id := _dict.get('network_id')) is not None:
            args['network_id'] = network_id
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in GatewayVirtualConnection JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in GatewayVirtualConnection JSON')
        return cls(**args)

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

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

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

    class StatusEnum(str, Enum):
        """
        Status of the virtual connection.
        The list of enumerated values for this property may expand in the future. Code and
        processes using this field  must tolerate unexpected values.
        """

        PENDING = 'pending'
        ATTACHED = 'attached'
        APPROVAL_PENDING = 'approval_pending'
        REJECTED = 'rejected'
        EXPIRED = 'expired'
        DELETING = 'deleting'
        DETACHED_BY_NETWORK_PENDING = 'detached_by_network_pending'
        DETACHED_BY_NETWORK = 'detached_by_network'


    class TypeEnum(str, Enum):
        """
        Virtual connection type.
        The list of enumerated values for this property may expand in the future. Code and
        processes using this field  must tolerate unexpected values.
        """

        CLASSIC = 'classic'
        VPC = 'vpc'
        TRANSIT = 'transit'



class GatewayVirtualConnectionCollection:
    """
    Virtual connection collection.

    :param List[GatewayVirtualConnection] virtual_connections: virtual connection
          array.
    """

    def __init__(
        self,
        virtual_connections: List['GatewayVirtualConnection'],
    ) -> None:
        """
        Initialize a GatewayVirtualConnectionCollection object.

        :param List[GatewayVirtualConnection] virtual_connections: virtual
               connection array.
        """
        self.virtual_connections = virtual_connections

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

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

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

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

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

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

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


class GatewayVirtualConnectionPatchTemplate:
    """
    Patch virtual connection template.

    :param str name: (optional) The user-defined name for this virtual connection.
          Virtual connection names are unique within a gateway.  This is the name of the
          virtual connection itself, the network being connected may have its own name
          attribute.
    :param str status: (optional) Status of the virtual connection.  Virtual
          connections that span IBM Cloud Accounts are created in approval_pending status.
           The owner of the target network can accept or reject connection requests by
          patching status to attached or rejected respectively.
    """

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

        :param str name: (optional) The user-defined name for this virtual
               connection.  Virtual connection names are unique within a gateway.  This is
               the name of the virtual connection itself, the network being connected may
               have its own name attribute.
        :param str status: (optional) Status of the virtual connection.  Virtual
               connections that span IBM Cloud Accounts are created in approval_pending
               status.  The owner of the target network can accept or reject connection
               requests by patching status to attached or rejected respectively.
        """
        self.name = name
        self.status = status

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

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

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

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

    class StatusEnum(str, Enum):
        """
        Status of the virtual connection.  Virtual connections that span IBM Cloud
        Accounts are created in approval_pending status.  The owner of the target network
        can accept or reject connection requests by patching status to attached or
        rejected respectively.
        """

        ATTACHED = 'attached'
        REJECTED = 'rejected'



class GetGatewayResponse:
    """
    GetGatewayResponse.

    """

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

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


class HpcsKeyIdentity:
    """
    A [Hyper Protect Crypto Service Standard
    Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).

    :param str crn: The CRN of the key.
    """

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

        :param str crn: The CRN of the key.
        """
        self.crn = crn

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

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

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

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

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


class HpcsKeyReference:
    """
    A reference to a [Hyper Protect Crypto Service Standard
    Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).

    :param str crn: The CRN of the referenced key.
    """

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

        :param str crn: The CRN of the referenced key.
        """
        self.crn = crn

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

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

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

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

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


class ImportRouteFilterCollection:
    """
    Collection of import route filters.

    :param List[RouteFilter] import_route_filters: Array of import route filters.
    """

    def __init__(
        self,
        import_route_filters: List['RouteFilter'],
    ) -> None:
        """
        Initialize a ImportRouteFilterCollection object.

        :param List[RouteFilter] import_route_filters: Array of import route
               filters.
        """
        self.import_route_filters = import_route_filters

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

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

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

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

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


class LocationCollection:
    """
    location collection.

    :param List[LocationOutput] locations: Collection of Direct Link locations.
    """

    def __init__(
        self,
        locations: List['LocationOutput'],
    ) -> None:
        """
        Initialize a LocationCollection object.

        :param List[LocationOutput] locations: Collection of Direct Link locations.
        """
        self.locations = locations

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

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

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

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

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


class LocationCrossConnectRouterCollection:
    """
    List of cross connect router details.

    :param List[CrossConnectRouter] cross_connect_routers: (optional) Array of
          Routers for this location.
    """

    def __init__(
        self,
        *,
        cross_connect_routers: Optional[List['CrossConnectRouter']] = None,
    ) -> None:
        """
        Initialize a LocationCrossConnectRouterCollection object.

        :param List[CrossConnectRouter] cross_connect_routers: (optional) Array of
               Routers for this location.
        """
        self.cross_connect_routers = cross_connect_routers

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

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

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

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

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


class LocationOutput:
    """
    location.

    :param str billing_location: (optional) Billing location.  Only present for
          locations where provisioning is enabled.
    :param str building_colocation_owner: (optional) Building colocation owner.
          Only present for offering_type=dedicated locations where provisioning is
          enabled.
    :param str display_name: Location long name.
    :param str location_type: Location type.
    :param bool macsec_enabled: (optional) Indicate whether location supports
          MACsec.  Only returned for gateway type=dedicated locations.  Contact IBM
          support for access to MACsec.
    :param str market: Location market.
    :param str market_geography: (optional) Location geography.  Only present for
          locations where provisioning is enabled.
    :param bool mzr: (optional) Is location a multi-zone region (MZR).  Only present
          for locations where provisioning is enabled.
    :param str name: Location short name.
    :param str offering_type: Location offering type.
    :param bool provision_enabled: Indicates for the specific offering_type whether
          this location supports gateway provisioning.
    :param str vpc_region: (optional) Location's VPC region.  Only present for
          locations where provisioning is enabled.
    """

    def __init__(
        self,
        display_name: str,
        location_type: str,
        market: str,
        name: str,
        offering_type: str,
        provision_enabled: bool,
        *,
        billing_location: Optional[str] = None,
        building_colocation_owner: Optional[str] = None,
        macsec_enabled: Optional[bool] = None,
        market_geography: Optional[str] = None,
        mzr: Optional[bool] = None,
        vpc_region: Optional[str] = None,
    ) -> None:
        """
        Initialize a LocationOutput object.

        :param str display_name: Location long name.
        :param str location_type: Location type.
        :param str market: Location market.
        :param str name: Location short name.
        :param str offering_type: Location offering type.
        :param bool provision_enabled: Indicates for the specific offering_type
               whether this location supports gateway provisioning.
        :param str billing_location: (optional) Billing location.  Only present for
               locations where provisioning is enabled.
        :param str building_colocation_owner: (optional) Building colocation owner.
                Only present for offering_type=dedicated locations where provisioning is
               enabled.
        :param bool macsec_enabled: (optional) Indicate whether location supports
               MACsec.  Only returned for gateway type=dedicated locations.  Contact IBM
               support for access to MACsec.
        :param str market_geography: (optional) Location geography.  Only present
               for locations where provisioning is enabled.
        :param bool mzr: (optional) Is location a multi-zone region (MZR).  Only
               present for locations where provisioning is enabled.
        :param str vpc_region: (optional) Location's VPC region.  Only present for
               locations where provisioning is enabled.
        """
        self.billing_location = billing_location
        self.building_colocation_owner = building_colocation_owner
        self.display_name = display_name
        self.location_type = location_type
        self.macsec_enabled = macsec_enabled
        self.market = market
        self.market_geography = market_geography
        self.mzr = mzr
        self.name = name
        self.offering_type = offering_type
        self.provision_enabled = provision_enabled
        self.vpc_region = vpc_region

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'LocationOutput':
        """Initialize a LocationOutput object from a json dictionary."""
        args = {}
        if (billing_location := _dict.get('billing_location')) is not None:
            args['billing_location'] = billing_location
        if (building_colocation_owner := _dict.get('building_colocation_owner')) is not None:
            args['building_colocation_owner'] = building_colocation_owner
        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 LocationOutput JSON')
        if (location_type := _dict.get('location_type')) is not None:
            args['location_type'] = location_type
        else:
            raise ValueError('Required property \'location_type\' not present in LocationOutput JSON')
        if (macsec_enabled := _dict.get('macsec_enabled')) is not None:
            args['macsec_enabled'] = macsec_enabled
        if (market := _dict.get('market')) is not None:
            args['market'] = market
        else:
            raise ValueError('Required property \'market\' not present in LocationOutput JSON')
        if (market_geography := _dict.get('market_geography')) is not None:
            args['market_geography'] = market_geography
        if (mzr := _dict.get('mzr')) is not None:
            args['mzr'] = mzr
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in LocationOutput JSON')
        if (offering_type := _dict.get('offering_type')) is not None:
            args['offering_type'] = offering_type
        else:
            raise ValueError('Required property \'offering_type\' not present in LocationOutput JSON')
        if (provision_enabled := _dict.get('provision_enabled')) is not None:
            args['provision_enabled'] = provision_enabled
        else:
            raise ValueError('Required property \'provision_enabled\' not present in LocationOutput JSON')
        if (vpc_region := _dict.get('vpc_region')) is not None:
            args['vpc_region'] = vpc_region
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'billing_location') and self.billing_location is not None:
            _dict['billing_location'] = self.billing_location
        if hasattr(self, 'building_colocation_owner') and self.building_colocation_owner is not None:
            _dict['building_colocation_owner'] = self.building_colocation_owner
        if hasattr(self, 'display_name') and self.display_name is not None:
            _dict['display_name'] = self.display_name
        if hasattr(self, 'location_type') and self.location_type is not None:
            _dict['location_type'] = self.location_type
        if hasattr(self, 'macsec_enabled') and self.macsec_enabled is not None:
            _dict['macsec_enabled'] = self.macsec_enabled
        if hasattr(self, 'market') and self.market is not None:
            _dict['market'] = self.market
        if hasattr(self, 'market_geography') and self.market_geography is not None:
            _dict['market_geography'] = self.market_geography
        if hasattr(self, 'mzr') and self.mzr is not None:
            _dict['mzr'] = self.mzr
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'offering_type') and self.offering_type is not None:
            _dict['offering_type'] = self.offering_type
        if hasattr(self, 'provision_enabled') and self.provision_enabled is not None:
            _dict['provision_enabled'] = self.provision_enabled
        if hasattr(self, 'vpc_region') and self.vpc_region is not None:
            _dict['vpc_region'] = self.vpc_region
        return _dict

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

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

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

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


class OfferingSpeed:
    """
    Speed.

    :param List[str] capabilities: Array of capabilities for billing option.
    :param int link_speed: Link speed in megabits per second.
    :param bool macsec_enabled: (optional) Indicate whether speed supports MACsec.
          Only returned for gateway type=dedicated speeds.  Contact IBM support for access
          to MACsec.
    """

    def __init__(
        self,
        capabilities: List[str],
        link_speed: int,
        *,
        macsec_enabled: Optional[bool] = None,
    ) -> None:
        """
        Initialize a OfferingSpeed object.

        :param List[str] capabilities: Array of capabilities for billing option.
        :param int link_speed: Link speed in megabits per second.
        :param bool macsec_enabled: (optional) Indicate whether speed supports
               MACsec.  Only returned for gateway type=dedicated speeds.  Contact IBM
               support for access to MACsec.
        """
        self.capabilities = capabilities
        self.link_speed = link_speed
        self.macsec_enabled = macsec_enabled

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

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

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

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

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

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

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


class OfferingSpeedCollection:
    """
    List of speeds.

    :param List[OfferingSpeed] speeds: speed list.
    """

    def __init__(
        self,
        speeds: List['OfferingSpeed'],
    ) -> None:
        """
        Initialize a OfferingSpeedCollection object.

        :param List[OfferingSpeed] speeds: speed list.
        """
        self.speeds = speeds

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

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

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

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

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


class Port:
    """
    Provider port details.

    :param int direct_link_count: Count of existing Direct Link gateways in this
          account on this port.
    :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's provider name.
    :param List[int] supported_link_speeds: Port's supported speeds in megabits per
          second.
    """

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

        :param int direct_link_count: Count of existing Direct Link gateways in
               this account on this port.
        :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's provider name.
        :param List[int] supported_link_speeds: Port's supported speeds in megabits
               per second.
        """
        self.direct_link_count = direct_link_count
        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) -> 'Port':
        """Initialize a Port object from a json dictionary."""
        args = {}
        if (direct_link_count := _dict.get('direct_link_count')) is not None:
            args['direct_link_count'] = direct_link_count
        else:
            raise ValueError('Required property \'direct_link_count\' not present in Port JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in Port JSON')
        if (label := _dict.get('label')) is not None:
            args['label'] = label
        else:
            raise ValueError('Required property \'label\' not present in Port JSON')
        if (location_display_name := _dict.get('location_display_name')) is not None:
            args['location_display_name'] = location_display_name
        else:
            raise ValueError('Required property \'location_display_name\' not present in Port JSON')
        if (location_name := _dict.get('location_name')) is not None:
            args['location_name'] = location_name
        else:
            raise ValueError('Required property \'location_name\' not present in Port JSON')
        if (provider_name := _dict.get('provider_name')) is not None:
            args['provider_name'] = provider_name
        else:
            raise ValueError('Required property \'provider_name\' not present in Port JSON')
        if (supported_link_speeds := _dict.get('supported_link_speeds')) is not None:
            args['supported_link_speeds'] = supported_link_speeds
        else:
            raise ValueError('Required property \'supported_link_speeds\' not present in Port JSON')
        return cls(**args)

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

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

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

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


class PortCollection:
    """
    List of port label details.

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

    def __init__(
        self,
        first: 'PortsPaginatedCollectionFirst',
        limit: int,
        total_count: int,
        *,
        next: Optional['PortsPaginatedCollectionNext'] = None,
        ports: Optional[List['Port']] = None,
    ) -> None:
        """
        Initialize a PortCollection object.

        :param PortsPaginatedCollectionFirst 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 PortsPaginatedCollectionNext next: (optional) A reference to the
               next page of resources; this reference is included for all pages except the
               last page.
        :param List[Port] 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) -> 'PortCollection':
        """Initialize a PortCollection object from a json dictionary."""
        args = {}
        if (first := _dict.get('first')) is not None:
            args['first'] = PortsPaginatedCollectionFirst.from_dict(first)
        else:
            raise ValueError('Required property \'first\' not present in PortCollection JSON')
        if (limit := _dict.get('limit')) is not None:
            args['limit'] = limit
        else:
            raise ValueError('Required property \'limit\' not present in PortCollection JSON')
        if (next := _dict.get('next')) is not None:
            args['next'] = PortsPaginatedCollectionNext.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 PortCollection JSON')
        if (ports := _dict.get('ports')) is not None:
            args['ports'] = [Port.from_dict(v) for v in ports]
        return cls(**args)

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

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

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


class PortsPaginatedCollectionFirst:
    """
    A reference to the first page of resources.

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

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

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

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

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

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

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

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

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

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


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

    :param str href: URL for the next page of resources.
    :param str start: (optional) start token for the next page of resources.
    """

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

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

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'PortsPaginatedCollectionNext':
        """Initialize a PortsPaginatedCollectionNext 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 PortsPaginatedCollectionNext JSON')
        if (start := _dict.get('start')) is not None:
            args['start'] = start
        return cls(**args)

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

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

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

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


class ResourceGroupIdentity:
    """
    Resource group for this resource. If unspecified, the account's [default resource
    group](https://cloud.ibm.com/apidocs/resource-manager#introduction) is used.

    :param str id: Resource group identifier.
    """

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

        :param str id: Resource group identifier.
        """
        self.id = id

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

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

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

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


class ResourceGroupReference:
    """
    Resource group reference.

    :param str id: Resource group identifier.
    """

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

        :param str id: Resource group identifier.
        """
        self.id = id

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

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

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

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

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


class RouteFilter:
    """
    Route filter.

    :param str action: Determines whether routes that match the prefix-set will be
          allowed (permit) or rejected (deny) through the filter.
    :param str before: (optional) Identifier of the next route filter considered if
          a route does not match the current filter. This property builds the ordering
          among route filters and follows semantics:
          - When before is an identifier of a route filter that exists and is in the same
          collection, a route will first attempt to match on the current filter before
          preceding to the filter referenced in this property.
          - When a filter is created with before that matches another filter in the same
          collection, the existing filter will take precedence. The before of the existing
          filter will be updated to refer to the newly created filter. The newly created
          filter will refer to the route filter identified by the provided before.
          - When a filter is created without a before, it takes the lowest precedence. The
          existing filter of lowest precedence will be updated to refer to the newly
          created filter.
    :param datetime created_at: The date and time the route filter was created in
          ISO 8601 format.
    :param int ge: (optional) The minimum matching length of the prefix-set
          (mnemonic for greater than or equal to).
    :param str id: The identifier of a route filter.
    :param int le: (optional) The maximum matching length of the prefix-set
          (mnemonic for less than or equal to).
    :param str prefix: IP prefix representing an address and mask length of the
          prefix-set.
    :param datetime updated_at: The date and time the route filter was last updated.
    """

    def __init__(
        self,
        action: str,
        created_at: datetime,
        id: str,
        prefix: str,
        updated_at: datetime,
        *,
        before: Optional[str] = None,
        ge: Optional[int] = None,
        le: Optional[int] = None,
    ) -> None:
        """
        Initialize a RouteFilter object.

        :param str action: Determines whether routes that match the prefix-set will
               be allowed (permit) or rejected (deny) through the filter.
        :param datetime created_at: The date and time the route filter was created
               in ISO 8601 format.
        :param str id: The identifier of a route filter.
        :param str prefix: IP prefix representing an address and mask length of the
               prefix-set.
        :param datetime updated_at: The date and time the route filter was last
               updated.
        :param str before: (optional) Identifier of the next route filter
               considered if a route does not match the current filter. This property
               builds the ordering among route filters and follows semantics:
               - When before is an identifier of a route filter that exists and is in the
               same collection, a route will first attempt to match on the current filter
               before preceding to the filter referenced in this property.
               - When a filter is created with before that matches another filter in the
               same collection, the existing filter will take precedence. The before of
               the existing filter will be updated to refer to the newly created filter.
               The newly created filter will refer to the route filter identified by the
               provided before.
               - When a filter is created without a before, it takes the lowest
               precedence. The existing filter of lowest precedence will be updated to
               refer to the newly created filter.
        :param int ge: (optional) The minimum matching length of the prefix-set
               (mnemonic for greater than or equal to).
        :param int le: (optional) The maximum matching length of the prefix-set
               (mnemonic for less than or equal to).
        """
        self.action = action
        self.before = before
        self.created_at = created_at
        self.ge = ge
        self.id = id
        self.le = le
        self.prefix = prefix
        self.updated_at = updated_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteFilter':
        """Initialize a RouteFilter 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 RouteFilter JSON')
        if (before := _dict.get('before')) is not None:
            args['before'] = 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 RouteFilter JSON')
        if (ge := _dict.get('ge')) is not None:
            args['ge'] = ge
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RouteFilter JSON')
        if (le := _dict.get('le')) is not None:
            args['le'] = le
        if (prefix := _dict.get('prefix')) is not None:
            args['prefix'] = prefix
        else:
            raise ValueError('Required property \'prefix\' not present in RouteFilter 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 RouteFilter JSON')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'action') and self.action is not None:
            _dict['action'] = self.action
        if hasattr(self, 'before') and self.before is not None:
            _dict['before'] = self.before
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'ge') and self.ge is not None:
            _dict['ge'] = self.ge
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'le') and self.le is not None:
            _dict['le'] = self.le
        if hasattr(self, 'prefix') and self.prefix is not None:
            _dict['prefix'] = self.prefix
        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 RouteFilter object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class ActionEnum(str, Enum):
        """
        Determines whether routes that match the prefix-set will be allowed (permit) or
        rejected (deny) through the filter.
        """

        PERMIT = 'permit'
        DENY = 'deny'



class RouteReport:
    """
    route report.

    :param List[RouteReportAdvertisedRoute] advertised_routes: (optional) Array of
          connection prefixes advertised to the on-prem network. This parameter is not
          returned when the route report was generated prior to inclusion of this
          parameter.
    :param datetime created_at: Date and time route report was requested.
    :param List[RouteReportRoute] gateway_routes: Array of local/direct routes.
    :param str id: Report identifier.
    :param List[RouteReportOnPremRoute] on_prem_routes: Array of on premises routes.
    :param List[RouteReportOverlappingRouteGroup] overlapping_routes: Array of
          overlapping routes.
    :param str status: Route report 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 datetime updated_at: (optional) Date and time route report was last
          modified.
    :param List[RouteReportConnection] virtual_connection_routes: Array of routes on
          virtual connections.
    """

    def __init__(
        self,
        created_at: datetime,
        gateway_routes: List['RouteReportRoute'],
        id: str,
        on_prem_routes: List['RouteReportOnPremRoute'],
        overlapping_routes: List['RouteReportOverlappingRouteGroup'],
        status: str,
        virtual_connection_routes: List['RouteReportConnection'],
        *,
        advertised_routes: Optional[List['RouteReportAdvertisedRoute']] = None,
        updated_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a RouteReport object.

        :param datetime created_at: Date and time route report was requested.
        :param List[RouteReportRoute] gateway_routes: Array of local/direct routes.
        :param str id: Report identifier.
        :param List[RouteReportOnPremRoute] on_prem_routes: Array of on premises
               routes.
        :param List[RouteReportOverlappingRouteGroup] overlapping_routes: Array of
               overlapping routes.
        :param str status: Route report 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 List[RouteReportConnection] virtual_connection_routes: Array of
               routes on virtual connections.
        :param List[RouteReportAdvertisedRoute] advertised_routes: (optional) Array
               of connection prefixes advertised to the on-prem network. This parameter is
               not returned when the route report was generated prior to inclusion of this
               parameter.
        :param datetime updated_at: (optional) Date and time route report was last
               modified.
        """
        self.advertised_routes = advertised_routes
        self.created_at = created_at
        self.gateway_routes = gateway_routes
        self.id = id
        self.on_prem_routes = on_prem_routes
        self.overlapping_routes = overlapping_routes
        self.status = status
        self.updated_at = updated_at
        self.virtual_connection_routes = virtual_connection_routes

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteReport':
        """Initialize a RouteReport object from a json dictionary."""
        args = {}
        if (advertised_routes := _dict.get('advertised_routes')) is not None:
            args['advertised_routes'] = [RouteReportAdvertisedRoute.from_dict(v) for v in advertised_routes]
        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 RouteReport JSON')
        if (gateway_routes := _dict.get('gateway_routes')) is not None:
            args['gateway_routes'] = [RouteReportRoute.from_dict(v) for v in gateway_routes]
        else:
            raise ValueError('Required property \'gateway_routes\' not present in RouteReport JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in RouteReport JSON')
        if (on_prem_routes := _dict.get('on_prem_routes')) is not None:
            args['on_prem_routes'] = [RouteReportOnPremRoute.from_dict(v) for v in on_prem_routes]
        else:
            raise ValueError('Required property \'on_prem_routes\' not present in RouteReport JSON')
        if (overlapping_routes := _dict.get('overlapping_routes')) is not None:
            args['overlapping_routes'] = [RouteReportOverlappingRouteGroup.from_dict(v) for v in overlapping_routes]
        else:
            raise ValueError('Required property \'overlapping_routes\' not present in RouteReport JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in RouteReport JSON')
        if (updated_at := _dict.get('updated_at')) is not None:
            args['updated_at'] = string_to_datetime(updated_at)
        if (virtual_connection_routes := _dict.get('virtual_connection_routes')) is not None:
            args['virtual_connection_routes'] = [RouteReportConnection.from_dict(v) for v in virtual_connection_routes]
        else:
            raise ValueError('Required property \'virtual_connection_routes\' not present in RouteReport JSON')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'advertised_routes') and self.advertised_routes is not None:
            advertised_routes_list = []
            for v in self.advertised_routes:
                if isinstance(v, dict):
                    advertised_routes_list.append(v)
                else:
                    advertised_routes_list.append(v.to_dict())
            _dict['advertised_routes'] = advertised_routes_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, 'gateway_routes') and self.gateway_routes is not None:
            gateway_routes_list = []
            for v in self.gateway_routes:
                if isinstance(v, dict):
                    gateway_routes_list.append(v)
                else:
                    gateway_routes_list.append(v.to_dict())
            _dict['gateway_routes'] = gateway_routes_list
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'on_prem_routes') and self.on_prem_routes is not None:
            on_prem_routes_list = []
            for v in self.on_prem_routes:
                if isinstance(v, dict):
                    on_prem_routes_list.append(v)
                else:
                    on_prem_routes_list.append(v.to_dict())
            _dict['on_prem_routes'] = on_prem_routes_list
        if hasattr(self, 'overlapping_routes') and self.overlapping_routes is not None:
            overlapping_routes_list = []
            for v in self.overlapping_routes:
                if isinstance(v, dict):
                    overlapping_routes_list.append(v)
                else:
                    overlapping_routes_list.append(v.to_dict())
            _dict['overlapping_routes'] = overlapping_routes_list
        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, 'virtual_connection_routes') and self.virtual_connection_routes is not None:
            virtual_connection_routes_list = []
            for v in self.virtual_connection_routes:
                if isinstance(v, dict):
                    virtual_connection_routes_list.append(v)
                else:
                    virtual_connection_routes_list.append(v.to_dict())
            _dict['virtual_connection_routes'] = virtual_connection_routes_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 RouteReport object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class StatusEnum(str, Enum):
        """
        Route report status. The list of enumerated values for this property may expand in
        the future. Code and processes using this field must tolerate unexpected values.
        """

        COMPLETE = 'complete'
        PENDING = 'pending'



class RouteReportAdvertisedRoute:
    """
    Route advertised to the on-prem network.

    :param str as_path: The BGP AS path of the route.
    :param str prefix: prefix.
    """

    def __init__(
        self,
        as_path: str,
        prefix: str,
    ) -> None:
        """
        Initialize a RouteReportAdvertisedRoute object.

        :param str as_path: The BGP AS path of the route.
        :param str prefix: prefix.
        """
        self.as_path = as_path
        self.prefix = prefix

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

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

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

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

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

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

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


class RouteReportCollection:
    """
    route reports.

    :param List[RouteReport] route_reports: Array of route reports.
    """

    def __init__(
        self,
        route_reports: List['RouteReport'],
    ) -> None:
        """
        Initialize a RouteReportCollection object.

        :param List[RouteReport] route_reports: Array of route reports.
        """
        self.route_reports = route_reports

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

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

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

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

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


class RouteReportConnection:
    """
    Routes of a virtual connection.

    :param List[RouteReportVirtualConnectionRoute] routes: Array of virtual
          connection's routes.
    :param str virtual_connection_id: (optional) ID of virtual connection.
    :param str virtual_connection_name: (optional) name of virtual connection.
    :param str virtual_connection_type: (optional) type of virtual connection.
    """

    def __init__(
        self,
        routes: List['RouteReportVirtualConnectionRoute'],
        *,
        virtual_connection_id: Optional[str] = None,
        virtual_connection_name: Optional[str] = None,
        virtual_connection_type: Optional[str] = None,
    ) -> None:
        """
        Initialize a RouteReportConnection object.

        :param List[RouteReportVirtualConnectionRoute] routes: Array of virtual
               connection's routes.
        :param str virtual_connection_id: (optional) ID of virtual connection.
        :param str virtual_connection_name: (optional) name of virtual connection.
        :param str virtual_connection_type: (optional) type of virtual connection.
        """
        self.routes = routes
        self.virtual_connection_id = virtual_connection_id
        self.virtual_connection_name = virtual_connection_name
        self.virtual_connection_type = virtual_connection_type

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

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

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

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

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

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

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


class RouteReportOnPremRoute:
    """
    on-prem route.

    :param str as_path: (optional) The BGP AS path of the route.
    :param str next_hop: (optional) Next hop address.
    :param str prefix: (optional) prefix.
    """

    def __init__(
        self,
        *,
        as_path: Optional[str] = None,
        next_hop: Optional[str] = None,
        prefix: Optional[str] = None,
    ) -> None:
        """
        Initialize a RouteReportOnPremRoute object.

        :param str as_path: (optional) The BGP AS path of the route.
        :param str next_hop: (optional) Next hop address.
        :param str prefix: (optional) prefix.
        """
        self.as_path = as_path
        self.next_hop = next_hop
        self.prefix = prefix

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

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

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

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

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

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

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


class RouteReportOverlappingRoute:
    """
    overlapping route details.

    """

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

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


class RouteReportOverlappingRouteGroup:
    """
    Collection of overlapping route.

    :param List[RouteReportOverlappingRoute] routes: (optional) Array of overlapping
          connection/prefix pairs.
    """

    def __init__(
        self,
        *,
        routes: Optional[List['RouteReportOverlappingRoute']] = None,
    ) -> None:
        """
        Initialize a RouteReportOverlappingRouteGroup object.

        :param List[RouteReportOverlappingRoute] routes: (optional) Array of
               overlapping connection/prefix pairs.
        """
        self.routes = routes

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

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

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

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

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

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

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


class RouteReportRoute:
    """
    route.

    :param str prefix: (optional) prefix.
    """

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

        :param str prefix: (optional) prefix.
        """
        self.prefix = prefix

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

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

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

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

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

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

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


class RouteReportVirtualConnectionRoute:
    """
    A route originating from an attached virtual connection.

    :param bool active: (optional) Indicates whether the route is the preferred path
          of the prefix.
    :param str local_preference: (optional) The local preference of the route. This
          attribute can manipulate the chosen path on routes.
    :param str prefix: prefix.
    """

    def __init__(
        self,
        prefix: str,
        *,
        active: Optional[bool] = None,
        local_preference: Optional[str] = None,
    ) -> None:
        """
        Initialize a RouteReportVirtualConnectionRoute object.

        :param str prefix: prefix.
        :param bool active: (optional) Indicates whether the route is the preferred
               path of the prefix.
        :param str local_preference: (optional) The local preference of the route.
               This attribute can manipulate the chosen path on routes.
        """
        self.active = active
        self.local_preference = local_preference
        self.prefix = prefix

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

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a RouteReportVirtualConnectionRoute object from 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, 'local_preference') and self.local_preference is not None:
            _dict['local_preference'] = self.local_preference
        if hasattr(self, 'prefix') and self.prefix is not None:
            _dict['prefix'] = self.prefix
        return _dict

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

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

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

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


class SakRekey:
    """
    Determines how SAK rekeying occurs. It is either timer based or based on the amount of
    used packet numbers.

    """

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

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


class SakRekeyPatch:
    """
    Determines how SAK rekeying occurs. It is either timer based or based on the amount of
    used packet numbers.

    """

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

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


class SakRekeyPrototype:
    """
    Determines how SAK rekeying occurs. It is either timer based or based on the amount of
    used packet numbers.

    """

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

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


class UpdateRouteFilterTemplate:
    """
    The route filter update template.

    :param str action: (optional) Determines whether routes that match the
          prefix-set will be allowed (permit) or rejected (deny) through the filter.
    :param str before: (optional) Identifier of the next route filter considered if
          a route does not match the current filter. This property builds the ordering
          among route filters and follows semantics:
          - When before is an identifier of a route filter that exists and is in the same
          collection, a route will first attempt to match on the current filter before
          preceding to the filter referenced in this property.
          - When a filter is created with before that matches another filter in the same
          collection, the existing filter will take precedence. The before of the existing
          filter will be updated to refer to the newly created filter. The newly created
          filter will refer to the route filter identified by the provided before.
          - When a filter is created without a before, it takes the lowest precedence. The
          existing filter of lowest precedence will be updated to refer to the newly
          created filter.
    :param int ge: (optional) The minimum matching length of the prefix-set
          (mnemonic for greater than or equal to).
          To clear the minimum matching length of the filter, patch the value to `0`.
    :param int le: (optional) The maximum matching length of the prefix-set
          (mnemonic for less than or equal to).
          To clear the maximum matching length of the filter, patch the value to `0`.
    :param str prefix: (optional) IP prefix representing an address and mask length
          of the prefix-set.
    """

    def __init__(
        self,
        *,
        action: Optional[str] = None,
        before: Optional[str] = None,
        ge: Optional[int] = None,
        le: Optional[int] = None,
        prefix: Optional[str] = None,
    ) -> None:
        """
        Initialize a UpdateRouteFilterTemplate object.

        :param str action: (optional) Determines whether routes that match the
               prefix-set will be allowed (permit) or rejected (deny) through the filter.
        :param str before: (optional) Identifier of the next route filter
               considered if a route does not match the current filter. This property
               builds the ordering among route filters and follows semantics:
               - When before is an identifier of a route filter that exists and is in the
               same collection, a route will first attempt to match on the current filter
               before preceding to the filter referenced in this property.
               - When a filter is created with before that matches another filter in the
               same collection, the existing filter will take precedence. The before of
               the existing filter will be updated to refer to the newly created filter.
               The newly created filter will refer to the route filter identified by the
               provided before.
               - When a filter is created without a before, it takes the lowest
               precedence. The existing filter of lowest precedence will be updated to
               refer to the newly created filter.
        :param int ge: (optional) The minimum matching length of the prefix-set
               (mnemonic for greater than or equal to).
               To clear the minimum matching length of the filter, patch the value to `0`.
        :param int le: (optional) The maximum matching length of the prefix-set
               (mnemonic for less than or equal to).
               To clear the maximum matching length of the filter, patch the value to `0`.
        :param str prefix: (optional) IP prefix representing an address and mask
               length of the prefix-set.
        """
        self.action = action
        self.before = before
        self.ge = ge
        self.le = le
        self.prefix = prefix

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'UpdateRouteFilterTemplate':
        """Initialize a UpdateRouteFilterTemplate 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 (ge := _dict.get('ge')) is not None:
            args['ge'] = ge
        if (le := _dict.get('le')) is not None:
            args['le'] = le
        if (prefix := _dict.get('prefix')) is not None:
            args['prefix'] = prefix
        return cls(**args)

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

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

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

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

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

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

    class ActionEnum(str, Enum):
        """
        Determines whether routes that match the prefix-set will be allowed (permit) or
        rejected (deny) through the filter.
        """

        PERMIT = 'permit'
        DENY = 'deny'



class AuthenticationKeyIdentityHpcsAuthenticationKeyIdentity(AuthenticationKeyIdentity):
    """
    A [Hyper Protect Crypto Service Standard
    Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).

    :param str crn: The CRN of the key.
    """

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

        :param str crn: The CRN of the key.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

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

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

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

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

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


class AuthenticationKeyIdentityKeyProtectAuthenticationKeyIdentity(AuthenticationKeyIdentity):
    """
    A [Key Protect Standard
    Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial).

    :param str crn: The CRN of the key.
    """

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

        :param str crn: The CRN of the key.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

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

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

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

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

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


class AuthenticationKeyReferenceHpcsAuthenticationKeyReference(AuthenticationKeyReference):
    """
    A reference to a [Hyper Protect Crypto Service Standard
    Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started).

    :param str crn: The CRN of the referenced key.
    """

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

        :param str crn: The CRN of the referenced key.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

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

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

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

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

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


class AuthenticationKeyReferenceKeyProtectAuthenticationKeyReference(AuthenticationKeyReference):
    """
    A reference to a [Key Protect Standard
    Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial).

    :param str crn: The CRN of the referenced key.
    """

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

        :param str crn: The CRN of the referenced key.
        """
        # pylint: disable=super-init-not-called
        self.crn = crn

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

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

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

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

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


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

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

    def __init__(
        self,
        *,
        bgp_asn: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayActionTemplateUpdatesItemGatewayClientBGPASNUpdate 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) -> 'GatewayActionTemplateUpdatesItemGatewayClientBGPASNUpdate':
        """Initialize a GatewayActionTemplateUpdatesItemGatewayClientBGPASNUpdate object from a json dictionary."""
        args = {}
        if (bgp_asn := _dict.get('bgp_asn')) is not None:
            args['bgp_asn'] = bgp_asn
        return cls(**args)

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

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

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


class GatewayActionTemplateUpdatesItemGatewayClientBGPIPUpdate(GatewayActionTemplateUpdatesItem):
    """
    Update BGP customer and IBM CIDR.

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

    def __init__(
        self,
        *,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_cidr: Optional[str] = None,
    ) -> None:
        """
        Initialize a GatewayActionTemplateUpdatesItemGatewayClientBGPIPUpdate 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) -> 'GatewayActionTemplateUpdatesItemGatewayClientBGPIPUpdate':
        """Initialize a GatewayActionTemplateUpdatesItemGatewayClientBGPIPUpdate object from a json dictionary."""
        args = {}
        if (bgp_cer_cidr := _dict.get('bgp_cer_cidr')) is not None:
            args['bgp_cer_cidr'] = bgp_cer_cidr
        if (bgp_ibm_cidr := _dict.get('bgp_ibm_cidr')) is not None:
            args['bgp_ibm_cidr'] = bgp_ibm_cidr
        return cls(**args)

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

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

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


class GatewayActionTemplateUpdatesItemGatewayClientSpeedUpdate(GatewayActionTemplateUpdatesItem):
    """
    gateway speed change.

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

    def __init__(
        self,
        *,
        speed_mbps: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayActionTemplateUpdatesItemGatewayClientSpeedUpdate 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) -> 'GatewayActionTemplateUpdatesItemGatewayClientSpeedUpdate':
        """Initialize a GatewayActionTemplateUpdatesItemGatewayClientSpeedUpdate object from a json dictionary."""
        args = {}
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        return cls(**args)

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

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

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


class GatewayActionTemplateUpdatesItemGatewayClientVLANUpdate(GatewayActionTemplateUpdatesItem):
    """
    Update VLAN for this gateway
    VLAN provided should be in the range 2 to 3967.

    :param int vlan: (optional) VLAN to be updated for this gateway.
    """

    def __init__(
        self,
        *,
        vlan: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayActionTemplateUpdatesItemGatewayClientVLANUpdate object.

        :param int vlan: (optional) VLAN to be updated for this gateway.
        """
        # pylint: disable=super-init-not-called
        self.vlan = vlan

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

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

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

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


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

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

    def __init__(
        self,
        *,
        bgp_asn: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientBGPASNUpdate 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) -> 'GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientBGPASNUpdate':
        """Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientBGPASNUpdate object from a json dictionary."""
        args = {}
        if (bgp_asn := _dict.get('bgp_asn')) is not None:
            args['bgp_asn'] = bgp_asn
        return cls(**args)

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

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

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


class GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientBGPIPUpdate(GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItem):
    """
    Update BGP customer and IBM CIDR.

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

    def __init__(
        self,
        *,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_cidr: Optional[str] = None,
    ) -> None:
        """
        Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientBGPIPUpdate 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) -> 'GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientBGPIPUpdate':
        """Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientBGPIPUpdate object from a json dictionary."""
        args = {}
        if (bgp_cer_cidr := _dict.get('bgp_cer_cidr')) is not None:
            args['bgp_cer_cidr'] = bgp_cer_cidr
        if (bgp_ibm_cidr := _dict.get('bgp_ibm_cidr')) is not None:
            args['bgp_ibm_cidr'] = bgp_ibm_cidr
        return cls(**args)

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

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

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


class GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientSpeedUpdate(GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItem):
    """
    gateway speed change.

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

    def __init__(
        self,
        *,
        speed_mbps: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientSpeedUpdate 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) -> 'GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientSpeedUpdate':
        """Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientSpeedUpdate object from a json dictionary."""
        args = {}
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        return cls(**args)

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

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

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


class GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientVLANUpdate(GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItem):
    """
    Update VLAN for this gateway
    VLAN provided should be in the range 2 to 3967.

    :param int vlan: (optional) VLAN to be updated for this gateway.
    """

    def __init__(
        self,
        *,
        vlan: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItemGatewayClientVLANUpdate object.

        :param int vlan: (optional) VLAN to be updated for this gateway.
        """
        # pylint: disable=super-init-not-called
        self.vlan = vlan

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

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

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

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


class GatewayChangeRequestGatewayClientGatewayCreate(GatewayChangeRequest):
    """
    gateway create.

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

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a GatewayChangeRequestGatewayClientGatewayCreate 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) -> 'GatewayChangeRequestGatewayClientGatewayCreate':
        """Initialize a GatewayChangeRequestGatewayClientGatewayCreate 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 GatewayChangeRequestGatewayClientGatewayCreate JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'GatewayChangeRequestGatewayClientGatewayCreate') -> 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 GatewayChangeRequestGatewayClientGatewayDelete(GatewayChangeRequest):
    """
    gateway delete.

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

    def __init__(
        self,
        type: str,
    ) -> None:
        """
        Initialize a GatewayChangeRequestGatewayClientGatewayDelete 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) -> 'GatewayChangeRequestGatewayClientGatewayDelete':
        """Initialize a GatewayChangeRequestGatewayClientGatewayDelete 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 GatewayChangeRequestGatewayClientGatewayDelete JSON')
        return cls(**args)

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

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

    def __ne__(self, other: 'GatewayChangeRequestGatewayClientGatewayDelete') -> 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 GatewayChangeRequestGatewayClientGatewayUpdateAttributes(GatewayChangeRequest):
    """
    gateway attributes update.

    :param str type: type of gateway change request.
    :param List[GatewayChangeRequestGatewayClientGatewayUpdateAttributesUpdatesItem]
          updates: array of pending updates.
    """

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

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

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayChangeRequestGatewayClientGatewayUpdateAttributes':
        """Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributes 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 GatewayChangeRequestGatewayClientGatewayUpdateAttributes JSON')
        if (updates := _dict.get('updates')) is not None:
            args['updates'] = updates
        else:
            raise ValueError('Required property \'updates\' not present in GatewayChangeRequestGatewayClientGatewayUpdateAttributes JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayChangeRequestGatewayClientGatewayUpdateAttributes object from 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 v in self.updates:
                if isinstance(v, dict):
                    updates_list.append(v)
                else:
                    updates_list.append(v.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 GatewayChangeRequestGatewayClientGatewayUpdateAttributes object."""
        return json.dumps(self.to_dict(), indent=2)

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

    def __ne__(self, other: 'GatewayChangeRequestGatewayClientGatewayUpdateAttributes') -> 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 GatewayCollectionGatewaysItemCrossAccountGateway(GatewayCollectionGatewaysItem):
    """
    cross-account gateway read-only view.

    :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 datetime bgp_status_updated_at: (optional) Date and time bgp status was
          updated.
    :param str connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param datetime created_at: The date and time resource was created.
    :param str crn: The CRN (Cloud Resource Name) of this gateway.
    :param bool cross_account: Indicates whether this gateway is cross account
          gateway.
    :param str cross_connect_router: (optional) Cross connect router. Only included
          on type=dedicated gateways.
    :param bool global_: Gateways with global routing (`true`) can connect to
          networks outside their associated region.
    :param str id: The unique identifier of this gateway.
    :param str link_status: (optional) Gateway link status.  Only included on
          type=dedicated gateways. The list of enumerated values for this property may
          expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    :param datetime link_status_updated_at: (optional) Date and time link status was
          updated.
    :param str location_display_name: Gateway location long name.
    :param str location_name: Gateway location.
    :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 GatewayPortReference port: (optional) Port information for type=connect
          gateways.
    :param int speed_mbps: Gateway speed in megabits per second.
    :param str type: Offering type. The list of enumerated values for this property
          may expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        cross_account: bool,
        global_: bool,
        id: str,
        location_display_name: str,
        location_name: str,
        name: str,
        operational_status: str,
        speed_mbps: int,
        type: str,
        *,
        bgp_status: Optional[str] = None,
        bgp_status_updated_at: Optional[datetime] = None,
        connection_mode: Optional[str] = None,
        cross_connect_router: Optional[str] = None,
        link_status: Optional[str] = None,
        link_status_updated_at: Optional[datetime] = None,
        port: Optional['GatewayPortReference'] = None,
    ) -> None:
        """
        Initialize a GatewayCollectionGatewaysItemCrossAccountGateway object.

        :param datetime created_at: The date and time resource was created.
        :param str crn: The CRN (Cloud Resource Name) of this gateway.
        :param bool cross_account: Indicates whether this gateway is cross account
               gateway.
        :param bool global_: Gateways with global routing (`true`) can connect to
               networks outside their associated region.
        :param str id: The unique identifier of this gateway.
        :param str location_display_name: Gateway location long name.
        :param str location_name: Gateway location.
        :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 int speed_mbps: Gateway speed in megabits per second.
        :param str type: Offering type. The list of enumerated values for this
               property may expand in the future. Code and processes using this field
               must tolerate unexpected values.
        :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 datetime bgp_status_updated_at: (optional) Date and time bgp status
               was updated.
        :param str connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str cross_connect_router: (optional) Cross connect router. Only
               included on type=dedicated gateways.
        :param str link_status: (optional) Gateway link status.  Only included on
               type=dedicated gateways. The list of enumerated values for this property
               may expand in the future. Code and processes using this field  must
               tolerate unexpected values.
        :param datetime link_status_updated_at: (optional) Date and time link
               status was updated.
        :param GatewayPortReference port: (optional) Port information for
               type=connect gateways.
        """
        # pylint: disable=super-init-not-called
        self.bgp_status = bgp_status
        self.bgp_status_updated_at = bgp_status_updated_at
        self.connection_mode = connection_mode
        self.created_at = created_at
        self.crn = crn
        self.cross_account = cross_account
        self.cross_connect_router = cross_connect_router
        self.global_ = global_
        self.id = id
        self.link_status = link_status
        self.link_status_updated_at = link_status_updated_at
        self.location_display_name = location_display_name
        self.location_name = location_name
        self.name = name
        self.operational_status = operational_status
        self.port = port
        self.speed_mbps = speed_mbps
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayCollectionGatewaysItemCrossAccountGateway':
        """Initialize a GatewayCollectionGatewaysItemCrossAccountGateway object from a json dictionary."""
        args = {}
        if (bgp_status := _dict.get('bgp_status')) is not None:
            args['bgp_status'] = bgp_status
        if (bgp_status_updated_at := _dict.get('bgp_status_updated_at')) is not None:
            args['bgp_status_updated_at'] = string_to_datetime(bgp_status_updated_at)
        if (connection_mode := _dict.get('connection_mode')) is not None:
            args['connection_mode'] = connection_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 GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (cross_account := _dict.get('cross_account')) is not None:
            args['cross_account'] = cross_account
        else:
            raise ValueError('Required property \'cross_account\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (cross_connect_router := _dict.get('cross_connect_router')) is not None:
            args['cross_connect_router'] = cross_connect_router
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        else:
            raise ValueError('Required property \'global\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (link_status := _dict.get('link_status')) is not None:
            args['link_status'] = link_status
        if (link_status_updated_at := _dict.get('link_status_updated_at')) is not None:
            args['link_status_updated_at'] = string_to_datetime(link_status_updated_at)
        if (location_display_name := _dict.get('location_display_name')) is not None:
            args['location_display_name'] = location_display_name
        else:
            raise ValueError('Required property \'location_display_name\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (location_name := _dict.get('location_name')) is not None:
            args['location_name'] = location_name
        else:
            raise ValueError('Required property \'location_name\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (operational_status := _dict.get('operational_status')) is not None:
            args['operational_status'] = operational_status
        else:
            raise ValueError('Required property \'operational_status\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (port := _dict.get('port')) is not None:
            args['port'] = GatewayPortReference.from_dict(port)
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        else:
            raise ValueError('Required property \'speed_mbps\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in GatewayCollectionGatewaysItemCrossAccountGateway JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GatewayCollectionGatewaysItemCrossAccountGateway object from 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_status') and self.bgp_status is not None:
            _dict['bgp_status'] = self.bgp_status
        if hasattr(self, 'bgp_status_updated_at') and self.bgp_status_updated_at is not None:
            _dict['bgp_status_updated_at'] = datetime_to_string(self.bgp_status_updated_at)
        if hasattr(self, 'connection_mode') and self.connection_mode is not None:
            _dict['connection_mode'] = self.connection_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, 'cross_account') and self.cross_account is not None:
            _dict['cross_account'] = self.cross_account
        if hasattr(self, 'cross_connect_router') and self.cross_connect_router is not None:
            _dict['cross_connect_router'] = self.cross_connect_router
        if hasattr(self, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'link_status') and self.link_status is not None:
            _dict['link_status'] = self.link_status
        if hasattr(self, 'link_status_updated_at') and self.link_status_updated_at is not None:
            _dict['link_status_updated_at'] = datetime_to_string(self.link_status_updated_at)
        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, '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:
            if isinstance(self.port, dict):
                _dict['port'] = self.port
            else:
                _dict['port'] = self.port.to_dict()
        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
        return _dict

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

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

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

    def __ne__(self, other: 'GatewayCollectionGatewaysItemCrossAccountGateway') -> 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 ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class LinkStatusEnum(str, Enum):
        """
        Gateway link status.  Only included on type=dedicated gateways. The list of
        enumerated values for this property may expand in the future. Code and processes
        using this field  must tolerate unexpected values.
        """

        DOWN = 'down'
        UP = 'up'


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

        AWAITING_COMPLETION_NOTICE = 'awaiting_completion_notice'
        AWAITING_LOA = 'awaiting_loa'
        CONFIGURING = 'configuring'
        CREATE_PENDING = 'create_pending'
        CREATE_REJECTED = 'create_rejected'
        COMPLETION_NOTICE_APPROVED = 'completion_notice_approved'
        COMPLETION_NOTICE_RECEIVED = 'completion_notice_received'
        COMPLETION_NOTICE_REJECTED = 'completion_notice_rejected'
        DELETE_PENDING = 'delete_pending'
        LOA_ACCEPTED = 'loa_accepted'
        LOA_CREATED = 'loa_created'
        LOA_REJECTED = 'loa_rejected'
        PROVISIONED = 'provisioned'


    class TypeEnum(str, Enum):
        """
        Offering type. The list of enumerated values for this property may expand in the
        future. Code and processes using this field  must tolerate unexpected values.
        """

        CONNECT = 'connect'
        DEDICATED = 'dedicated'



class GatewayCollectionGatewaysItemGateway(GatewayCollectionGatewaysItem):
    """
    gateway.

    :param List[AsPrepend] as_prepends: (optional) array of AS Prepend information.
    :param AuthenticationKeyReference authentication_key: (optional)
    :param GatewayBfdConfig bfd_config: (optional) BFD configuration information.
    :param int bgp_asn: Customer BGP ASN.
    :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR is deprecated
          and no longer recognized by the Direct Link APIs.
          See bgp_cer_cidr and bgp_ibm_cidr fields instead for IP related information.
          Deprecated field bgp_base_cidr will be removed from the API specification after
          15-MAR-2021.
    :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
    :param int bgp_ibm_asn: (optional) IBM BGP ASN.
    :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 datetime bgp_status_updated_at: (optional) Date and time bgp status was
          updated.
    :param str carrier_name: (optional) Carrier name.  Only set for type=dedicated
          gateways.
    :param GatewayChangeRequest change_request: (optional) Changes pending approval
          for provider managed Direct Link Connect gateways.
    :param str completion_notice_reject_reason: (optional) Reason for completion
          notice rejection.  Only included on type=dedicated gateways with a rejected
          completion notice.
    :param str connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param datetime created_at: The date and time resource was created.
    :param str crn: The CRN (Cloud Resource Name) of this gateway.
    :param bool cross_account: Indicates whether this gateway is cross account
          gateway.
    :param str cross_connect_router: (optional) Cross connect router. Only included
          on type=dedicated gateways.
    :param str customer_name: (optional) Customer name.  Only set for type=dedicated
          gateways.
    :param str default_export_route_filter: The default directional route filter
          action that applies to routes that do not match any directional route filters.
    :param str default_import_route_filter: The default directional route filter
          action that applies to routes that do not match any directional route filters.
    :param bool global_: Gateways with global routing (`true`) can connect to
          networks outside their associated region.
    :param str id: The unique identifier of this gateway.
    :param str link_status: (optional) Gateway link status.  Only included on
          type=dedicated gateways. The list of enumerated values for this property may
          expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    :param datetime link_status_updated_at: (optional) Date and time link status was
          updated.
    :param str location_display_name: Gateway location long name.
    :param str location_name: Gateway location.
    :param GatewayMacsecReference macsec: (optional) MACsec configuration
          information of a Direct Link gateway.
    :param str macsec_capability: (optional) Indicates the direct link's MACsec
          capability. It must match one of the MACsec related `capabilities` of the
          `cross_connect_router`.
          Only included on type=dedicated direct links.
          - non_macsec: The direct link does not support MACsec.
          - macsec: The direct link supports MACsec. The MACsec feature must be enabled.
          - macsec_optional: The direct link supports MACsec. The MACsec feature is not
          required and can be enabled after direct link creation.
    :param bool metered: Metered billing option.  When `true` gateway usage is
          billed per gigabyte.  When `false` there is no per gigabyte usage charge,
          instead a flat rate is charged for the 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.
          See `operational_status_reasons[]` for possible remediation of the `failed`
          `operational_status`.
    :param List[GatewayStatusReason] operational_status_reasons: Context for certain
          values of `operational_status`.
    :param str patch_panel_completion_notice: (optional) Gateway patch panel
          complete notification from implementation team.
    :param GatewayPortReference port: (optional) Port information for type=connect
          gateways.
    :param bool provider_api_managed: (optional) Indicates whether gateway changes
          must be made via a provider portal.
    :param ResourceGroupReference resource_group: (optional) Resource group
          reference.
    :param int speed_mbps: Gateway speed in megabits per second.
    :param str type: Offering type. The list of enumerated values for this property
          may expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    :param int vlan: (optional) VLAN configured for this gateway. If there is no
          vlan configured for the gateway, the vlan will be absent. This property will
          also be absent if this gateway's `crn` is in another account.
    """

    def __init__(
        self,
        bgp_asn: int,
        created_at: datetime,
        crn: str,
        cross_account: bool,
        default_export_route_filter: str,
        default_import_route_filter: str,
        global_: bool,
        id: str,
        location_display_name: str,
        location_name: str,
        metered: bool,
        name: str,
        operational_status: str,
        operational_status_reasons: List['GatewayStatusReason'],
        speed_mbps: int,
        type: str,
        *,
        as_prepends: Optional[List['AsPrepend']] = None,
        authentication_key: Optional['AuthenticationKeyReference'] = None,
        bfd_config: Optional['GatewayBfdConfig'] = None,
        bgp_base_cidr: Optional[str] = None,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_asn: Optional[int] = None,
        bgp_ibm_cidr: Optional[str] = None,
        bgp_status: Optional[str] = None,
        bgp_status_updated_at: Optional[datetime] = None,
        carrier_name: Optional[str] = None,
        change_request: Optional['GatewayChangeRequest'] = None,
        completion_notice_reject_reason: Optional[str] = None,
        connection_mode: Optional[str] = None,
        cross_connect_router: Optional[str] = None,
        customer_name: Optional[str] = None,
        link_status: Optional[str] = None,
        link_status_updated_at: Optional[datetime] = None,
        macsec: Optional['GatewayMacsecReference'] = None,
        macsec_capability: Optional[str] = None,
        patch_panel_completion_notice: Optional[str] = None,
        port: Optional['GatewayPortReference'] = None,
        provider_api_managed: Optional[bool] = None,
        resource_group: Optional['ResourceGroupReference'] = None,
        vlan: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayCollectionGatewaysItemGateway object.

        :param int bgp_asn: Customer BGP ASN.
        :param datetime created_at: The date and time resource was created.
        :param str crn: The CRN (Cloud Resource Name) of this gateway.
        :param bool cross_account: Indicates whether this gateway is cross account
               gateway.
        :param str default_export_route_filter: The default directional route
               filter action that applies to routes that do not match any directional
               route filters.
        :param str default_import_route_filter: The default directional route
               filter action that applies to routes that do not match any directional
               route filters.
        :param bool global_: Gateways with global routing (`true`) can connect to
               networks outside their associated region.
        :param str id: The unique identifier of this gateway.
        :param str location_display_name: Gateway location long name.
        :param str location_name: Gateway location.
        :param bool metered: Metered billing option.  When `true` gateway usage is
               billed per gigabyte.  When `false` there is no per gigabyte usage charge,
               instead a flat rate is charged for the 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.
               See `operational_status_reasons[]` for possible remediation of the `failed`
               `operational_status`.
        :param List[GatewayStatusReason] operational_status_reasons: Context for
               certain values of `operational_status`.
        :param int speed_mbps: Gateway speed in megabits per second.
        :param str type: Offering type. The list of enumerated values for this
               property may expand in the future. Code and processes using this field
               must tolerate unexpected values.
        :param List[AsPrepend] as_prepends: (optional) array of AS Prepend
               information.
        :param AuthenticationKeyReference authentication_key: (optional)
        :param GatewayBfdConfig bfd_config: (optional) BFD configuration
               information.
        :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR is
               deprecated and no longer recognized by the Direct Link APIs.
               See bgp_cer_cidr and bgp_ibm_cidr fields instead for IP related
               information.
               Deprecated field bgp_base_cidr will be removed from the API specification
               after 15-MAR-2021.
        :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
        :param int bgp_ibm_asn: (optional) IBM BGP ASN.
        :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 datetime bgp_status_updated_at: (optional) Date and time bgp status
               was updated.
        :param str carrier_name: (optional) Carrier name.  Only set for
               type=dedicated gateways.
        :param GatewayChangeRequest change_request: (optional) Changes pending
               approval for provider managed Direct Link Connect gateways.
        :param str completion_notice_reject_reason: (optional) Reason for
               completion notice rejection.  Only included on type=dedicated gateways with
               a rejected completion notice.
        :param str connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str cross_connect_router: (optional) Cross connect router. Only
               included on type=dedicated gateways.
        :param str customer_name: (optional) Customer name.  Only set for
               type=dedicated gateways.
        :param str link_status: (optional) Gateway link status.  Only included on
               type=dedicated gateways. The list of enumerated values for this property
               may expand in the future. Code and processes using this field  must
               tolerate unexpected values.
        :param datetime link_status_updated_at: (optional) Date and time link
               status was updated.
        :param GatewayMacsecReference macsec: (optional) MACsec configuration
               information of a Direct Link gateway.
        :param str macsec_capability: (optional) Indicates the direct link's MACsec
               capability. It must match one of the MACsec related `capabilities` of the
               `cross_connect_router`.
               Only included on type=dedicated direct links.
               - non_macsec: The direct link does not support MACsec.
               - macsec: The direct link supports MACsec. The MACsec feature must be
               enabled.
               - macsec_optional: The direct link supports MACsec. The MACsec feature is
               not required and can be enabled after direct link creation.
        :param str patch_panel_completion_notice: (optional) Gateway patch panel
               complete notification from implementation team.
        :param GatewayPortReference port: (optional) Port information for
               type=connect gateways.
        :param bool provider_api_managed: (optional) Indicates whether gateway
               changes must be made via a provider portal.
        :param ResourceGroupReference resource_group: (optional) Resource group
               reference.
        :param int vlan: (optional) VLAN configured for this gateway. If there is
               no vlan configured for the gateway, the vlan will be absent. This property
               will also be absent if this gateway's `crn` is in another account.
        """
        # pylint: disable=super-init-not-called
        self.as_prepends = as_prepends
        self.authentication_key = authentication_key
        self.bfd_config = bfd_config
        self.bgp_asn = bgp_asn
        self.bgp_base_cidr = bgp_base_cidr
        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.bgp_status_updated_at = bgp_status_updated_at
        self.carrier_name = carrier_name
        self.change_request = change_request
        self.completion_notice_reject_reason = completion_notice_reject_reason
        self.connection_mode = connection_mode
        self.created_at = created_at
        self.crn = crn
        self.cross_account = cross_account
        self.cross_connect_router = cross_connect_router
        self.customer_name = customer_name
        self.default_export_route_filter = default_export_route_filter
        self.default_import_route_filter = default_import_route_filter
        self.global_ = global_
        self.id = id
        self.link_status = link_status
        self.link_status_updated_at = link_status_updated_at
        self.location_display_name = location_display_name
        self.location_name = location_name
        self.macsec = macsec
        self.macsec_capability = macsec_capability
        self.metered = metered
        self.name = name
        self.operational_status = operational_status
        self.operational_status_reasons = operational_status_reasons
        self.patch_panel_completion_notice = patch_panel_completion_notice
        self.port = port
        self.provider_api_managed = provider_api_managed
        self.resource_group = resource_group
        self.speed_mbps = speed_mbps
        self.type = type
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayCollectionGatewaysItemGateway':
        """Initialize a GatewayCollectionGatewaysItemGateway object from a json dictionary."""
        args = {}
        if (as_prepends := _dict.get('as_prepends')) is not None:
            args['as_prepends'] = [AsPrepend.from_dict(v) for v in as_prepends]
        if (authentication_key := _dict.get('authentication_key')) is not None:
            args['authentication_key'] = authentication_key
        if (bfd_config := _dict.get('bfd_config')) is not None:
            args['bfd_config'] = GatewayBfdConfig.from_dict(bfd_config)
        if (bgp_asn := _dict.get('bgp_asn')) is not None:
            args['bgp_asn'] = bgp_asn
        else:
            raise ValueError('Required property \'bgp_asn\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (bgp_base_cidr := _dict.get('bgp_base_cidr')) is not None:
            args['bgp_base_cidr'] = bgp_base_cidr
        if (bgp_cer_cidr := _dict.get('bgp_cer_cidr')) is not None:
            args['bgp_cer_cidr'] = bgp_cer_cidr
        if (bgp_ibm_asn := _dict.get('bgp_ibm_asn')) is not None:
            args['bgp_ibm_asn'] = bgp_ibm_asn
        if (bgp_ibm_cidr := _dict.get('bgp_ibm_cidr')) is not None:
            args['bgp_ibm_cidr'] = bgp_ibm_cidr
        if (bgp_status := _dict.get('bgp_status')) is not None:
            args['bgp_status'] = bgp_status
        if (bgp_status_updated_at := _dict.get('bgp_status_updated_at')) is not None:
            args['bgp_status_updated_at'] = string_to_datetime(bgp_status_updated_at)
        if (carrier_name := _dict.get('carrier_name')) is not None:
            args['carrier_name'] = carrier_name
        if (change_request := _dict.get('change_request')) is not None:
            args['change_request'] = change_request
        if (completion_notice_reject_reason := _dict.get('completion_notice_reject_reason')) is not None:
            args['completion_notice_reject_reason'] = completion_notice_reject_reason
        if (connection_mode := _dict.get('connection_mode')) is not None:
            args['connection_mode'] = connection_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 GatewayCollectionGatewaysItemGateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (cross_account := _dict.get('cross_account')) is not None:
            args['cross_account'] = cross_account
        else:
            raise ValueError('Required property \'cross_account\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (cross_connect_router := _dict.get('cross_connect_router')) is not None:
            args['cross_connect_router'] = cross_connect_router
        if (customer_name := _dict.get('customer_name')) is not None:
            args['customer_name'] = customer_name
        if (default_export_route_filter := _dict.get('default_export_route_filter')) is not None:
            args['default_export_route_filter'] = default_export_route_filter
        else:
            raise ValueError('Required property \'default_export_route_filter\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (default_import_route_filter := _dict.get('default_import_route_filter')) is not None:
            args['default_import_route_filter'] = default_import_route_filter
        else:
            raise ValueError('Required property \'default_import_route_filter\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        else:
            raise ValueError('Required property \'global\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (link_status := _dict.get('link_status')) is not None:
            args['link_status'] = link_status
        if (link_status_updated_at := _dict.get('link_status_updated_at')) is not None:
            args['link_status_updated_at'] = string_to_datetime(link_status_updated_at)
        if (location_display_name := _dict.get('location_display_name')) is not None:
            args['location_display_name'] = location_display_name
        else:
            raise ValueError('Required property \'location_display_name\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (location_name := _dict.get('location_name')) is not None:
            args['location_name'] = location_name
        else:
            raise ValueError('Required property \'location_name\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (macsec := _dict.get('macsec')) is not None:
            args['macsec'] = GatewayMacsecReference.from_dict(macsec)
        if (macsec_capability := _dict.get('macsec_capability')) is not None:
            args['macsec_capability'] = macsec_capability
        if (metered := _dict.get('metered')) is not None:
            args['metered'] = metered
        else:
            raise ValueError('Required property \'metered\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (operational_status := _dict.get('operational_status')) is not None:
            args['operational_status'] = operational_status
        else:
            raise ValueError('Required property \'operational_status\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (operational_status_reasons := _dict.get('operational_status_reasons')) is not None:
            args['operational_status_reasons'] = [GatewayStatusReason.from_dict(v) for v in operational_status_reasons]
        else:
            raise ValueError('Required property \'operational_status_reasons\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (patch_panel_completion_notice := _dict.get('patch_panel_completion_notice')) is not None:
            args['patch_panel_completion_notice'] = patch_panel_completion_notice
        if (port := _dict.get('port')) is not None:
            args['port'] = GatewayPortReference.from_dict(port)
        if (provider_api_managed := _dict.get('provider_api_managed')) is not None:
            args['provider_api_managed'] = provider_api_managed
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        else:
            raise ValueError('Required property \'speed_mbps\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in GatewayCollectionGatewaysItemGateway JSON')
        if (vlan := _dict.get('vlan')) is not None:
            args['vlan'] = vlan
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'as_prepends') and self.as_prepends is not None:
            as_prepends_list = []
            for v in self.as_prepends:
                if isinstance(v, dict):
                    as_prepends_list.append(v)
                else:
                    as_prepends_list.append(v.to_dict())
            _dict['as_prepends'] = as_prepends_list
        if hasattr(self, 'authentication_key') and self.authentication_key is not None:
            if isinstance(self.authentication_key, dict):
                _dict['authentication_key'] = self.authentication_key
            else:
                _dict['authentication_key'] = self.authentication_key.to_dict()
        if hasattr(self, 'bfd_config') and self.bfd_config is not None:
            if isinstance(self.bfd_config, dict):
                _dict['bfd_config'] = self.bfd_config
            else:
                _dict['bfd_config'] = self.bfd_config.to_dict()
        if hasattr(self, 'bgp_asn') and self.bgp_asn is not None:
            _dict['bgp_asn'] = self.bgp_asn
        if hasattr(self, 'bgp_base_cidr') and self.bgp_base_cidr is not None:
            _dict['bgp_base_cidr'] = self.bgp_base_cidr
        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, 'bgp_status_updated_at') and self.bgp_status_updated_at is not None:
            _dict['bgp_status_updated_at'] = datetime_to_string(self.bgp_status_updated_at)
        if hasattr(self, 'carrier_name') and self.carrier_name is not None:
            _dict['carrier_name'] = self.carrier_name
        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, 'completion_notice_reject_reason') and self.completion_notice_reject_reason is not None:
            _dict['completion_notice_reject_reason'] = self.completion_notice_reject_reason
        if hasattr(self, 'connection_mode') and self.connection_mode is not None:
            _dict['connection_mode'] = self.connection_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, 'cross_account') and self.cross_account is not None:
            _dict['cross_account'] = self.cross_account
        if hasattr(self, 'cross_connect_router') and self.cross_connect_router is not None:
            _dict['cross_connect_router'] = self.cross_connect_router
        if hasattr(self, 'customer_name') and self.customer_name is not None:
            _dict['customer_name'] = self.customer_name
        if hasattr(self, 'default_export_route_filter') and self.default_export_route_filter is not None:
            _dict['default_export_route_filter'] = self.default_export_route_filter
        if hasattr(self, 'default_import_route_filter') and self.default_import_route_filter is not None:
            _dict['default_import_route_filter'] = self.default_import_route_filter
        if hasattr(self, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'link_status') and self.link_status is not None:
            _dict['link_status'] = self.link_status
        if hasattr(self, 'link_status_updated_at') and self.link_status_updated_at is not None:
            _dict['link_status_updated_at'] = datetime_to_string(self.link_status_updated_at)
        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, 'macsec') and self.macsec is not None:
            if isinstance(self.macsec, dict):
                _dict['macsec'] = self.macsec
            else:
                _dict['macsec'] = self.macsec.to_dict()
        if hasattr(self, 'macsec_capability') and self.macsec_capability is not None:
            _dict['macsec_capability'] = self.macsec_capability
        if hasattr(self, 'metered') and self.metered is not None:
            _dict['metered'] = self.metered
        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, 'operational_status_reasons') and self.operational_status_reasons is not None:
            operational_status_reasons_list = []
            for v in self.operational_status_reasons:
                if isinstance(v, dict):
                    operational_status_reasons_list.append(v)
                else:
                    operational_status_reasons_list.append(v.to_dict())
            _dict['operational_status_reasons'] = operational_status_reasons_list
        if hasattr(self, 'patch_panel_completion_notice') and self.patch_panel_completion_notice is not None:
            _dict['patch_panel_completion_notice'] = self.patch_panel_completion_notice
        if hasattr(self, 'port') and self.port is not None:
            if isinstance(self.port, dict):
                _dict['port'] = self.port
            else:
                _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, '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, '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 GatewayCollectionGatewaysItemGateway object."""
        return json.dumps(self.to_dict(), indent=2)

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

    def __ne__(self, other: 'GatewayCollectionGatewaysItemGateway') -> 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 ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class DefaultExportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class DefaultImportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class LinkStatusEnum(str, Enum):
        """
        Gateway link status.  Only included on type=dedicated gateways. The list of
        enumerated values for this property may expand in the future. Code and processes
        using this field  must tolerate unexpected values.
        """

        DOWN = 'down'
        UP = 'up'


    class MacsecCapabilityEnum(str, Enum):
        """
        Indicates the direct link's MACsec capability. It must match one of the MACsec
        related `capabilities` of the `cross_connect_router`.
        Only included on type=dedicated direct links.
        - non_macsec: The direct link does not support MACsec.
        - macsec: The direct link supports MACsec. The MACsec feature must be enabled.
        - macsec_optional: The direct link supports MACsec. The MACsec feature is not
        required and can be enabled after direct link creation.
        """

        NON_MACSEC = 'non_macsec'
        MACSEC = 'macsec'
        MACSEC_OPTIONAL = 'macsec_optional'


    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.
        See `operational_status_reasons[]` for possible remediation of the `failed`
        `operational_status`.
        """

        AWAITING_COMPLETION_NOTICE = 'awaiting_completion_notice'
        AWAITING_LOA = 'awaiting_loa'
        CONFIGURING = 'configuring'
        CREATE_PENDING = 'create_pending'
        CREATE_REJECTED = 'create_rejected'
        COMPLETION_NOTICE_APPROVED = 'completion_notice_approved'
        COMPLETION_NOTICE_RECEIVED = 'completion_notice_received'
        COMPLETION_NOTICE_REJECTED = 'completion_notice_rejected'
        DELETE_PENDING = 'delete_pending'
        LOA_ACCEPTED = 'loa_accepted'
        LOA_CREATED = 'loa_created'
        LOA_REJECTED = 'loa_rejected'
        PROVISIONED = 'provisioned'
        FAILED = 'failed'


    class TypeEnum(str, Enum):
        """
        Offering type. The list of enumerated values for this property may expand in the
        future. Code and processes using this field  must tolerate unexpected values.
        """

        CONNECT = 'connect'
        DEDICATED = 'dedicated'



class GatewayStatusGatewayBFDStatus(GatewayStatus):
    """
    Gateway bfd status.

    :param str type: Status type.
    :param datetime updated_at: Date and time status was collected.
    :param str value: Status.
    """

    def __init__(
        self,
        type: str,
        updated_at: datetime,
        value: str,
    ) -> None:
        """
        Initialize a GatewayStatusGatewayBFDStatus object.

        :param str type: Status type.
        :param datetime updated_at: Date and time status was collected.
        :param str value: Status.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.updated_at = updated_at
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayStatusGatewayBFDStatus':
        """Initialize a GatewayStatusGatewayBFDStatus 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 GatewayStatusGatewayBFDStatus 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 GatewayStatusGatewayBFDStatus JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in GatewayStatusGatewayBFDStatus JSON')
        return cls(**args)

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

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

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

    class TypeEnum(str, Enum):
        """
        Status type.
        """

        BFD = 'bfd'


    class ValueEnum(str, Enum):
        """
        Status.
        """

        NOT_AVAILABLE = 'not_available'
        INIT = 'init'
        UP = 'up'
        DOWN = 'down'



class GatewayStatusGatewayBGPStatus(GatewayStatus):
    """
    Gateway bgp status.

    :param str type: Status type.
    :param datetime updated_at: Date and time status was collected.
    :param str value: Status.
    """

    def __init__(
        self,
        type: str,
        updated_at: datetime,
        value: str,
    ) -> None:
        """
        Initialize a GatewayStatusGatewayBGPStatus object.

        :param str type: Status type.
        :param datetime updated_at: Date and time status was collected.
        :param str value: Status.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.updated_at = updated_at
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayStatusGatewayBGPStatus':
        """Initialize a GatewayStatusGatewayBGPStatus 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 GatewayStatusGatewayBGPStatus 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 GatewayStatusGatewayBGPStatus JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in GatewayStatusGatewayBGPStatus JSON')
        return cls(**args)

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

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

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

    class TypeEnum(str, Enum):
        """
        Status type.
        """

        BGP = 'bgp'


    class ValueEnum(str, Enum):
        """
        Status.
        """

        ACTIVE = 'active'
        CONNECT = 'connect'
        ESTABLISHED = 'established'
        IDLE = 'idle'



class GatewayStatusGatewayLinkStatus(GatewayStatus):
    """
    Gateway link status. Only available for dedicated gateways.

    :param str type: Status type.
    :param datetime updated_at: Date and time status was collected.
    :param str value: Status.
    """

    def __init__(
        self,
        type: str,
        updated_at: datetime,
        value: str,
    ) -> None:
        """
        Initialize a GatewayStatusGatewayLinkStatus object.

        :param str type: Status type.
        :param datetime updated_at: Date and time status was collected.
        :param str value: Status.
        """
        # pylint: disable=super-init-not-called
        self.type = type
        self.updated_at = updated_at
        self.value = value

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayStatusGatewayLinkStatus':
        """Initialize a GatewayStatusGatewayLinkStatus 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 GatewayStatusGatewayLinkStatus 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 GatewayStatusGatewayLinkStatus JSON')
        if (value := _dict.get('value')) is not None:
            args['value'] = value
        else:
            raise ValueError('Required property \'value\' not present in GatewayStatusGatewayLinkStatus JSON')
        return cls(**args)

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

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

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

    class TypeEnum(str, Enum):
        """
        Status type.
        """

        LINK = 'link'


    class ValueEnum(str, Enum):
        """
        Status.
        """

        UP = 'up'
        DOWN = 'down'



class GatewayTemplateGatewayTypeConnectTemplate(GatewayTemplate):
    """
    Gateway fields specific to type=connect gateway create.

    :param List[AsPrependTemplate] as_prepends: (optional) array of AS Prepend
          configuration information.
    :param AuthenticationKeyIdentity authentication_key: (optional)
    :param GatewayBfdConfigTemplate bfd_config: (optional)
    :param int bgp_asn: BGP ASN.
    :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR.
          Field is deprecated.  See bgp_ibm_cidr and bgp_cer_cidr for details on how to
          create a gateway using either automatic or explicit IP assignment.  Any
          bgp_base_cidr value set will be ignored.
          Deprecated field bgp_base_cidr will be removed from the API specification after
          15-MAR-2021.
    :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 explicit 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 explicit 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 connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param str default_export_route_filter: (optional) The default directional route
          filter action that applies to routes that do not match any directional route
          filters.
    :param str default_import_route_filter: (optional) The default directional route
          filter action that applies to routes that do not match any directional route
          filters.
    :param List[GatewayTemplateRouteFilter] export_route_filters: (optional) Array
          of directional route filters for a Direct Link gateway. When creating a gateway
          or replacing existing route filters, the order of the items in the array will
          set the ordering of the list of route filters.
    :param bool global_: Gateways with global routing (`true`) can connect to
          networks outside their associated region.
    :param List[GatewayTemplateRouteFilter] import_route_filters: (optional) Array
          of directional route filters for a Direct Link gateway. When creating a gateway
          or replacing existing route filters, the order of the items in the array will
          set the ordering of the list of route filters.
    :param bool metered: Metered billing option.  When `true` gateway usage is
          billed per gigabyte.  When `false` there is no per gigabyte usage charge,
          instead a flat rate is charged for the gateway.
    :param str name: The unique user-defined name for this gateway.
    :param str patch_panel_completion_notice: (optional) Gateway patch panel
          complete notification from implementation team.
    :param ResourceGroupIdentity resource_group: (optional)
    :param int speed_mbps: Gateway speed in megabits per second.
    :param str type: Offering type.
    :param GatewayPortIdentity port: Select Port Label for new type=connect gateway.
    """

    def __init__(
        self,
        bgp_asn: int,
        global_: bool,
        metered: bool,
        name: str,
        speed_mbps: int,
        type: str,
        port: 'GatewayPortIdentity',
        *,
        as_prepends: Optional[List['AsPrependTemplate']] = None,
        authentication_key: Optional['AuthenticationKeyIdentity'] = None,
        bfd_config: Optional['GatewayBfdConfigTemplate'] = None,
        bgp_base_cidr: Optional[str] = None,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_cidr: Optional[str] = None,
        connection_mode: Optional[str] = None,
        default_export_route_filter: Optional[str] = None,
        default_import_route_filter: Optional[str] = None,
        export_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        import_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        patch_panel_completion_notice: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
    ) -> None:
        """
        Initialize a GatewayTemplateGatewayTypeConnectTemplate object.

        :param int bgp_asn: BGP ASN.
        :param bool global_: Gateways with global routing (`true`) can connect to
               networks outside their associated region.
        :param bool metered: Metered billing option.  When `true` gateway usage is
               billed per gigabyte.  When `false` there is no per gigabyte usage charge,
               instead a flat rate is charged for the gateway.
        :param str name: The unique user-defined name for this gateway.
        :param int speed_mbps: Gateway speed in megabits per second.
        :param str type: Offering type.
        :param GatewayPortIdentity port: Select Port Label for new type=connect
               gateway.
        :param List[AsPrependTemplate] as_prepends: (optional) array of AS Prepend
               configuration information.
        :param AuthenticationKeyIdentity authentication_key: (optional)
        :param GatewayBfdConfigTemplate bfd_config: (optional)
        :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR.
               Field is deprecated.  See bgp_ibm_cidr and bgp_cer_cidr for details on how
               to create a gateway using either automatic or explicit IP assignment.  Any
               bgp_base_cidr value set will be ignored.
               Deprecated field bgp_base_cidr will be removed from the API specification
               after 15-MAR-2021.
        :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 explicit 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 explicit 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 connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str default_export_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param str default_import_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param List[GatewayTemplateRouteFilter] export_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param List[GatewayTemplateRouteFilter] import_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param str patch_panel_completion_notice: (optional) Gateway patch panel
               complete notification from implementation team.
        :param ResourceGroupIdentity resource_group: (optional)
        """
        # pylint: disable=super-init-not-called
        self.as_prepends = as_prepends
        self.authentication_key = authentication_key
        self.bfd_config = bfd_config
        self.bgp_asn = bgp_asn
        self.bgp_base_cidr = bgp_base_cidr
        self.bgp_cer_cidr = bgp_cer_cidr
        self.bgp_ibm_cidr = bgp_ibm_cidr
        self.connection_mode = connection_mode
        self.default_export_route_filter = default_export_route_filter
        self.default_import_route_filter = default_import_route_filter
        self.export_route_filters = export_route_filters
        self.global_ = global_
        self.import_route_filters = import_route_filters
        self.metered = metered
        self.name = name
        self.patch_panel_completion_notice = patch_panel_completion_notice
        self.resource_group = resource_group
        self.speed_mbps = speed_mbps
        self.type = type
        self.port = port

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayTemplateGatewayTypeConnectTemplate':
        """Initialize a GatewayTemplateGatewayTypeConnectTemplate object from a json dictionary."""
        args = {}
        if (as_prepends := _dict.get('as_prepends')) is not None:
            args['as_prepends'] = [AsPrependTemplate.from_dict(v) for v in as_prepends]
        if (authentication_key := _dict.get('authentication_key')) is not None:
            args['authentication_key'] = authentication_key
        if (bfd_config := _dict.get('bfd_config')) is not None:
            args['bfd_config'] = GatewayBfdConfigTemplate.from_dict(bfd_config)
        if (bgp_asn := _dict.get('bgp_asn')) is not None:
            args['bgp_asn'] = bgp_asn
        else:
            raise ValueError('Required property \'bgp_asn\' not present in GatewayTemplateGatewayTypeConnectTemplate JSON')
        if (bgp_base_cidr := _dict.get('bgp_base_cidr')) is not None:
            args['bgp_base_cidr'] = bgp_base_cidr
        if (bgp_cer_cidr := _dict.get('bgp_cer_cidr')) is not None:
            args['bgp_cer_cidr'] = bgp_cer_cidr
        if (bgp_ibm_cidr := _dict.get('bgp_ibm_cidr')) is not None:
            args['bgp_ibm_cidr'] = bgp_ibm_cidr
        if (connection_mode := _dict.get('connection_mode')) is not None:
            args['connection_mode'] = connection_mode
        if (default_export_route_filter := _dict.get('default_export_route_filter')) is not None:
            args['default_export_route_filter'] = default_export_route_filter
        if (default_import_route_filter := _dict.get('default_import_route_filter')) is not None:
            args['default_import_route_filter'] = default_import_route_filter
        if (export_route_filters := _dict.get('export_route_filters')) is not None:
            args['export_route_filters'] = [GatewayTemplateRouteFilter.from_dict(v) for v in export_route_filters]
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        else:
            raise ValueError('Required property \'global\' not present in GatewayTemplateGatewayTypeConnectTemplate JSON')
        if (import_route_filters := _dict.get('import_route_filters')) is not None:
            args['import_route_filters'] = [GatewayTemplateRouteFilter.from_dict(v) for v in import_route_filters]
        if (metered := _dict.get('metered')) is not None:
            args['metered'] = metered
        else:
            raise ValueError('Required property \'metered\' not present in GatewayTemplateGatewayTypeConnectTemplate JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in GatewayTemplateGatewayTypeConnectTemplate JSON')
        if (patch_panel_completion_notice := _dict.get('patch_panel_completion_notice')) is not None:
            args['patch_panel_completion_notice'] = patch_panel_completion_notice
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupIdentity.from_dict(resource_group)
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        else:
            raise ValueError('Required property \'speed_mbps\' not present in GatewayTemplateGatewayTypeConnectTemplate JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in GatewayTemplateGatewayTypeConnectTemplate JSON')
        if (port := _dict.get('port')) is not None:
            args['port'] = GatewayPortIdentity.from_dict(port)
        else:
            raise ValueError('Required property \'port\' not present in GatewayTemplateGatewayTypeConnectTemplate JSON')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'as_prepends') and self.as_prepends is not None:
            as_prepends_list = []
            for v in self.as_prepends:
                if isinstance(v, dict):
                    as_prepends_list.append(v)
                else:
                    as_prepends_list.append(v.to_dict())
            _dict['as_prepends'] = as_prepends_list
        if hasattr(self, 'authentication_key') and self.authentication_key is not None:
            if isinstance(self.authentication_key, dict):
                _dict['authentication_key'] = self.authentication_key
            else:
                _dict['authentication_key'] = self.authentication_key.to_dict()
        if hasattr(self, 'bfd_config') and self.bfd_config is not None:
            if isinstance(self.bfd_config, dict):
                _dict['bfd_config'] = self.bfd_config
            else:
                _dict['bfd_config'] = self.bfd_config.to_dict()
        if hasattr(self, 'bgp_asn') and self.bgp_asn is not None:
            _dict['bgp_asn'] = self.bgp_asn
        if hasattr(self, 'bgp_base_cidr') and self.bgp_base_cidr is not None:
            _dict['bgp_base_cidr'] = self.bgp_base_cidr
        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
        if hasattr(self, 'connection_mode') and self.connection_mode is not None:
            _dict['connection_mode'] = self.connection_mode
        if hasattr(self, 'default_export_route_filter') and self.default_export_route_filter is not None:
            _dict['default_export_route_filter'] = self.default_export_route_filter
        if hasattr(self, 'default_import_route_filter') and self.default_import_route_filter is not None:
            _dict['default_import_route_filter'] = self.default_import_route_filter
        if hasattr(self, 'export_route_filters') and self.export_route_filters is not None:
            export_route_filters_list = []
            for v in self.export_route_filters:
                if isinstance(v, dict):
                    export_route_filters_list.append(v)
                else:
                    export_route_filters_list.append(v.to_dict())
            _dict['export_route_filters'] = export_route_filters_list
        if hasattr(self, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'import_route_filters') and self.import_route_filters is not None:
            import_route_filters_list = []
            for v in self.import_route_filters:
                if isinstance(v, dict):
                    import_route_filters_list.append(v)
                else:
                    import_route_filters_list.append(v.to_dict())
            _dict['import_route_filters'] = import_route_filters_list
        if hasattr(self, 'metered') and self.metered is not None:
            _dict['metered'] = self.metered
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'patch_panel_completion_notice') and self.patch_panel_completion_notice is not None:
            _dict['patch_panel_completion_notice'] = self.patch_panel_completion_notice
        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, '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, 'port') and self.port is not None:
            if isinstance(self.port, dict):
                _dict['port'] = self.port
            else:
                _dict['port'] = self.port.to_dict()
        return _dict

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

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

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

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

    class ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class DefaultExportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class DefaultImportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class TypeEnum(str, Enum):
        """
        Offering type.
        """

        CONNECT = 'connect'
        DEDICATED = 'dedicated'



class GatewayTemplateGatewayTypeDedicatedTemplate(GatewayTemplate):
    """
    Gateway fields specific to type=dedicated gateway create.

    :param List[AsPrependTemplate] as_prepends: (optional) array of AS Prepend
          configuration information.
    :param AuthenticationKeyIdentity authentication_key: (optional)
    :param GatewayBfdConfigTemplate bfd_config: (optional)
    :param int bgp_asn: BGP ASN.
    :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR.
          Field is deprecated.  See bgp_ibm_cidr and bgp_cer_cidr for details on how to
          create a gateway using either automatic or explicit IP assignment.  Any
          bgp_base_cidr value set will be ignored.
          Deprecated field bgp_base_cidr will be removed from the API specification after
          15-MAR-2021.
    :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 explicit 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 explicit 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 connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param str default_export_route_filter: (optional) The default directional route
          filter action that applies to routes that do not match any directional route
          filters.
    :param str default_import_route_filter: (optional) The default directional route
          filter action that applies to routes that do not match any directional route
          filters.
    :param List[GatewayTemplateRouteFilter] export_route_filters: (optional) Array
          of directional route filters for a Direct Link gateway. When creating a gateway
          or replacing existing route filters, the order of the items in the array will
          set the ordering of the list of route filters.
    :param bool global_: Gateways with global routing (`true`) can connect to
          networks outside their associated region.
    :param List[GatewayTemplateRouteFilter] import_route_filters: (optional) Array
          of directional route filters for a Direct Link gateway. When creating a gateway
          or replacing existing route filters, the order of the items in the array will
          set the ordering of the list of route filters.
    :param bool metered: Metered billing option.  When `true` gateway usage is
          billed per gigabyte.  When `false` there is no per gigabyte usage charge,
          instead a flat rate is charged for the gateway.
    :param str name: The unique user-defined name for this gateway.
    :param str patch_panel_completion_notice: (optional) Gateway patch panel
          complete notification from implementation team.
    :param ResourceGroupIdentity resource_group: (optional)
    :param int speed_mbps: Gateway speed in megabits per second.
    :param str type: Offering type.
    :param str carrier_name: Carrier name.
    :param str cross_connect_router: Cross connect router.
    :param str customer_name: Customer name.
    :param str location_name: Gateway location.
    :param GatewayMacsecPrototype macsec: (optional) MACsec configuration
          information of a Direct Link gateway.
    :param str macsec_capability: (optional) Indicates the direct link's MACsec
          capability. It must match one of the MACsec related `capabilities` of the
          `cross_connect_router`.
          - non_macsec: The direct link does not support MACsec.
          - macsec: The direct link supports MACsec. The MACsec feature must be enabled.
          - macsec_optional: The direct link supports MACsec. The MACsec feature is not
          required and can be enabled after direct link creation.
          If not explicitly provided, the field will be assigned with the following
          priorities based on `cross_connect_router` capabilities and available ports:
            - `macsec` was not provided in the request
              - `non_macsec`
              - `macsec_optional`
            - `macsec` was provided in the request
              - `macsec_optional`
              - `macsec`.
    :param int vlan: (optional) The VLAN to configure for this gateway.
    """

    def __init__(
        self,
        bgp_asn: int,
        global_: bool,
        metered: bool,
        name: str,
        speed_mbps: int,
        type: str,
        carrier_name: str,
        cross_connect_router: str,
        customer_name: str,
        location_name: str,
        *,
        as_prepends: Optional[List['AsPrependTemplate']] = None,
        authentication_key: Optional['AuthenticationKeyIdentity'] = None,
        bfd_config: Optional['GatewayBfdConfigTemplate'] = None,
        bgp_base_cidr: Optional[str] = None,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_cidr: Optional[str] = None,
        connection_mode: Optional[str] = None,
        default_export_route_filter: Optional[str] = None,
        default_import_route_filter: Optional[str] = None,
        export_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        import_route_filters: Optional[List['GatewayTemplateRouteFilter']] = None,
        patch_panel_completion_notice: Optional[str] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        macsec: Optional['GatewayMacsecPrototype'] = None,
        macsec_capability: Optional[str] = None,
        vlan: Optional[int] = None,
    ) -> None:
        """
        Initialize a GatewayTemplateGatewayTypeDedicatedTemplate object.

        :param int bgp_asn: BGP ASN.
        :param bool global_: Gateways with global routing (`true`) can connect to
               networks outside their associated region.
        :param bool metered: Metered billing option.  When `true` gateway usage is
               billed per gigabyte.  When `false` there is no per gigabyte usage charge,
               instead a flat rate is charged for the gateway.
        :param str name: The unique user-defined name for this gateway.
        :param int speed_mbps: Gateway speed in megabits per second.
        :param str type: Offering type.
        :param str carrier_name: Carrier name.
        :param str cross_connect_router: Cross connect router.
        :param str customer_name: Customer name.
        :param str location_name: Gateway location.
        :param List[AsPrependTemplate] as_prepends: (optional) array of AS Prepend
               configuration information.
        :param AuthenticationKeyIdentity authentication_key: (optional)
        :param GatewayBfdConfigTemplate bfd_config: (optional)
        :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR.
               Field is deprecated.  See bgp_ibm_cidr and bgp_cer_cidr for details on how
               to create a gateway using either automatic or explicit IP assignment.  Any
               bgp_base_cidr value set will be ignored.
               Deprecated field bgp_base_cidr will be removed from the API specification
               after 15-MAR-2021.
        :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 explicit 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 explicit 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 connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str default_export_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param str default_import_route_filter: (optional) The default directional
               route filter action that applies to routes that do not match any
               directional route filters.
        :param List[GatewayTemplateRouteFilter] export_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param List[GatewayTemplateRouteFilter] import_route_filters: (optional)
               Array of directional route filters for a Direct Link gateway. When creating
               a gateway or replacing existing route filters, the order of the items in
               the array will set the ordering of the list of route filters.
        :param str patch_panel_completion_notice: (optional) Gateway patch panel
               complete notification from implementation team.
        :param ResourceGroupIdentity resource_group: (optional)
        :param GatewayMacsecPrototype macsec: (optional) MACsec configuration
               information of a Direct Link gateway.
        :param str macsec_capability: (optional) Indicates the direct link's MACsec
               capability. It must match one of the MACsec related `capabilities` of the
               `cross_connect_router`.
               - non_macsec: The direct link does not support MACsec.
               - macsec: The direct link supports MACsec. The MACsec feature must be
               enabled.
               - macsec_optional: The direct link supports MACsec. The MACsec feature is
               not required and can be enabled after direct link creation.
               If not explicitly provided, the field will be assigned with the following
               priorities based on `cross_connect_router` capabilities and available
               ports:
                 - `macsec` was not provided in the request
                   - `non_macsec`
                   - `macsec_optional`
                 - `macsec` was provided in the request
                   - `macsec_optional`
                   - `macsec`.
        :param int vlan: (optional) The VLAN to configure for this gateway.
        """
        # pylint: disable=super-init-not-called
        self.as_prepends = as_prepends
        self.authentication_key = authentication_key
        self.bfd_config = bfd_config
        self.bgp_asn = bgp_asn
        self.bgp_base_cidr = bgp_base_cidr
        self.bgp_cer_cidr = bgp_cer_cidr
        self.bgp_ibm_cidr = bgp_ibm_cidr
        self.connection_mode = connection_mode
        self.default_export_route_filter = default_export_route_filter
        self.default_import_route_filter = default_import_route_filter
        self.export_route_filters = export_route_filters
        self.global_ = global_
        self.import_route_filters = import_route_filters
        self.metered = metered
        self.name = name
        self.patch_panel_completion_notice = patch_panel_completion_notice
        self.resource_group = resource_group
        self.speed_mbps = speed_mbps
        self.type = type
        self.carrier_name = carrier_name
        self.cross_connect_router = cross_connect_router
        self.customer_name = customer_name
        self.location_name = location_name
        self.macsec = macsec
        self.macsec_capability = macsec_capability
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GatewayTemplateGatewayTypeDedicatedTemplate':
        """Initialize a GatewayTemplateGatewayTypeDedicatedTemplate object from a json dictionary."""
        args = {}
        if (as_prepends := _dict.get('as_prepends')) is not None:
            args['as_prepends'] = [AsPrependTemplate.from_dict(v) for v in as_prepends]
        if (authentication_key := _dict.get('authentication_key')) is not None:
            args['authentication_key'] = authentication_key
        if (bfd_config := _dict.get('bfd_config')) is not None:
            args['bfd_config'] = GatewayBfdConfigTemplate.from_dict(bfd_config)
        if (bgp_asn := _dict.get('bgp_asn')) is not None:
            args['bgp_asn'] = bgp_asn
        else:
            raise ValueError('Required property \'bgp_asn\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (bgp_base_cidr := _dict.get('bgp_base_cidr')) is not None:
            args['bgp_base_cidr'] = bgp_base_cidr
        if (bgp_cer_cidr := _dict.get('bgp_cer_cidr')) is not None:
            args['bgp_cer_cidr'] = bgp_cer_cidr
        if (bgp_ibm_cidr := _dict.get('bgp_ibm_cidr')) is not None:
            args['bgp_ibm_cidr'] = bgp_ibm_cidr
        if (connection_mode := _dict.get('connection_mode')) is not None:
            args['connection_mode'] = connection_mode
        if (default_export_route_filter := _dict.get('default_export_route_filter')) is not None:
            args['default_export_route_filter'] = default_export_route_filter
        if (default_import_route_filter := _dict.get('default_import_route_filter')) is not None:
            args['default_import_route_filter'] = default_import_route_filter
        if (export_route_filters := _dict.get('export_route_filters')) is not None:
            args['export_route_filters'] = [GatewayTemplateRouteFilter.from_dict(v) for v in export_route_filters]
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        else:
            raise ValueError('Required property \'global\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (import_route_filters := _dict.get('import_route_filters')) is not None:
            args['import_route_filters'] = [GatewayTemplateRouteFilter.from_dict(v) for v in import_route_filters]
        if (metered := _dict.get('metered')) is not None:
            args['metered'] = metered
        else:
            raise ValueError('Required property \'metered\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (patch_panel_completion_notice := _dict.get('patch_panel_completion_notice')) is not None:
            args['patch_panel_completion_notice'] = patch_panel_completion_notice
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupIdentity.from_dict(resource_group)
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        else:
            raise ValueError('Required property \'speed_mbps\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (carrier_name := _dict.get('carrier_name')) is not None:
            args['carrier_name'] = carrier_name
        else:
            raise ValueError('Required property \'carrier_name\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (cross_connect_router := _dict.get('cross_connect_router')) is not None:
            args['cross_connect_router'] = cross_connect_router
        else:
            raise ValueError('Required property \'cross_connect_router\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (customer_name := _dict.get('customer_name')) is not None:
            args['customer_name'] = customer_name
        else:
            raise ValueError('Required property \'customer_name\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (location_name := _dict.get('location_name')) is not None:
            args['location_name'] = location_name
        else:
            raise ValueError('Required property \'location_name\' not present in GatewayTemplateGatewayTypeDedicatedTemplate JSON')
        if (macsec := _dict.get('macsec')) is not None:
            args['macsec'] = GatewayMacsecPrototype.from_dict(macsec)
        if (macsec_capability := _dict.get('macsec_capability')) is not None:
            args['macsec_capability'] = macsec_capability
        if (vlan := _dict.get('vlan')) is not None:
            args['vlan'] = vlan
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'as_prepends') and self.as_prepends is not None:
            as_prepends_list = []
            for v in self.as_prepends:
                if isinstance(v, dict):
                    as_prepends_list.append(v)
                else:
                    as_prepends_list.append(v.to_dict())
            _dict['as_prepends'] = as_prepends_list
        if hasattr(self, 'authentication_key') and self.authentication_key is not None:
            if isinstance(self.authentication_key, dict):
                _dict['authentication_key'] = self.authentication_key
            else:
                _dict['authentication_key'] = self.authentication_key.to_dict()
        if hasattr(self, 'bfd_config') and self.bfd_config is not None:
            if isinstance(self.bfd_config, dict):
                _dict['bfd_config'] = self.bfd_config
            else:
                _dict['bfd_config'] = self.bfd_config.to_dict()
        if hasattr(self, 'bgp_asn') and self.bgp_asn is not None:
            _dict['bgp_asn'] = self.bgp_asn
        if hasattr(self, 'bgp_base_cidr') and self.bgp_base_cidr is not None:
            _dict['bgp_base_cidr'] = self.bgp_base_cidr
        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
        if hasattr(self, 'connection_mode') and self.connection_mode is not None:
            _dict['connection_mode'] = self.connection_mode
        if hasattr(self, 'default_export_route_filter') and self.default_export_route_filter is not None:
            _dict['default_export_route_filter'] = self.default_export_route_filter
        if hasattr(self, 'default_import_route_filter') and self.default_import_route_filter is not None:
            _dict['default_import_route_filter'] = self.default_import_route_filter
        if hasattr(self, 'export_route_filters') and self.export_route_filters is not None:
            export_route_filters_list = []
            for v in self.export_route_filters:
                if isinstance(v, dict):
                    export_route_filters_list.append(v)
                else:
                    export_route_filters_list.append(v.to_dict())
            _dict['export_route_filters'] = export_route_filters_list
        if hasattr(self, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'import_route_filters') and self.import_route_filters is not None:
            import_route_filters_list = []
            for v in self.import_route_filters:
                if isinstance(v, dict):
                    import_route_filters_list.append(v)
                else:
                    import_route_filters_list.append(v.to_dict())
            _dict['import_route_filters'] = import_route_filters_list
        if hasattr(self, 'metered') and self.metered is not None:
            _dict['metered'] = self.metered
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'patch_panel_completion_notice') and self.patch_panel_completion_notice is not None:
            _dict['patch_panel_completion_notice'] = self.patch_panel_completion_notice
        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, '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, 'carrier_name') and self.carrier_name is not None:
            _dict['carrier_name'] = self.carrier_name
        if hasattr(self, 'cross_connect_router') and self.cross_connect_router is not None:
            _dict['cross_connect_router'] = self.cross_connect_router
        if hasattr(self, 'customer_name') and self.customer_name is not None:
            _dict['customer_name'] = self.customer_name
        if hasattr(self, 'location_name') and self.location_name is not None:
            _dict['location_name'] = self.location_name
        if hasattr(self, 'macsec') and self.macsec is not None:
            if isinstance(self.macsec, dict):
                _dict['macsec'] = self.macsec
            else:
                _dict['macsec'] = self.macsec.to_dict()
        if hasattr(self, 'macsec_capability') and self.macsec_capability is not None:
            _dict['macsec_capability'] = self.macsec_capability
        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 GatewayTemplateGatewayTypeDedicatedTemplate object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class DefaultExportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class DefaultImportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class TypeEnum(str, Enum):
        """
        Offering type.
        """

        CONNECT = 'connect'
        DEDICATED = 'dedicated'


    class MacsecCapabilityEnum(str, Enum):
        """
        Indicates the direct link's MACsec capability. It must match one of the MACsec
        related `capabilities` of the `cross_connect_router`.
        - non_macsec: The direct link does not support MACsec.
        - macsec: The direct link supports MACsec. The MACsec feature must be enabled.
        - macsec_optional: The direct link supports MACsec. The MACsec feature is not
        required and can be enabled after direct link creation.
        If not explicitly provided, the field will be assigned with the following
        priorities based on `cross_connect_router` capabilities and available ports:
          - `macsec` was not provided in the request
            - `non_macsec`
            - `macsec_optional`
          - `macsec` was provided in the request
            - `macsec_optional`
            - `macsec`.
        """

        NON_MACSEC = 'non_macsec'
        MACSEC = 'macsec'
        MACSEC_OPTIONAL = 'macsec_optional'



class GetGatewayResponseCrossAccountGateway(GetGatewayResponse):
    """
    cross-account gateway read-only view.

    :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 datetime bgp_status_updated_at: (optional) Date and time bgp status was
          updated.
    :param str connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param datetime created_at: The date and time resource was created.
    :param str crn: The CRN (Cloud Resource Name) of this gateway.
    :param bool cross_account: Indicates whether this gateway is cross account
          gateway.
    :param str cross_connect_router: (optional) Cross connect router. Only included
          on type=dedicated gateways.
    :param bool global_: Gateways with global routing (`true`) can connect to
          networks outside their associated region.
    :param str id: The unique identifier of this gateway.
    :param str link_status: (optional) Gateway link status.  Only included on
          type=dedicated gateways. The list of enumerated values for this property may
          expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    :param datetime link_status_updated_at: (optional) Date and time link status was
          updated.
    :param str location_display_name: Gateway location long name.
    :param str location_name: Gateway location.
    :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 GatewayPortReference port: (optional) Port information for type=connect
          gateways.
    :param int speed_mbps: Gateway speed in megabits per second.
    :param str type: Offering type. The list of enumerated values for this property
          may expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    """

    def __init__(
        self,
        created_at: datetime,
        crn: str,
        cross_account: bool,
        global_: bool,
        id: str,
        location_display_name: str,
        location_name: str,
        name: str,
        operational_status: str,
        speed_mbps: int,
        type: str,
        *,
        bgp_status: Optional[str] = None,
        bgp_status_updated_at: Optional[datetime] = None,
        connection_mode: Optional[str] = None,
        cross_connect_router: Optional[str] = None,
        link_status: Optional[str] = None,
        link_status_updated_at: Optional[datetime] = None,
        port: Optional['GatewayPortReference'] = None,
    ) -> None:
        """
        Initialize a GetGatewayResponseCrossAccountGateway object.

        :param datetime created_at: The date and time resource was created.
        :param str crn: The CRN (Cloud Resource Name) of this gateway.
        :param bool cross_account: Indicates whether this gateway is cross account
               gateway.
        :param bool global_: Gateways with global routing (`true`) can connect to
               networks outside their associated region.
        :param str id: The unique identifier of this gateway.
        :param str location_display_name: Gateway location long name.
        :param str location_name: Gateway location.
        :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 int speed_mbps: Gateway speed in megabits per second.
        :param str type: Offering type. The list of enumerated values for this
               property may expand in the future. Code and processes using this field
               must tolerate unexpected values.
        :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 datetime bgp_status_updated_at: (optional) Date and time bgp status
               was updated.
        :param str connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str cross_connect_router: (optional) Cross connect router. Only
               included on type=dedicated gateways.
        :param str link_status: (optional) Gateway link status.  Only included on
               type=dedicated gateways. The list of enumerated values for this property
               may expand in the future. Code and processes using this field  must
               tolerate unexpected values.
        :param datetime link_status_updated_at: (optional) Date and time link
               status was updated.
        :param GatewayPortReference port: (optional) Port information for
               type=connect gateways.
        """
        # pylint: disable=super-init-not-called
        self.bgp_status = bgp_status
        self.bgp_status_updated_at = bgp_status_updated_at
        self.connection_mode = connection_mode
        self.created_at = created_at
        self.crn = crn
        self.cross_account = cross_account
        self.cross_connect_router = cross_connect_router
        self.global_ = global_
        self.id = id
        self.link_status = link_status
        self.link_status_updated_at = link_status_updated_at
        self.location_display_name = location_display_name
        self.location_name = location_name
        self.name = name
        self.operational_status = operational_status
        self.port = port
        self.speed_mbps = speed_mbps
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GetGatewayResponseCrossAccountGateway':
        """Initialize a GetGatewayResponseCrossAccountGateway object from a json dictionary."""
        args = {}
        if (bgp_status := _dict.get('bgp_status')) is not None:
            args['bgp_status'] = bgp_status
        if (bgp_status_updated_at := _dict.get('bgp_status_updated_at')) is not None:
            args['bgp_status_updated_at'] = string_to_datetime(bgp_status_updated_at)
        if (connection_mode := _dict.get('connection_mode')) is not None:
            args['connection_mode'] = connection_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 GetGatewayResponseCrossAccountGateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (cross_account := _dict.get('cross_account')) is not None:
            args['cross_account'] = cross_account
        else:
            raise ValueError('Required property \'cross_account\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (cross_connect_router := _dict.get('cross_connect_router')) is not None:
            args['cross_connect_router'] = cross_connect_router
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        else:
            raise ValueError('Required property \'global\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (link_status := _dict.get('link_status')) is not None:
            args['link_status'] = link_status
        if (link_status_updated_at := _dict.get('link_status_updated_at')) is not None:
            args['link_status_updated_at'] = string_to_datetime(link_status_updated_at)
        if (location_display_name := _dict.get('location_display_name')) is not None:
            args['location_display_name'] = location_display_name
        else:
            raise ValueError('Required property \'location_display_name\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (location_name := _dict.get('location_name')) is not None:
            args['location_name'] = location_name
        else:
            raise ValueError('Required property \'location_name\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (operational_status := _dict.get('operational_status')) is not None:
            args['operational_status'] = operational_status
        else:
            raise ValueError('Required property \'operational_status\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (port := _dict.get('port')) is not None:
            args['port'] = GatewayPortReference.from_dict(port)
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        else:
            raise ValueError('Required property \'speed_mbps\' not present in GetGatewayResponseCrossAccountGateway JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in GetGatewayResponseCrossAccountGateway JSON')
        return cls(**args)

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a GetGatewayResponseCrossAccountGateway object from 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_status') and self.bgp_status is not None:
            _dict['bgp_status'] = self.bgp_status
        if hasattr(self, 'bgp_status_updated_at') and self.bgp_status_updated_at is not None:
            _dict['bgp_status_updated_at'] = datetime_to_string(self.bgp_status_updated_at)
        if hasattr(self, 'connection_mode') and self.connection_mode is not None:
            _dict['connection_mode'] = self.connection_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, 'cross_account') and self.cross_account is not None:
            _dict['cross_account'] = self.cross_account
        if hasattr(self, 'cross_connect_router') and self.cross_connect_router is not None:
            _dict['cross_connect_router'] = self.cross_connect_router
        if hasattr(self, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'link_status') and self.link_status is not None:
            _dict['link_status'] = self.link_status
        if hasattr(self, 'link_status_updated_at') and self.link_status_updated_at is not None:
            _dict['link_status_updated_at'] = datetime_to_string(self.link_status_updated_at)
        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, '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:
            if isinstance(self.port, dict):
                _dict['port'] = self.port
            else:
                _dict['port'] = self.port.to_dict()
        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
        return _dict

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

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

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

    def __ne__(self, other: 'GetGatewayResponseCrossAccountGateway') -> 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 ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class LinkStatusEnum(str, Enum):
        """
        Gateway link status.  Only included on type=dedicated gateways. The list of
        enumerated values for this property may expand in the future. Code and processes
        using this field  must tolerate unexpected values.
        """

        DOWN = 'down'
        UP = 'up'


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

        AWAITING_COMPLETION_NOTICE = 'awaiting_completion_notice'
        AWAITING_LOA = 'awaiting_loa'
        CONFIGURING = 'configuring'
        CREATE_PENDING = 'create_pending'
        CREATE_REJECTED = 'create_rejected'
        COMPLETION_NOTICE_APPROVED = 'completion_notice_approved'
        COMPLETION_NOTICE_RECEIVED = 'completion_notice_received'
        COMPLETION_NOTICE_REJECTED = 'completion_notice_rejected'
        DELETE_PENDING = 'delete_pending'
        LOA_ACCEPTED = 'loa_accepted'
        LOA_CREATED = 'loa_created'
        LOA_REJECTED = 'loa_rejected'
        PROVISIONED = 'provisioned'


    class TypeEnum(str, Enum):
        """
        Offering type. The list of enumerated values for this property may expand in the
        future. Code and processes using this field  must tolerate unexpected values.
        """

        CONNECT = 'connect'
        DEDICATED = 'dedicated'



class GetGatewayResponseGateway(GetGatewayResponse):
    """
    gateway.

    :param List[AsPrepend] as_prepends: (optional) array of AS Prepend information.
    :param AuthenticationKeyReference authentication_key: (optional)
    :param GatewayBfdConfig bfd_config: (optional) BFD configuration information.
    :param int bgp_asn: Customer BGP ASN.
    :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR is deprecated
          and no longer recognized by the Direct Link APIs.
          See bgp_cer_cidr and bgp_ibm_cidr fields instead for IP related information.
          Deprecated field bgp_base_cidr will be removed from the API specification after
          15-MAR-2021.
    :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
    :param int bgp_ibm_asn: (optional) IBM BGP ASN.
    :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 datetime bgp_status_updated_at: (optional) Date and time bgp status was
          updated.
    :param str carrier_name: (optional) Carrier name.  Only set for type=dedicated
          gateways.
    :param GatewayChangeRequest change_request: (optional) Changes pending approval
          for provider managed Direct Link Connect gateways.
    :param str completion_notice_reject_reason: (optional) Reason for completion
          notice rejection.  Only included on type=dedicated gateways with a rejected
          completion notice.
    :param str connection_mode: (optional) Type of services this Gateway is attached
          to. Mode transit means this Gateway will be attached to Transit Gateway Service
          and direct means this Gateway will be attached to vpc or classic connection. The
          list of enumerated values for this property may expand in the future. Code and
          processes using this field  must tolerate unexpected values.
    :param datetime created_at: The date and time resource was created.
    :param str crn: The CRN (Cloud Resource Name) of this gateway.
    :param bool cross_account: Indicates whether this gateway is cross account
          gateway.
    :param str cross_connect_router: (optional) Cross connect router. Only included
          on type=dedicated gateways.
    :param str customer_name: (optional) Customer name.  Only set for type=dedicated
          gateways.
    :param str default_export_route_filter: The default directional route filter
          action that applies to routes that do not match any directional route filters.
    :param str default_import_route_filter: The default directional route filter
          action that applies to routes that do not match any directional route filters.
    :param bool global_: Gateways with global routing (`true`) can connect to
          networks outside their associated region.
    :param str id: The unique identifier of this gateway.
    :param str link_status: (optional) Gateway link status.  Only included on
          type=dedicated gateways. The list of enumerated values for this property may
          expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    :param datetime link_status_updated_at: (optional) Date and time link status was
          updated.
    :param str location_display_name: Gateway location long name.
    :param str location_name: Gateway location.
    :param GatewayMacsecReference macsec: (optional) MACsec configuration
          information of a Direct Link gateway.
    :param str macsec_capability: (optional) Indicates the direct link's MACsec
          capability. It must match one of the MACsec related `capabilities` of the
          `cross_connect_router`.
          Only included on type=dedicated direct links.
          - non_macsec: The direct link does not support MACsec.
          - macsec: The direct link supports MACsec. The MACsec feature must be enabled.
          - macsec_optional: The direct link supports MACsec. The MACsec feature is not
          required and can be enabled after direct link creation.
    :param bool metered: Metered billing option.  When `true` gateway usage is
          billed per gigabyte.  When `false` there is no per gigabyte usage charge,
          instead a flat rate is charged for the 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.
          See `operational_status_reasons[]` for possible remediation of the `failed`
          `operational_status`.
    :param List[GatewayStatusReason] operational_status_reasons: Context for certain
          values of `operational_status`.
    :param str patch_panel_completion_notice: (optional) Gateway patch panel
          complete notification from implementation team.
    :param GatewayPortReference port: (optional) Port information for type=connect
          gateways.
    :param bool provider_api_managed: (optional) Indicates whether gateway changes
          must be made via a provider portal.
    :param ResourceGroupReference resource_group: (optional) Resource group
          reference.
    :param int speed_mbps: Gateway speed in megabits per second.
    :param str type: Offering type. The list of enumerated values for this property
          may expand in the future. Code and processes using this field  must tolerate
          unexpected values.
    :param int vlan: (optional) VLAN configured for this gateway. If there is no
          vlan configured for the gateway, the vlan will be absent. This property will
          also be absent if this gateway's `crn` is in another account.
    """

    def __init__(
        self,
        bgp_asn: int,
        created_at: datetime,
        crn: str,
        cross_account: bool,
        default_export_route_filter: str,
        default_import_route_filter: str,
        global_: bool,
        id: str,
        location_display_name: str,
        location_name: str,
        metered: bool,
        name: str,
        operational_status: str,
        operational_status_reasons: List['GatewayStatusReason'],
        speed_mbps: int,
        type: str,
        *,
        as_prepends: Optional[List['AsPrepend']] = None,
        authentication_key: Optional['AuthenticationKeyReference'] = None,
        bfd_config: Optional['GatewayBfdConfig'] = None,
        bgp_base_cidr: Optional[str] = None,
        bgp_cer_cidr: Optional[str] = None,
        bgp_ibm_asn: Optional[int] = None,
        bgp_ibm_cidr: Optional[str] = None,
        bgp_status: Optional[str] = None,
        bgp_status_updated_at: Optional[datetime] = None,
        carrier_name: Optional[str] = None,
        change_request: Optional['GatewayChangeRequest'] = None,
        completion_notice_reject_reason: Optional[str] = None,
        connection_mode: Optional[str] = None,
        cross_connect_router: Optional[str] = None,
        customer_name: Optional[str] = None,
        link_status: Optional[str] = None,
        link_status_updated_at: Optional[datetime] = None,
        macsec: Optional['GatewayMacsecReference'] = None,
        macsec_capability: Optional[str] = None,
        patch_panel_completion_notice: Optional[str] = None,
        port: Optional['GatewayPortReference'] = None,
        provider_api_managed: Optional[bool] = None,
        resource_group: Optional['ResourceGroupReference'] = None,
        vlan: Optional[int] = None,
    ) -> None:
        """
        Initialize a GetGatewayResponseGateway object.

        :param int bgp_asn: Customer BGP ASN.
        :param datetime created_at: The date and time resource was created.
        :param str crn: The CRN (Cloud Resource Name) of this gateway.
        :param bool cross_account: Indicates whether this gateway is cross account
               gateway.
        :param str default_export_route_filter: The default directional route
               filter action that applies to routes that do not match any directional
               route filters.
        :param str default_import_route_filter: The default directional route
               filter action that applies to routes that do not match any directional
               route filters.
        :param bool global_: Gateways with global routing (`true`) can connect to
               networks outside their associated region.
        :param str id: The unique identifier of this gateway.
        :param str location_display_name: Gateway location long name.
        :param str location_name: Gateway location.
        :param bool metered: Metered billing option.  When `true` gateway usage is
               billed per gigabyte.  When `false` there is no per gigabyte usage charge,
               instead a flat rate is charged for the 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.
               See `operational_status_reasons[]` for possible remediation of the `failed`
               `operational_status`.
        :param List[GatewayStatusReason] operational_status_reasons: Context for
               certain values of `operational_status`.
        :param int speed_mbps: Gateway speed in megabits per second.
        :param str type: Offering type. The list of enumerated values for this
               property may expand in the future. Code and processes using this field
               must tolerate unexpected values.
        :param List[AsPrepend] as_prepends: (optional) array of AS Prepend
               information.
        :param AuthenticationKeyReference authentication_key: (optional)
        :param GatewayBfdConfig bfd_config: (optional) BFD configuration
               information.
        :param str bgp_base_cidr: (optional) (DEPRECATED) BGP base CIDR is
               deprecated and no longer recognized by the Direct Link APIs.
               See bgp_cer_cidr and bgp_ibm_cidr fields instead for IP related
               information.
               Deprecated field bgp_base_cidr will be removed from the API specification
               after 15-MAR-2021.
        :param str bgp_cer_cidr: (optional) BGP customer edge router CIDR.
        :param int bgp_ibm_asn: (optional) IBM BGP ASN.
        :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 datetime bgp_status_updated_at: (optional) Date and time bgp status
               was updated.
        :param str carrier_name: (optional) Carrier name.  Only set for
               type=dedicated gateways.
        :param GatewayChangeRequest change_request: (optional) Changes pending
               approval for provider managed Direct Link Connect gateways.
        :param str completion_notice_reject_reason: (optional) Reason for
               completion notice rejection.  Only included on type=dedicated gateways with
               a rejected completion notice.
        :param str connection_mode: (optional) Type of services this Gateway is
               attached to. Mode transit means this Gateway will be attached to Transit
               Gateway Service and direct means this Gateway will be attached to vpc or
               classic connection. The list of enumerated values for this property may
               expand in the future. Code and processes using this field  must tolerate
               unexpected values.
        :param str cross_connect_router: (optional) Cross connect router. Only
               included on type=dedicated gateways.
        :param str customer_name: (optional) Customer name.  Only set for
               type=dedicated gateways.
        :param str link_status: (optional) Gateway link status.  Only included on
               type=dedicated gateways. The list of enumerated values for this property
               may expand in the future. Code and processes using this field  must
               tolerate unexpected values.
        :param datetime link_status_updated_at: (optional) Date and time link
               status was updated.
        :param GatewayMacsecReference macsec: (optional) MACsec configuration
               information of a Direct Link gateway.
        :param str macsec_capability: (optional) Indicates the direct link's MACsec
               capability. It must match one of the MACsec related `capabilities` of the
               `cross_connect_router`.
               Only included on type=dedicated direct links.
               - non_macsec: The direct link does not support MACsec.
               - macsec: The direct link supports MACsec. The MACsec feature must be
               enabled.
               - macsec_optional: The direct link supports MACsec. The MACsec feature is
               not required and can be enabled after direct link creation.
        :param str patch_panel_completion_notice: (optional) Gateway patch panel
               complete notification from implementation team.
        :param GatewayPortReference port: (optional) Port information for
               type=connect gateways.
        :param bool provider_api_managed: (optional) Indicates whether gateway
               changes must be made via a provider portal.
        :param ResourceGroupReference resource_group: (optional) Resource group
               reference.
        :param int vlan: (optional) VLAN configured for this gateway. If there is
               no vlan configured for the gateway, the vlan will be absent. This property
               will also be absent if this gateway's `crn` is in another account.
        """
        # pylint: disable=super-init-not-called
        self.as_prepends = as_prepends
        self.authentication_key = authentication_key
        self.bfd_config = bfd_config
        self.bgp_asn = bgp_asn
        self.bgp_base_cidr = bgp_base_cidr
        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.bgp_status_updated_at = bgp_status_updated_at
        self.carrier_name = carrier_name
        self.change_request = change_request
        self.completion_notice_reject_reason = completion_notice_reject_reason
        self.connection_mode = connection_mode
        self.created_at = created_at
        self.crn = crn
        self.cross_account = cross_account
        self.cross_connect_router = cross_connect_router
        self.customer_name = customer_name
        self.default_export_route_filter = default_export_route_filter
        self.default_import_route_filter = default_import_route_filter
        self.global_ = global_
        self.id = id
        self.link_status = link_status
        self.link_status_updated_at = link_status_updated_at
        self.location_display_name = location_display_name
        self.location_name = location_name
        self.macsec = macsec
        self.macsec_capability = macsec_capability
        self.metered = metered
        self.name = name
        self.operational_status = operational_status
        self.operational_status_reasons = operational_status_reasons
        self.patch_panel_completion_notice = patch_panel_completion_notice
        self.port = port
        self.provider_api_managed = provider_api_managed
        self.resource_group = resource_group
        self.speed_mbps = speed_mbps
        self.type = type
        self.vlan = vlan

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'GetGatewayResponseGateway':
        """Initialize a GetGatewayResponseGateway object from a json dictionary."""
        args = {}
        if (as_prepends := _dict.get('as_prepends')) is not None:
            args['as_prepends'] = [AsPrepend.from_dict(v) for v in as_prepends]
        if (authentication_key := _dict.get('authentication_key')) is not None:
            args['authentication_key'] = authentication_key
        if (bfd_config := _dict.get('bfd_config')) is not None:
            args['bfd_config'] = GatewayBfdConfig.from_dict(bfd_config)
        if (bgp_asn := _dict.get('bgp_asn')) is not None:
            args['bgp_asn'] = bgp_asn
        else:
            raise ValueError('Required property \'bgp_asn\' not present in GetGatewayResponseGateway JSON')
        if (bgp_base_cidr := _dict.get('bgp_base_cidr')) is not None:
            args['bgp_base_cidr'] = bgp_base_cidr
        if (bgp_cer_cidr := _dict.get('bgp_cer_cidr')) is not None:
            args['bgp_cer_cidr'] = bgp_cer_cidr
        if (bgp_ibm_asn := _dict.get('bgp_ibm_asn')) is not None:
            args['bgp_ibm_asn'] = bgp_ibm_asn
        if (bgp_ibm_cidr := _dict.get('bgp_ibm_cidr')) is not None:
            args['bgp_ibm_cidr'] = bgp_ibm_cidr
        if (bgp_status := _dict.get('bgp_status')) is not None:
            args['bgp_status'] = bgp_status
        if (bgp_status_updated_at := _dict.get('bgp_status_updated_at')) is not None:
            args['bgp_status_updated_at'] = string_to_datetime(bgp_status_updated_at)
        if (carrier_name := _dict.get('carrier_name')) is not None:
            args['carrier_name'] = carrier_name
        if (change_request := _dict.get('change_request')) is not None:
            args['change_request'] = change_request
        if (completion_notice_reject_reason := _dict.get('completion_notice_reject_reason')) is not None:
            args['completion_notice_reject_reason'] = completion_notice_reject_reason
        if (connection_mode := _dict.get('connection_mode')) is not None:
            args['connection_mode'] = connection_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 GetGatewayResponseGateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        else:
            raise ValueError('Required property \'crn\' not present in GetGatewayResponseGateway JSON')
        if (cross_account := _dict.get('cross_account')) is not None:
            args['cross_account'] = cross_account
        else:
            raise ValueError('Required property \'cross_account\' not present in GetGatewayResponseGateway JSON')
        if (cross_connect_router := _dict.get('cross_connect_router')) is not None:
            args['cross_connect_router'] = cross_connect_router
        if (customer_name := _dict.get('customer_name')) is not None:
            args['customer_name'] = customer_name
        if (default_export_route_filter := _dict.get('default_export_route_filter')) is not None:
            args['default_export_route_filter'] = default_export_route_filter
        else:
            raise ValueError('Required property \'default_export_route_filter\' not present in GetGatewayResponseGateway JSON')
        if (default_import_route_filter := _dict.get('default_import_route_filter')) is not None:
            args['default_import_route_filter'] = default_import_route_filter
        else:
            raise ValueError('Required property \'default_import_route_filter\' not present in GetGatewayResponseGateway JSON')
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        else:
            raise ValueError('Required property \'global\' not present in GetGatewayResponseGateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in GetGatewayResponseGateway JSON')
        if (link_status := _dict.get('link_status')) is not None:
            args['link_status'] = link_status
        if (link_status_updated_at := _dict.get('link_status_updated_at')) is not None:
            args['link_status_updated_at'] = string_to_datetime(link_status_updated_at)
        if (location_display_name := _dict.get('location_display_name')) is not None:
            args['location_display_name'] = location_display_name
        else:
            raise ValueError('Required property \'location_display_name\' not present in GetGatewayResponseGateway JSON')
        if (location_name := _dict.get('location_name')) is not None:
            args['location_name'] = location_name
        else:
            raise ValueError('Required property \'location_name\' not present in GetGatewayResponseGateway JSON')
        if (macsec := _dict.get('macsec')) is not None:
            args['macsec'] = GatewayMacsecReference.from_dict(macsec)
        if (macsec_capability := _dict.get('macsec_capability')) is not None:
            args['macsec_capability'] = macsec_capability
        if (metered := _dict.get('metered')) is not None:
            args['metered'] = metered
        else:
            raise ValueError('Required property \'metered\' not present in GetGatewayResponseGateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in GetGatewayResponseGateway JSON')
        if (operational_status := _dict.get('operational_status')) is not None:
            args['operational_status'] = operational_status
        else:
            raise ValueError('Required property \'operational_status\' not present in GetGatewayResponseGateway JSON')
        if (operational_status_reasons := _dict.get('operational_status_reasons')) is not None:
            args['operational_status_reasons'] = [GatewayStatusReason.from_dict(v) for v in operational_status_reasons]
        else:
            raise ValueError('Required property \'operational_status_reasons\' not present in GetGatewayResponseGateway JSON')
        if (patch_panel_completion_notice := _dict.get('patch_panel_completion_notice')) is not None:
            args['patch_panel_completion_notice'] = patch_panel_completion_notice
        if (port := _dict.get('port')) is not None:
            args['port'] = GatewayPortReference.from_dict(port)
        if (provider_api_managed := _dict.get('provider_api_managed')) is not None:
            args['provider_api_managed'] = provider_api_managed
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        if (speed_mbps := _dict.get('speed_mbps')) is not None:
            args['speed_mbps'] = speed_mbps
        else:
            raise ValueError('Required property \'speed_mbps\' not present in GetGatewayResponseGateway JSON')
        if (type := _dict.get('type')) is not None:
            args['type'] = type
        else:
            raise ValueError('Required property \'type\' not present in GetGatewayResponseGateway JSON')
        if (vlan := _dict.get('vlan')) is not None:
            args['vlan'] = vlan
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'as_prepends') and self.as_prepends is not None:
            as_prepends_list = []
            for v in self.as_prepends:
                if isinstance(v, dict):
                    as_prepends_list.append(v)
                else:
                    as_prepends_list.append(v.to_dict())
            _dict['as_prepends'] = as_prepends_list
        if hasattr(self, 'authentication_key') and self.authentication_key is not None:
            if isinstance(self.authentication_key, dict):
                _dict['authentication_key'] = self.authentication_key
            else:
                _dict['authentication_key'] = self.authentication_key.to_dict()
        if hasattr(self, 'bfd_config') and self.bfd_config is not None:
            if isinstance(self.bfd_config, dict):
                _dict['bfd_config'] = self.bfd_config
            else:
                _dict['bfd_config'] = self.bfd_config.to_dict()
        if hasattr(self, 'bgp_asn') and self.bgp_asn is not None:
            _dict['bgp_asn'] = self.bgp_asn
        if hasattr(self, 'bgp_base_cidr') and self.bgp_base_cidr is not None:
            _dict['bgp_base_cidr'] = self.bgp_base_cidr
        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, 'bgp_status_updated_at') and self.bgp_status_updated_at is not None:
            _dict['bgp_status_updated_at'] = datetime_to_string(self.bgp_status_updated_at)
        if hasattr(self, 'carrier_name') and self.carrier_name is not None:
            _dict['carrier_name'] = self.carrier_name
        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, 'completion_notice_reject_reason') and self.completion_notice_reject_reason is not None:
            _dict['completion_notice_reject_reason'] = self.completion_notice_reject_reason
        if hasattr(self, 'connection_mode') and self.connection_mode is not None:
            _dict['connection_mode'] = self.connection_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, 'cross_account') and self.cross_account is not None:
            _dict['cross_account'] = self.cross_account
        if hasattr(self, 'cross_connect_router') and self.cross_connect_router is not None:
            _dict['cross_connect_router'] = self.cross_connect_router
        if hasattr(self, 'customer_name') and self.customer_name is not None:
            _dict['customer_name'] = self.customer_name
        if hasattr(self, 'default_export_route_filter') and self.default_export_route_filter is not None:
            _dict['default_export_route_filter'] = self.default_export_route_filter
        if hasattr(self, 'default_import_route_filter') and self.default_import_route_filter is not None:
            _dict['default_import_route_filter'] = self.default_import_route_filter
        if hasattr(self, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'link_status') and self.link_status is not None:
            _dict['link_status'] = self.link_status
        if hasattr(self, 'link_status_updated_at') and self.link_status_updated_at is not None:
            _dict['link_status_updated_at'] = datetime_to_string(self.link_status_updated_at)
        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, 'macsec') and self.macsec is not None:
            if isinstance(self.macsec, dict):
                _dict['macsec'] = self.macsec
            else:
                _dict['macsec'] = self.macsec.to_dict()
        if hasattr(self, 'macsec_capability') and self.macsec_capability is not None:
            _dict['macsec_capability'] = self.macsec_capability
        if hasattr(self, 'metered') and self.metered is not None:
            _dict['metered'] = self.metered
        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, 'operational_status_reasons') and self.operational_status_reasons is not None:
            operational_status_reasons_list = []
            for v in self.operational_status_reasons:
                if isinstance(v, dict):
                    operational_status_reasons_list.append(v)
                else:
                    operational_status_reasons_list.append(v.to_dict())
            _dict['operational_status_reasons'] = operational_status_reasons_list
        if hasattr(self, 'patch_panel_completion_notice') and self.patch_panel_completion_notice is not None:
            _dict['patch_panel_completion_notice'] = self.patch_panel_completion_notice
        if hasattr(self, 'port') and self.port is not None:
            if isinstance(self.port, dict):
                _dict['port'] = self.port
            else:
                _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, '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, '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 GetGatewayResponseGateway object."""
        return json.dumps(self.to_dict(), indent=2)

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

    def __ne__(self, other: 'GetGatewayResponseGateway') -> 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 ConnectionModeEnum(str, Enum):
        """
        Type of services this Gateway is attached to. Mode transit means this Gateway will
        be attached to Transit Gateway Service and direct means this Gateway will be
        attached to vpc or classic connection. The list of enumerated values for this
        property may expand in the future. Code and processes using this field  must
        tolerate unexpected values.
        """

        DIRECT = 'direct'
        TRANSIT = 'transit'


    class DefaultExportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class DefaultImportRouteFilterEnum(str, Enum):
        """
        The default directional route filter action that applies to routes that do not
        match any directional route filters.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class LinkStatusEnum(str, Enum):
        """
        Gateway link status.  Only included on type=dedicated gateways. The list of
        enumerated values for this property may expand in the future. Code and processes
        using this field  must tolerate unexpected values.
        """

        DOWN = 'down'
        UP = 'up'


    class MacsecCapabilityEnum(str, Enum):
        """
        Indicates the direct link's MACsec capability. It must match one of the MACsec
        related `capabilities` of the `cross_connect_router`.
        Only included on type=dedicated direct links.
        - non_macsec: The direct link does not support MACsec.
        - macsec: The direct link supports MACsec. The MACsec feature must be enabled.
        - macsec_optional: The direct link supports MACsec. The MACsec feature is not
        required and can be enabled after direct link creation.
        """

        NON_MACSEC = 'non_macsec'
        MACSEC = 'macsec'
        MACSEC_OPTIONAL = 'macsec_optional'


    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.
        See `operational_status_reasons[]` for possible remediation of the `failed`
        `operational_status`.
        """

        AWAITING_COMPLETION_NOTICE = 'awaiting_completion_notice'
        AWAITING_LOA = 'awaiting_loa'
        CONFIGURING = 'configuring'
        CREATE_PENDING = 'create_pending'
        CREATE_REJECTED = 'create_rejected'
        COMPLETION_NOTICE_APPROVED = 'completion_notice_approved'
        COMPLETION_NOTICE_RECEIVED = 'completion_notice_received'
        COMPLETION_NOTICE_REJECTED = 'completion_notice_rejected'
        DELETE_PENDING = 'delete_pending'
        LOA_ACCEPTED = 'loa_accepted'
        LOA_CREATED = 'loa_created'
        LOA_REJECTED = 'loa_rejected'
        PROVISIONED = 'provisioned'
        FAILED = 'failed'


    class TypeEnum(str, Enum):
        """
        Offering type. The list of enumerated values for this property may expand in the
        future. Code and processes using this field  must tolerate unexpected values.
        """

        CONNECT = 'connect'
        DEDICATED = 'dedicated'



class RouteReportOverlappingRouteForConnection(RouteReportOverlappingRoute):
    """
    overlapping route details.

    :param str prefix: overlapping prefix.
    :param str type: type of the route.
    :param str virtual_connection_id: virtual connection ID.
    """

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

        :param str prefix: overlapping prefix.
        :param str type: type of the route.
        :param str virtual_connection_id: virtual connection ID.
        """
        # pylint: disable=super-init-not-called
        self.prefix = prefix
        self.type = type
        self.virtual_connection_id = virtual_connection_id

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

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

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

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

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

    class TypeEnum(str, Enum):
        """
        type of the route.
        """

        VIRTUAL_CONNECTION = 'virtual_connection'



class RouteReportOverlappingRouteForOthers(RouteReportOverlappingRoute):
    """
    overlapping route details.

    :param str prefix: overlapping prefix.
    :param str type: type of the route.
    """

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

        :param str prefix: overlapping prefix.
        :param str type: type of the route.
        """
        # pylint: disable=super-init-not-called
        self.prefix = prefix
        self.type = type

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

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

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

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

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

    class TypeEnum(str, Enum):
        """
        type of the route.
        """

        GATEWAY = 'gateway'
        ON_PREM = 'on_prem'



class SakRekeyPacketNumberRolloverMode(SakRekey):
    """
    SAK rekey mode based on a high proportion of used packet numbers with the current SAK
    (the exact threshold determined at the system's discretion).

    :param str mode: Determines that the SAK rekey occurs based on the used packet
          numbers.
    """

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

        :param str mode: Determines that the SAK rekey occurs based on the used
               packet numbers.
        """
        # pylint: disable=super-init-not-called
        self.mode = mode

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

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

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

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

    class ModeEnum(str, Enum):
        """
        Determines that the SAK rekey occurs based on the used packet numbers.
        """

        PACKET_NUMBER_ROLLOVER = 'packet_number_rollover'



class SakRekeyPatchSakRekeyPacketNumberRolloverModePatch(SakRekeyPatch):
    """
    SAK rekey mode based on a high proportion of used packet numbers with the current SAK
    (the exact threshold determined at the system's discretion).

    :param str mode: Determines that the SAK rekey occurs based on the used packet
          numbers.
    """

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

        :param str mode: Determines that the SAK rekey occurs based on the used
               packet numbers.
        """
        # pylint: disable=super-init-not-called
        self.mode = mode

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

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

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

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

    class ModeEnum(str, Enum):
        """
        Determines that the SAK rekey occurs based on the used packet numbers.
        """

        PACKET_NUMBER_ROLLOVER = 'packet_number_rollover'



class SakRekeyPatchSakRekeyTimerModePatch(SakRekeyPatch):
    """
    SAK rekey mode based on length of time since last rekey.

    :param int interval: The time, in seconds, to force a Secure Association Key
          (SAK) rekey.
    :param str mode: Determines that the SAK rekey occurs based on a timer.
    """

    def __init__(
        self,
        interval: int,
        mode: str,
    ) -> None:
        """
        Initialize a SakRekeyPatchSakRekeyTimerModePatch object.

        :param int interval: The time, in seconds, to force a Secure Association
               Key (SAK) rekey.
        :param str mode: Determines that the SAK rekey occurs based on a timer.
        """
        # pylint: disable=super-init-not-called
        self.interval = interval
        self.mode = mode

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

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

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

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

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

    class ModeEnum(str, Enum):
        """
        Determines that the SAK rekey occurs based on a timer.
        """

        TIMER = 'timer'



class SakRekeyPrototypeSakRekeyPacketNumberRolloverModePrototype(SakRekeyPrototype):
    """
    Packet number (PN) rollover SAK rekey mode. The SAK is rekeyed based on the proportion
    of used packet numbers with the current SAK.

    :param str mode: Determines that the SAK rekey occurs based on the used packet
          numbers.
    """

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

        :param str mode: Determines that the SAK rekey occurs based on the used
               packet numbers.
        """
        # pylint: disable=super-init-not-called
        self.mode = mode

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

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

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

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

    class ModeEnum(str, Enum):
        """
        Determines that the SAK rekey occurs based on the used packet numbers.
        """

        PACKET_NUMBER_ROLLOVER = 'packet_number_rollover'



class SakRekeyPrototypeSakRekeyTimerModePrototype(SakRekeyPrototype):
    """
    SAK rekey mode based on length of time since last rekey.

    :param int interval: The time, in seconds, to force a Secure Association Key
          (SAK) rekey.
    :param str mode: Determines that the SAK rekey occurs based on a timer.
    """

    def __init__(
        self,
        interval: int,
        mode: str,
    ) -> None:
        """
        Initialize a SakRekeyPrototypeSakRekeyTimerModePrototype object.

        :param int interval: The time, in seconds, to force a Secure Association
               Key (SAK) rekey.
        :param str mode: Determines that the SAK rekey occurs based on a timer.
        """
        # pylint: disable=super-init-not-called
        self.interval = interval
        self.mode = mode

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

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

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

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

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

    class ModeEnum(str, Enum):
        """
        Determines that the SAK rekey occurs based on a timer.
        """

        TIMER = 'timer'



class SakRekeyTimerMode(SakRekey):
    """
    SAK rekey mode based on length of time since last rekey.

    :param int interval: The time, in seconds, to force a Secure Association Key
          (SAK) rekey.
    :param str mode: Determines that the SAK rekey occurs based on a timer.
    """

    def __init__(
        self,
        interval: int,
        mode: str,
    ) -> None:
        """
        Initialize a SakRekeyTimerMode object.

        :param int interval: The time, in seconds, to force a Secure Association
               Key (SAK) rekey.
        :param str mode: Determines that the SAK rekey occurs based on a timer.
        """
        # pylint: disable=super-init-not-called
        self.interval = interval
        self.mode = mode

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

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

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

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

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

    class ModeEnum(str, Enum):
        """
        Determines that the SAK rekey occurs based on a timer.
        """

        TIMER = 'timer'


##############################################################################
# Pagers
##############################################################################


class PortsPager:
    """
    PortsPager can be used to simplify the use of the "list_ports" method.
    """

    def __init__(
        self,
        *,
        client: DirectLinkV1,
        limit: int = None,
        location_name: str = None,
    ) -> None:
        """
        Initialize a PortsPager object.
        :param int limit: (optional) The number of resources to return on a page.
        :param str location_name: (optional) Direct Link location short name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._location_name = location_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 Port.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_ports(
            limit=self._limit,
            location_name=self._location_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 = next_page_link.get('start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('ports')

    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 Port.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results