# 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.107.1-41b0fbd0-20250825-080732

"""
No description provided (generated by Openapi Generator
https://github.com/openapitools/openapi-generator)

API Version: __VERSION__
"""

from datetime import datetime
from enum import Enum
from typing import Dict, List, 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 TransitGatewayApisV1(BaseService):
    """The Transit Gateway Apis V1 service."""

    DEFAULT_SERVICE_URL = 'https://transit.cloud.ibm.com/v1'
    DEFAULT_SERVICE_NAME = 'transit_gateway_apis'

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

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

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

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

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

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

    #########################
    # Transit Gateways
    #########################

    def list_transit_gateways(
        self,
        *,
        limit: Optional[int] = None,
        start: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves all Transit Gateways.

        List all Transit Gateways in account the caller is authorized to view.

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

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

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

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

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

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

    def create_transit_gateway(
        self,
        location: str,
        name: str,
        *,
        global_: Optional[bool] = None,
        gre_enhanced_route_propagation: Optional[bool] = None,
        resource_group: Optional['ResourceGroupIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Creates a Transit Gateway.

        Create a Transit Gateway based on the supplied input template.

        :param str location: Location of Transit Gateway Services.
        :param str name: A human readable name for the transit gateway.
        :param bool global_: (optional) Allow global routing for a Transit Gateway.
               If unspecified, the default value is false.
        :param bool gre_enhanced_route_propagation: (optional) Allow route
               propagation across all GREs connected to the same transit gateway. This
               affects connections on the gateway of type `redundant_gre`,
               `unbound_gre_tunnel` and `gre_tunnel`.
        :param ResourceGroupIdentity resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://console.bluemix.net/apidocs/resource-manager#introduction)
               is used.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `TransitGateway` object
        """

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

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

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

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

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

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

    def delete_transit_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Deletes specified Transit Gateway.

        This request deletes a Transit Gateway. This operation cannot be reversed. For
        this request to succeed, the Transit Gateway must not contain connections.

        :param str id: The Transit 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_transit_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 = '/transit_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_transit_gateway(
        self,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves specified Transit Gateway.

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

        :param str id: The Transit 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 `TransitGateway` 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_transit_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 = '/transit_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_transit_gateway(
        self,
        id: str,
        *,
        global_: Optional[bool] = None,
        gre_enhanced_route_propagation: Optional[bool] = None,
        name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Updates specified Transit Gateway.

        This request updates a Transit Gateway's name and/or global flag.

        :param str id: The Transit Gateway identifier.
        :param bool global_: (optional) Allow global routing for a Transit Gateway.
        :param bool gre_enhanced_route_propagation: (optional) Allow route
               propagation across all GREs connected to the same transit gateway. This
               affects connections on the gateway of type `redundant_gre`,
               `unbound_gre_tunnel` and `gre_tunnel`. It takes a few minutes for the
               change to take effect.
        :param str name: (optional) A human readable name for a resource.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `TransitGateway` 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='update_transit_gateway',
        )
        headers.update(sdk_headers)

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

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

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

        path_param_keys = ['id']
        path_param_values = self.encode_path_vars(id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_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

    #########################
    # Transit Connections
    #########################

    def list_connections(
        self,
        *,
        limit: Optional[int] = None,
        start: Optional[str] = None,
        network_id: Optional[str] = None,
        network_type: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves all connections.

        List all transit gateway connections associated with this account.

        :param int limit: (optional) The maximum number of resources to return per
               page.
        :param str start: (optional) A server supplied token determining which
               resource to start the page on.
        :param str network_id: (optional) Search for connections with the given
               network_id value.
        :param str network_type: (optional) Search for connections with the given
               network_type 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 `TransitConnectionCollection` object
        """

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

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

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

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

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

    #########################
    # Transit Gateways Network Connections
    #########################

    def list_transit_gateway_connections(
        self,
        transit_gateway_id: str,
        *,
        start: Optional[str] = None,
        limit: Optional[int] = None,
        name: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves all connections in a Transit Gateway.

        This request retrieves all connections in a Transit Gateway.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str start: (optional) A server supplied token determining which
               resource to start the page on.
        :param int limit: (optional) The maximum number of resources to return per
               page.
        :param str name: (optional) Search for connections with the given 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 `TransitGatewayConnectionCollection` object
        """

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

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

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

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

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

    def create_transit_gateway_connection(
        self,
        transit_gateway_id: str,
        network_type: str,
        *,
        base_connection_id: Optional[str] = None,
        base_network_type: Optional[str] = None,
        cidr: Optional[str] = None,
        local_gateway_ip: Optional[str] = None,
        local_tunnel_ip: Optional[str] = None,
        name: Optional[str] = None,
        network_account_id: Optional[str] = None,
        network_id: Optional[str] = None,
        prefix_filters: Optional[List['TransitGatewayConnectionPrefixFilter']] = None,
        prefix_filters_default: Optional[str] = None,
        remote_bgp_asn: Optional[int] = None,
        remote_gateway_ip: Optional[str] = None,
        remote_tunnel_ip: Optional[str] = None,
        tunnels: Optional[List['TransitGatewayTunnelTemplate']] = None,
        zone: Optional['ZoneIdentity'] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Adds a connection to a Transit Gateway.

        Add a connection to Transit Gateway.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str network_type: Defines what type of network is connected via this
               connection.
        :param str base_connection_id: (optional) Deprecated: network_type
               `gre_tunnel` connections must be created over an existing network_type
               `classic` connection. This field must specify the ID of an active transit
               gateway network_type `classic` connection in the same transit gateway.
               This field is required for network type `gre_tunnel` connections.
               This field is required to be unspecified for network type `classic`,
               `directlink`, `vpc`,
               `power_virtual_server`, `unbound_gre_tunnel`, `vpn_gateway` and
               `redundant_gre` connections.
        :param str base_network_type: (optional) The type of network the Unbound
               GRE tunnel is targeting. This field is required for network type
               `unbound_gre_tunnel` and must be set to `classic`.  For a `redundant_gre`
               network type, the value is required and can be either VPC or Classic. This
               field is required to be unspecified for network type `classic`,
               `directlink`, `vpc`, `power_virtual_server`, `vpn_gateway` and `gre_tunnel`
               connections.
        :param str cidr: (optional) network_type 'vpn_gateway' connections use
               'cidr' to specify the CIDR to use for the VPN GRE tunnels.
               This field is required for network type `vpn_gateway` connections.
               This field is required to be unspecified for network type `classic`,
               `directlink`, `vpc`, `power_virtual_server`, `gre_tunnel`,
               `unbound_gre_tunnel`, and `redundant_gre` connections.
        :param str local_gateway_ip: (optional) Local gateway IP address. This
               field is required for network type `gre_tunnel` and `unbound_gre_tunnel`
               connections. This field is required to be unspecified for network type
               `classic`, `directlink`, `vpc`, `power_virtual_server`, `vpn_gateway` and
               `redundant_gre` connections.
        :param str local_tunnel_ip: (optional) Local tunnel IP address. The
               local_tunnel_ip and remote_tunnel_ip addresses must be in the same /30
               network. Neither can be the network nor broadcast addresses.
               This field is required for network type `gre_tunnel` and
               `unbound_gre_tunnel` connections.
               This field is required to be unspecified for network type `classic`,
               `directlink`, `vpc`, `power_virtual_server`, `vpn_gateway` and
               `redundant_gre` connections.
        :param str name: (optional) The user-defined name for this transit gateway
               connection. Network type `vpc`  connections are defaulted to the name of
               the VPC.  Network type `classic` connections are named `classic`.
               This field is required for network type `power_virtual_server`,
               `directlink`, `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway` and
               `redundant_gre` connections.
               This field is optional for network type `classic`, `vpc` connections.
        :param str network_account_id: (optional) The ID of the account which owns
               the network that is being connected. Generally only used if the network is
               in a different account than the gateway. This field is required for type
               `unbound_gre_tunnel` when the associated_network_type is `classic` or
               network_type is `redundant_gre` and the GRE tunnel is in a different
               account than the gateway.
        :param str network_id: (optional) The ID of the network being connected via
               this connection. For network types `vpc`,`power_virtual_server`,
               `directlink` and `vpn_gateway` this is the CRN of the VPC / PowerVS / VDC /
               Direct Link / VPN gateway respectively. This field is required for network
               type `vpc`, `power_virtual_server`, `vpn_gateway`, and `directlink`
               connections.  It is also required for `redundant_gre` connections when the
               base_network_type is set to VPC. This field is required to be unspecified
               for network type `classic`, `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param List[TransitGatewayConnectionPrefixFilter] prefix_filters:
               (optional) Array of prefix route filters for a transit gateway connection.
               Prefix filters can be specified for netowrk type `vpc`, `classic`,
               `power_virtual_server` and `directlink` connections. They are not allowed
               for type `gre_tunnel` connections. This is order dependent with those first
               in the array being applied first, and those at the end of the array being
               applied last, or just before applying the default. This field is optional
               for network type `classic`, `vpc`, `directlink`, and `power_virtual_server`
               connections. This field is required to be unspecified for network type
               `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway` and `redundant_gre`
               connections.
        :param str prefix_filters_default: (optional) Default setting of permit or
               deny which applies to any routes that don't match a specified filter. This
               field is optional for network type `classic`, `vpc`, `directlink`, and
               `power_virtual_server` connections. This field is required to be
               unspecified for network type `gre_tunnel`, `unbound_gre_tunnel`,
               `vpn_gateway` and `redundant_gre` connections.
        :param int remote_bgp_asn: (optional) Remote network BGP ASN. The following
               ASN values are reserved and unavailable 0, 13884, 36351, 64512, 64513,
               65100, 65200-65234, 65402-65433, 65500, 65516, 65519, 65521, 65531 and
               4201065000-4201065999. If `remote_bgp_asn` is omitted on gre_tunnel or
               unbound_gre_tunnel connection create requests IBM will assign an ASN.
               This field is optional for network type `gre_tunnel` and
               `unbound_gre_tunnel` connections.
               This field is required to be unspecified for network type `classic`,
               `directlink`, `vpc`, `power_virtual_server`, `vpn_gateway` and `gre_tunnel`
               connections.
        :param str remote_gateway_ip: (optional) Remote gateway IP address. This
               field is required for network type `gre_tunnel` and `unbound_gre_tunnel`
               connections. This field is required to be unspecified for network type
               `classic`, `directlink`, `vpc`, `power_virtual_server`, `vpn_gateway` and
               `redundant_gre` connections.
        :param str remote_tunnel_ip: (optional) Remote tunnel IP address. The
               local_tunnel_ip and remote_tunnel_ip addresses must be in the same /30
               network. Neither can be the network nor broadcast addresses.
               This field is required for network type `gre_tunnel` and
               `unbound_gre_tunnel` connections.
               This field is required to be unspecified for network type `classic`,
               `directlink`, `vpc`,  `power_virtual_server`, `vpn_gateway` and
               `redundant_gre` connections.
        :param List[TransitGatewayTunnelTemplate] tunnels: (optional) Array of GRE
               tunnels for a transit gateway `redundant_gre` connections.  This field is
               required for `redundant_gre` connections.
        :param ZoneIdentity zone: (optional) Specify the connection's location.
               The specified availability zone must reside in the gateway's region.
               Use the IBM Cloud global catalog to list zones within the desired region.
               This field is required for network type `gre_tunnel`, and
               `unbound_gre_tunnel` connections.
               This field is optional for network type `vpn_gateway` connections.
               This field is required to be unspecified for network type `classic`,
               `directlink`, `vpc`, `power_virtual_server` and `redundant_gre`
               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 `TransitGatewayConnectionCust` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if network_type is None:
            raise ValueError('network_type must be provided')
        if prefix_filters is not None:
            prefix_filters = [convert_model(x) for x in prefix_filters]
        if tunnels is not None:
            tunnels = [convert_model(x) for x in tunnels]
        if zone is not None:
            zone = convert_model(zone)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_transit_gateway_connection',
        )
        headers.update(sdk_headers)

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

        data = {
            'network_type': network_type,
            'base_connection_id': base_connection_id,
            'base_network_type': base_network_type,
            'cidr': cidr,
            'local_gateway_ip': local_gateway_ip,
            'local_tunnel_ip': local_tunnel_ip,
            'name': name,
            'network_account_id': network_account_id,
            'network_id': network_id,
            'prefix_filters': prefix_filters,
            'prefix_filters_default': prefix_filters_default,
            'remote_bgp_asn': remote_bgp_asn,
            'remote_gateway_ip': remote_gateway_ip,
            'remote_tunnel_ip': remote_tunnel_ip,
            'tunnels': tunnels,
            'zone': zone,
        }
        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 = ['transit_gateway_id']
        path_param_values = self.encode_path_vars(transit_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections'.format(**path_param_dict)
        request = self.prepare_request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

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

    def delete_transit_gateway_connection(
        self,
        transit_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Removes a connection from Transit Gateway.

        After the specified connection is detached, entities still within the Transit
        Gateway will no longer be able to communicate directly to it through the IBM Cloud
        private backbone.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The 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 transit_gateway_id:
            raise ValueError('transit_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_transit_gateway_connection',
        )
        headers.update(sdk_headers)

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

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

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

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

    def get_transit_gateway_connection(
        self,
        transit_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves specified Transit Gateway connection.

        This request retrieves a connection from the Transit Gateway.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The 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 `TransitGatewayConnectionCust` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_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_transit_gateway_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 = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

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

    def update_transit_gateway_connection(
        self,
        transit_gateway_id: str,
        id: str,
        *,
        name: Optional[str] = None,
        prefix_filters_default: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Updates specified Transit Gateway connection.

        Update the name of a connection to a Transit Gateway.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str name: (optional) The user-defined name for this transit gateway.
               If specified as empty string or nil,  the name will be the network name
               (the name of the VPC in the case of network type `vpc`,  and the word
               Classic, in the case of network type `classic`).
        :param str prefix_filters_default: (optional) Default setting of permit or
               deny which applies to any routes that don't match a specified 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 `TransitGatewayConnectionCust` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_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='update_transit_gateway_connection',
        )
        headers.update(sdk_headers)

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

        data = {
            'name': name,
            'prefix_filters_default': prefix_filters_default,
        }
        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 = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}'.format(**path_param_dict)
        request = self.prepare_request(
            method='PATCH',
            url=url,
            headers=headers,
            params=params,
            data=data,
        )

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

    def create_transit_gateway_connection_actions(
        self,
        transit_gateway_id: str,
        id: str,
        action: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Performs actions on a connection for a Transit Gateway.

        Allow a network owner to approve or reject a cross-account connection request.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str action: The action that is to be performed against the
               connection request.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse
        """

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

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

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

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

        path_param_keys = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{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_transit_gateway_gre_tunnel(
        self,
        transit_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves specified Transit Gateway redundant gre connection tunnels.

        This request retrieves a list of all the tunnels for connection.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The 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 `TransitGatewayTunnelCollection` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_transit_gateway_gre_tunnel',
        )
        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 = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/tunnels'.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_transit_gateway_gre_tunnel(
        self,
        transit_gateway_id: str,
        id: str,
        local_gateway_ip: str,
        local_tunnel_ip: str,
        name: str,
        remote_gateway_ip: str,
        remote_tunnel_ip: str,
        zone: 'ZoneIdentity',
        *,
        remote_bgp_asn: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Creates a Transit Gateway redundant GRE tunnel.

        Add a tunnel to an existing Redundant GRE connection.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str local_gateway_ip: Local gateway IP address.
        :param str local_tunnel_ip: Local tunnel IP address. The local_tunnel_ip
               and remote_tunnel_ip addresses must be in the same /30 network. Neither can
               be the network nor broadcast addresses.
        :param str name: The user-defined name for this tunnel connection.
        :param str remote_gateway_ip: Remote gateway IP address.
        :param str remote_tunnel_ip: Remote tunnel IP address. The local_tunnel_ip
               and remote_tunnel_ip addresses must be in the same /30 network. Neither can
               be the network nor broadcast addresses.
        :param ZoneIdentity zone: Specify the connection's location.  The specified
               availability zone must reside in the gateway's region.
               Use the IBM Cloud global catalog to list zones within the desired region.
        :param int remote_bgp_asn: (optional) Remote network BGP ASN. The following
               ASN values are reserved and unavailable 0, 13884, 36351, 64512, 64513,
               65100, 65200-65234, 65402-65433, 65500, 65516, 65519, 65521, 65531 and
               4201065000-4201065999 If `remote_bgp_asn` is omitted on create requests,
               IBM will assign an ASN.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `TransitGatewayTunnel` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if local_gateway_ip is None:
            raise ValueError('local_gateway_ip must be provided')
        if local_tunnel_ip is None:
            raise ValueError('local_tunnel_ip must be provided')
        if name is None:
            raise ValueError('name must be provided')
        if remote_gateway_ip is None:
            raise ValueError('remote_gateway_ip must be provided')
        if remote_tunnel_ip is None:
            raise ValueError('remote_tunnel_ip must be provided')
        if zone is None:
            raise ValueError('zone must be provided')
        zone = convert_model(zone)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_transit_gateway_gre_tunnel',
        )
        headers.update(sdk_headers)

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

        data = {
            'local_gateway_ip': local_gateway_ip,
            'local_tunnel_ip': local_tunnel_ip,
            'name': name,
            'remote_gateway_ip': remote_gateway_ip,
            'remote_tunnel_ip': remote_tunnel_ip,
            'zone': zone,
            'remote_bgp_asn': remote_bgp_asn,
        }
        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 = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/tunnels'.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_transit_gateway_connection_tunnels(
        self,
        transit_gateway_id: str,
        id: str,
        gre_tunnel_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Deletes a specified Transit Gateway redundant GRE tunnel.

        Remove a tunnel from a redundant GRE connection.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str gre_tunnel_id: The tunnel 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 transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not gre_tunnel_id:
            raise ValueError('gre_tunnel_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_transit_gateway_connection_tunnels',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['transit_gateway_id', 'id', 'gre_tunnel_id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id, gre_tunnel_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/tunnels/{gre_tunnel_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_transit_gateway_connection_tunnels(
        self,
        transit_gateway_id: str,
        id: str,
        gre_tunnel_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves specified Transit Gateway connection tunnel.

        This request retrieves a connection tunnel from the Transit Gateway connection.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str gre_tunnel_id: The tunnel identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `TransitGatewayTunnel` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not gre_tunnel_id:
            raise ValueError('gre_tunnel_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_transit_gateway_connection_tunnels',
        )
        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 = ['transit_gateway_id', 'id', 'gre_tunnel_id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id, gre_tunnel_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/tunnels/{gre_tunnel_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_transit_gateway_connection_tunnels(
        self,
        transit_gateway_id: str,
        id: str,
        gre_tunnel_id: str,
        transit_gateway_tunnel_patch: 'TransitGatewayTunnelPatch',
        **kwargs,
    ) -> DetailedResponse:
        """
        Updates specified Transit Gateway redundant GRE tunnel.

        Update the name of a connection tunnel.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str gre_tunnel_id: The tunnel identifier.
        :param TransitGatewayTunnelPatch transit_gateway_tunnel_patch: The update
               connection tunnel 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 `TransitGatewayTunnel` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not gre_tunnel_id:
            raise ValueError('gre_tunnel_id must be provided')
        if transit_gateway_tunnel_patch is None:
            raise ValueError('transit_gateway_tunnel_patch must be provided')
        if isinstance(transit_gateway_tunnel_patch, TransitGatewayTunnelPatch):
            transit_gateway_tunnel_patch = convert_model(transit_gateway_tunnel_patch)
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='update_transit_gateway_connection_tunnels',
        )
        headers.update(sdk_headers)

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

        data = json.dumps(transit_gateway_tunnel_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 = ['transit_gateway_id', 'id', 'gre_tunnel_id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id, gre_tunnel_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/tunnels/{gre_tunnel_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

    #########################
    # Transit Locations
    #########################

    def list_gateway_locations(
        self,
        **kwargs,
    ) -> DetailedResponse:
        """
        Lists all locations that support Transit Gateways.

        List all locations that support Transit Gateways.

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

        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_gateway_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'

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

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

    def get_gateway_location(
        self,
        name: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Shows the details of a given Transit Gateway location.

        Get the details of a Transit Gateway Location.

        :param str name: The Transit Gateway location 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 `TSLocation` object
        """

        if not name:
            raise ValueError('name must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_gateway_location',
        )
        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 = ['name']
        path_param_values = self.encode_path_vars(name)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/locations/{name}'.format(**path_param_dict)
        request = self.prepare_request(
            method='GET',
            url=url,
            headers=headers,
            params=params,
        )

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

    #########################
    # Transit Gateway Connection Prefix Filters
    #########################

    def list_transit_gateway_connection_prefix_filters(
        self,
        transit_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves all prefix filters in a Transit Gateway connection.

        This request retrieves all prefix filters in a Transit Gateway connection.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The 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 `PrefixFilterCollection` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_transit_gateway_connection_prefix_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 = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/prefix_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_transit_gateway_connection_prefix_filter(
        self,
        transit_gateway_id: str,
        id: str,
        action: str,
        prefix: str,
        *,
        before: Optional[str] = None,
        ge: Optional[int] = None,
        le: Optional[int] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Add a prefix filter to a Transit Gateway connection.

        Add a Prefix Filter to a Transit Gateway Connection. Prefix Filters can be added
        to `vpc`, `classic`, `directlink`, and `power_virtual_server` Connection types.
        Prefix Filters cannot be added to `gre_tunnel`, `unbound_gre_tunnel`,
        `redundant_gre` or `vpn_gateway` Connection types.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str action: Whether or not this prefix filter should allow or deny
               prefixes matching this filter's prefix definition.
        :param str prefix: The IPv4 Prefix to be matched by this filter. If both
               the `le` and `ge` are zero, then this filter will only apply to routes that
               exactly match this prefix, while a non-zero value for either `le` or `ge`,
               this filter can apply to multiple routes with different prefix lengths, but
               will still only apply to prefixes contained in the address space defined by
               `prefix`.
        :param str before: (optional) A reference to the prefix filter that will be
               the next filter applied to the Transit Gateway connection.
               If this field is blank, this prefix filter will be the last rule applied
               before the connection's default rule.
               When a prefix filter is created with the same before field as an existing
               prefix filter, the existing filter will be applied before the new filter,
               and the existing filter's before field will be updated accordingly.
        :param int ge: (optional) Defines the minimum matched prefix precision. If
               this field is non-zero then the filter will match all routes within the
               `prefix` that have a prefix length greater than or equal to this value.
               This value can be zero, or a non-negative number greater than or equal to
               the prefix length of the filter's prefix or less then or equal to 32. If
               this value is set to zero, the filter will not use the `ge` route matching
               behavior. If the `le` value is non-zero the the `ge` value must between the
               prefix length and the
               `le` value, inclusive.
        :param int le: (optional) Defines the maximum matched prefix precision. If
               this field is non-zero then the filter will match all routes within the
               `prefix` that have a prefix length less than or equal to this value.
               This value can be zero, or a non-negative number greater than or equal to
               the prefix length of the filter's prefix or less then or equal to 32. If
               this value is set to zero, the filter will not use the `le` route matching
               behavior. If the `ge` value is non-zero the the `le` value must between the
               `ge` value and 32, inclusive.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PrefixFilterCust` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('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_transit_gateway_connection_prefix_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 = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/prefix_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 delete_transit_gateway_connection_prefix_filter(
        self,
        transit_gateway_id: str,
        id: str,
        filter_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Remove prefix filter from Transit Gateway connection.

        Delete a prefix filter.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str filter_id: Prefix filter 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 transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not filter_id:
            raise ValueError('filter_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='delete_transit_gateway_connection_prefix_filter',
        )
        headers.update(sdk_headers)

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

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

        path_param_keys = ['transit_gateway_id', 'id', 'filter_id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id, filter_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/prefix_filters/{filter_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_transit_gateway_connection_prefix_filter(
        self,
        transit_gateway_id: str,
        id: str,
        filter_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves specified Transit Gateway connection prefix filter.

        This request retrieves a prefix filter from the Transit Gateway connection.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str filter_id: Prefix filter identifier.
        :param dict headers: A `dict` containing the request headers
        :return: A `DetailedResponse` containing the result, headers and HTTP status code.
        :rtype: DetailedResponse with `dict` result representing a `PrefixFilterCust` object
        """

        if not transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        if not id:
            raise ValueError('id must be provided')
        if not filter_id:
            raise ValueError('filter_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='get_transit_gateway_connection_prefix_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 = ['transit_gateway_id', 'id', 'filter_id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id, filter_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/prefix_filters/{filter_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_transit_gateway_connection_prefix_filter(
        self,
        transit_gateway_id: str,
        id: str,
        filter_id: str,
        *,
        action: Optional[str] = None,
        before: Optional[str] = None,
        ge: Optional[int] = None,
        le: Optional[int] = None,
        prefix: Optional[str] = None,
        **kwargs,
    ) -> DetailedResponse:
        """
        Updates specified Transit Gateway connection prefix filter.

        Update prefix filter for a Transit Gateway Connection.

        :param str transit_gateway_id: The Transit Gateway identifier.
        :param str id: The connection identifier.
        :param str filter_id: Prefix filter identifier.
        :param str action: (optional) Whether or not this prefix filter should
               allow or deny prefixes matching this filter's prefix definition.
        :param str before: (optional) A reference to the prefix filter that will be
               the next filter applied to the Transit Gateway connection.
               If this field is blank, this prefix filter will be the last rule applied
               before the connection's default rule.
               When a prefix filter is created with the same before field as an existing
               prefix filter, the existing filter will be applied before the new filter,
               and the existing filter's before field will be updated accordingly.
        :param int ge: (optional) Defines the minimum matched prefix precision. If
               this field is non-zero then the filter will match all routes within the
               `prefix` that have a prefix length greater or equal to this value.
               This value can be zero, or a non-negative number greater than or equal to
               the prefix length of the filter's prefix or less then or equal to 32. If
               this value is set to zero, the filter will not use the `ge` route matching
               behavior. If the `le` value is non-zero the the `ge` value must between the
               prefix length and the
               `le` value, inclusive.
        :param int le: (optional) Defines the maximum matched prefix precision. If
               this field is non-zero then the filter will match all routes within the
               `prefix` that have a prefix length less than or equal to this value.
               This value can be zero, or a non-negative number greater than or equal to
               the prefix length of the filter's prefix or less then or equal to 32. If
               this value is set to zero, the filter will not use the `le` route matching
               behavior. If the `ge` value is non-zero the the `le` value must between the
               `ge` value and 32, inclusive.
        :param str prefix: (optional) The IPv4 Prefix to be matched by this 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 `PrefixFilterCust` object
        """

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

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

        data = {
            'action': action,
            'before': before,
            'ge': ge,
            'le': le,
            'prefix': prefix,
        }
        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 = ['transit_gateway_id', 'id', 'filter_id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id, filter_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_gateway_id}/connections/{id}/prefix_filters/{filter_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

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

    def list_transit_gateway_route_reports(
        self,
        transit_gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Lists route reports.

        Retrieve all route reports for the specified Transit Gateway.  There will normally
        be at most one completed report and one pending report.  Additionally, completed
        route reports are written to IBM Cloud Activity Tracker.

        :param str transit_gateway_id: The Transit 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 transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='list_transit_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 = ['transit_gateway_id']
        path_param_values = self.encode_path_vars(transit_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_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_transit_gateway_route_report(
        self,
        transit_gateway_id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Requests 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.

        :param str transit_gateway_id: The Transit 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 transit_gateway_id:
            raise ValueError('transit_gateway_id must be provided')
        headers = {}
        sdk_headers = get_sdk_headers(
            service_name=self.DEFAULT_SERVICE_NAME,
            service_version='V1',
            operation_id='create_transit_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 = ['transit_gateway_id']
        path_param_values = self.encode_path_vars(transit_gateway_id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_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_transit_gateway_route_report(
        self,
        transit_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Deletes a route report.

        Delete a route report.

        :param str transit_gateway_id: The Transit 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 transit_gateway_id:
            raise ValueError('transit_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_transit_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 = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_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_transit_gateway_route_report(
        self,
        transit_gateway_id: str,
        id: str,
        **kwargs,
    ) -> DetailedResponse:
        """
        Retrieves a route report.

        Retrieve a route report.

        :param str transit_gateway_id: The Transit 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 transit_gateway_id:
            raise ValueError('transit_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_transit_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 = ['transit_gateway_id', 'id']
        path_param_values = self.encode_path_vars(transit_gateway_id, id)
        path_param_dict = dict(zip(path_param_keys, path_param_values))
        url = '/transit_gateways/{transit_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


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


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

    :param str href: url.
    """

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

        :param str href: url.
        """
        self.href = href

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

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

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

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

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

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

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


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

    :param str href: url.
    """

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

        :param str href: url.
        """
        self.href = href

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

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

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

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

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

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

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


class PaginationFirstTGWConnection:
    """
    A reference to the first page of resources. This will be returned when number of
    connections in response are greater than max page limit.

    :param str href: url.
    """

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

        :param str href: url.
        """
        self.href = href

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

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

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

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

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

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

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


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

    :param str href: url.
    :param str start: server generated start token for next page of resources.
    """

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

        :param str href: url.
        :param str start: server generated start token for next page of resources.
        """
        self.href = href
        self.start = start

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

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

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

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

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


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

    :param str href: url.
    :param str start: server generated start token for next page of resources.
    """

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

        :param str href: url.
        :param str start: server generated start token for next page of resources.
        """
        self.href = href
        self.start = start

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

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

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

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

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


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

    :param str href: url.
    :param str start: server generated start token for next page of resources.
    """

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

        :param str href: url.
        :param str start: server generated start token for next page of resources.
        """
        self.href = href
        self.start = start

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

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

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

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

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


class PrefixFilterCollection:
    """
    prefix filters.

    :param List[PrefixFilterCust] prefix_filters: Array of prefix filters.
    """

    def __init__(
        self,
        prefix_filters: List['PrefixFilterCust'],
    ) -> None:
        """
        Initialize a PrefixFilterCollection object.

        :param List[PrefixFilterCust] prefix_filters: Array of prefix filters.
        """
        self.prefix_filters = prefix_filters

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

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

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

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


class PrefixFilterCust:
    """
    prefix filter.

    :param str action: Whether or not this prefix filter should allow or deny
          prefixes matching this filter's prefix definition.
    :param str before: (optional) A reference to the prefix filter that will be the
          next filter applied to the Transit Gateway connection.
          If this field is blank, this prefix filter will be the last rule applied before
          the connection's default rule.
          When a prefix filter is created with the same before field as an existing prefix
          filter, the existing filter will be applied before the new filter, and the
          existing filter's before field will be updated accordingly.
    :param datetime created_at: The date and time that this prefix filter was
          created.
    :param int ge: (optional) Defines the minimum matched prefix precision. If this
          field is non-zero then the filter will match all routes within the `prefix` that
          have a prefix length greater or equal to this value.
          This value can be zero, or a non-negative number greater than or equal to the
          prefix length of the filter's prefix or less then or equal to 32. If this value
          is set to zero, the filter will not use the `ge` route matching behavior. If the
          `le` value is non-zero the the `ge` value must between the prefix length and the
          `le` value, inclusive.
    :param str id: Prefix Filter identifier.
    :param int le: (optional) Defines the maximum matched prefix precision. If this
          field is non-zero then the filter will match all routes within the `prefix` that
          have a prefix length less than or equal to this value.
          This value can be zero, or a non-negative number greater than or equal to the
          prefix length of the filter's prefix or less then or equal to 32. If this value
          is set to zero, the filter will not use the `le` route matching behavior. If the
          `ge` value is non-zero the the `le` value must between the `ge` value and 32,
          inclusive.
    :param str prefix: The IPv4 Prefix to be matched by this filter. If both the
          `le` and `ge` are zero, then this filter will only apply to routes that exactly
          match this prefix, while a non-zero value for either `le` or `ge`, this filter
          can apply to multiple routes with different prefix lengths, but will still only
          apply to prefixes contained in the address space defined by `prefix`.
    :param datetime updated_at: (optional) The date and time that this prefix filter
          was last updated.
    """

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

        :param str action: Whether or not this prefix filter should allow or deny
               prefixes matching this filter's prefix definition.
        :param datetime created_at: The date and time that this prefix filter was
               created.
        :param str id: Prefix Filter identifier.
        :param str prefix: The IPv4 Prefix to be matched by this filter. If both
               the `le` and `ge` are zero, then this filter will only apply to routes that
               exactly match this prefix, while a non-zero value for either `le` or `ge`,
               this filter can apply to multiple routes with different prefix lengths, but
               will still only apply to prefixes contained in the address space defined by
               `prefix`.
        :param str before: (optional) A reference to the prefix filter that will be
               the next filter applied to the Transit Gateway connection.
               If this field is blank, this prefix filter will be the last rule applied
               before the connection's default rule.
               When a prefix filter is created with the same before field as an existing
               prefix filter, the existing filter will be applied before the new filter,
               and the existing filter's before field will be updated accordingly.
        :param int ge: (optional) Defines the minimum matched prefix precision. If
               this field is non-zero then the filter will match all routes within the
               `prefix` that have a prefix length greater or equal to this value.
               This value can be zero, or a non-negative number greater than or equal to
               the prefix length of the filter's prefix or less then or equal to 32. If
               this value is set to zero, the filter will not use the `ge` route matching
               behavior. If the `le` value is non-zero the the `ge` value must between the
               prefix length and the
               `le` value, inclusive.
        :param int le: (optional) Defines the maximum matched prefix precision. If
               this field is non-zero then the filter will match all routes within the
               `prefix` that have a prefix length less than or equal to this value.
               This value can be zero, or a non-negative number greater than or equal to
               the prefix length of the filter's prefix or less then or equal to 32. If
               this value is set to zero, the filter will not use the `le` route matching
               behavior. If the `ge` value is non-zero the the `le` value must between the
               `ge` value and 32, inclusive.
        :param datetime updated_at: (optional) The date and time that this prefix
               filter was last updated.
        """
        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) -> 'PrefixFilterCust':
        """Initialize a PrefixFilterCust 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 PrefixFilterCust 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 PrefixFilterCust 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 PrefixFilterCust 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 PrefixFilterCust JSON')
        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 PrefixFilterCust object from 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 PrefixFilterCust object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class ActionEnum(str, Enum):
        """
        Whether or not this prefix filter should allow or deny prefixes matching this
        filter's prefix definition.
        """

        PERMIT = 'permit'
        DENY = 'deny'



class ResourceGroupIdentity:
    """
    The resource group to use. If unspecified, the account's [default resource
    group](https://console.bluemix.net/apidocs/resource-manager#introduction) is used.

    :param str id: The unique identifier for this resource group.
    """

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

        :param str id: The unique identifier for this resource group.
        """
        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:
    """
    The resource group to use. If unspecified, the account's [default resource
    group](https://console.bluemix.net/apidocs/resource-manager#introduction) is used.

    :param str href: The URL for this resource group.
    :param str id: The unique identifier for this resource group.
    """

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

        :param str href: The URL for this resource group.
        :param str id: The unique identifier for this resource group.
        """
        self.href = href
        self.id = id

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

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

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

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

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

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

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


class RouteReport:
    """
    route report.

    :param List[RouteReportConnection] connections: Array of connections with their
          routes.
    :param datetime created_at: Date and time route report was requested.
    :param str id: Report identifier.
    :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.
    """

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

        :param List[RouteReportConnection] connections: Array of connections with
               their routes.
        :param datetime created_at: Date and time route report was requested.
        :param str id: Report identifier.
        :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.
        """
        self.connections = connections
        self.created_at = created_at
        self.id = id
        self.overlapping_routes = overlapping_routes
        self.status = status
        self.updated_at = updated_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteReport':
        """Initialize a RouteReport object from a json dictionary."""
        args = {}
        if (connections := _dict.get('connections')) is not None:
            args['connections'] = [RouteReportConnection.from_dict(v) for v in connections]
        else:
            raise ValueError('Required property \'connections\' not present in RouteReport 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 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 (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)
        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, 'connections') and self.connections is not None:
            connections_list = []
            for v in self.connections:
                if isinstance(v, dict):
                    connections_list.append(v)
                else:
                    connections_list.append(v.to_dict())
            _dict['connections'] = connections_list
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        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)
        return _dict

    def _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'
        FAILED = 'failed'



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:
    """
    route report connection.

    :param List[RouteReportConnectionBgp] bgps: (optional) Array of connection's
          bgps.
    :param str id: (optional) connection ID.
    :param str name: (optional) connection name.
    :param List[RouteReportConnectionRoute] routes: (optional) Array of connection's
          routes.
    :param str type: (optional) connection type.
    """

    def __init__(
        self,
        *,
        bgps: Optional[List['RouteReportConnectionBgp']] = None,
        id: Optional[str] = None,
        name: Optional[str] = None,
        routes: Optional[List['RouteReportConnectionRoute']] = None,
        type: Optional[str] = None,
    ) -> None:
        """
        Initialize a RouteReportConnection object.

        :param List[RouteReportConnectionBgp] bgps: (optional) Array of
               connection's bgps.
        :param str id: (optional) connection ID.
        :param str name: (optional) connection name.
        :param List[RouteReportConnectionRoute] routes: (optional) Array of
               connection's routes.
        :param str type: (optional) connection type.
        """
        self.bgps = bgps
        self.id = id
        self.name = name
        self.routes = routes
        self.type = type

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'RouteReportConnection':
        """Initialize a RouteReportConnection object from a json dictionary."""
        args = {}
        if (bgps := _dict.get('bgps')) is not None:
            args['bgps'] = [RouteReportConnectionBgp.from_dict(v) for v in bgps]
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (routes := _dict.get('routes')) is not None:
            args['routes'] = [RouteReportConnectionRoute.from_dict(v) for v in routes]
        if (type := _dict.get('type')) is not None:
            args['type'] = 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, 'bgps') and self.bgps is not None:
            bgps_list = []
            for v in self.bgps:
                if isinstance(v, dict):
                    bgps_list.append(v)
                else:
                    bgps_list.append(v.to_dict())
            _dict['bgps'] = bgps_list
        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, '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, '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 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 RouteReportConnectionBgp:
    """
    connection bgp details.

    :param str as_path: (optional) AS path.
    :param bool is_used: Indicates whether current route is used or not.
    :param str local_preference: (optional) local preference.
    :param str prefix: (optional) prefix.
    """

    def __init__(
        self,
        is_used: bool,
        *,
        as_path: Optional[str] = None,
        local_preference: Optional[str] = None,
        prefix: Optional[str] = None,
    ) -> None:
        """
        Initialize a RouteReportConnectionBgp object.

        :param bool is_used: Indicates whether current route is used or not.
        :param str as_path: (optional) AS path.
        :param str local_preference: (optional) local preference.
        :param str prefix: (optional) prefix.
        """
        self.as_path = as_path
        self.is_used = is_used
        self.local_preference = local_preference
        self.prefix = prefix

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

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

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

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


class RouteReportConnectionRoute:
    """
    connection used route.

    :param str prefix: (optional) prefix.
    """

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

        :param str prefix: (optional) prefix.
        """
        self.prefix = prefix

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

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

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


class RouteReportOverlappingRoute:
    """
    overlapping route details.

    :param str connection_id: (optional) connection ID.
    :param str prefix: (optional) overlapping prefix.
    """

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

        :param str connection_id: (optional) connection ID.
        :param str prefix: (optional) overlapping prefix.
        """
        self.connection_id = connection_id
        self.prefix = prefix

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

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

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

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

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


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'] = [RouteReportOverlappingRoute.from_dict(v) for v in 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 TSCollection:
    """
    A list of Transit Gateway locations.

    :param List[TSLocationBasic] locations: Collection of Transit Gateway locations.
    """

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

        :param List[TSLocationBasic] locations: Collection of Transit Gateway
               locations.
        """
        self.locations = locations

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

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

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

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


class TSLocalLocation:
    """
    Details of a local connection location.

    :param str display_name: A descriptive display name for the location.
    :param str name: The name of the location.
    :param List[str] supported_connection_types: (optional) Array of supported
          connection types.
    :param str type: The type of the location, determining is this a multi-zone
          region, a single data center, or a point of presence. 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,
        display_name: str,
        name: str,
        type: str,
        *,
        supported_connection_types: Optional[List[str]] = None,
    ) -> None:
        """
        Initialize a TSLocalLocation object.

        :param str display_name: A descriptive display name for the location.
        :param str name: The name of the location.
        :param str type: The type of the location, determining is this a multi-zone
               region, a single data center, or a point of presence. 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[str] supported_connection_types: (optional) Array of supported
               connection types.
        """
        self.display_name = display_name
        self.name = name
        self.supported_connection_types = supported_connection_types
        self.type = type

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

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

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

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

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

    class TypeEnum(str, Enum):
        """
        The type of the location, determining is this a multi-zone region, a single data
        center, or a point of presence. The list of enumerated values for this property
        may expand in the future. Code and processes using this field must tolerate
        unexpected values.
        """

        REGION = 'region'
        DC = 'dc'



class TSLocation:
    """
    Details of a Transit Gateway location.

    :param str billing_location: The geographical location of this location, used
          for billing purposes.
    :param str name: Name of the Location.
    :param str type: The type of the location, determining is this a multi-zone
          region, a single data center, or a point of presence.
    :param List[TSLocalLocation] local_connection_locations: The set of network
          locations that are considered local for this Transit Gateway location.
    :param List[ZoneReference] zones: List of valid zones for GRE tunnels.
    """

    def __init__(
        self,
        billing_location: str,
        name: str,
        type: str,
        local_connection_locations: List['TSLocalLocation'],
        zones: List['ZoneReference'],
    ) -> None:
        """
        Initialize a TSLocation object.

        :param str billing_location: The geographical location of this location,
               used for billing purposes.
        :param str name: Name of the Location.
        :param str type: The type of the location, determining is this a multi-zone
               region, a single data center, or a point of presence.
        :param List[TSLocalLocation] local_connection_locations: The set of network
               locations that are considered local for this Transit Gateway location.
        :param List[ZoneReference] zones: List of valid zones for GRE tunnels.
        """
        self.billing_location = billing_location
        self.name = name
        self.type = type
        self.local_connection_locations = local_connection_locations
        self.zones = zones

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

    @classmethod
    def _from_dict(cls, _dict):
        """Initialize a TSLocation object from 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, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'type') and self.type is not None:
            _dict['type'] = self.type
        if hasattr(self, 'local_connection_locations') and self.local_connection_locations is not None:
            local_connection_locations_list = []
            for v in self.local_connection_locations:
                if isinstance(v, dict):
                    local_connection_locations_list.append(v)
                else:
                    local_connection_locations_list.append(v.to_dict())
            _dict['local_connection_locations'] = local_connection_locations_list
        if hasattr(self, 'zones') and self.zones is not None:
            zones_list = []
            for v in self.zones:
                if isinstance(v, dict):
                    zones_list.append(v)
                else:
                    zones_list.append(v.to_dict())
            _dict['zones'] = zones_list
        return _dict

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

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

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

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


class TSLocationBasic:
    """
    Details of a Transit Gateway location.

    :param str billing_location: The geographical location of this location, used
          for billing purposes.
    :param str name: Name of the Location.
    :param str type: The type of the location, determining is this a multi-zone
          region, a single data center, or a point of presence.
    """

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

        :param str billing_location: The geographical location of this location,
               used for billing purposes.
        :param str name: Name of the Location.
        :param str type: The type of the location, determining is this a multi-zone
               region, a single data center, or a point of presence.
        """
        self.billing_location = billing_location
        self.name = name
        self.type = type

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

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

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

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

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

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


class TransitConnection:
    """
    Connection included in transit gateway.

    :param str base_network_type: (optional) The type of network the GRE tunnel is
          targeting.
    :param str name: The user-defined name for this transit gateway connection.
    :param str network_id: (optional) The ID of the network being connected via this
          connection. This field is required for some types, such as `vpc`,
          `power_virtual_server`, `directlink`, `vpn_gateway` and `redundant_gre`. For
          network types `vpc`, `redundant_gre`, `power_virtual_server` and `directlink`
          this is the CRN of the VPC  / PowerVS / VDC / Direct Link gateway respectively.
    :param str network_type: Defines what type of network is connected via this
          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 id: The unique identifier for this Transit Gateway connection.
    :param str base_connection_id: (optional) Deprecated: network_type `gre_tunnel`
          connections use `base_connection_id` to specify the ID of a network_type
          `classic` connection the tunnel is configured over. The specified connection
          must reside in the same transit gateway and be in an active state. The `classic`
          connection cannot be deleted until any `gre_tunnel` connections using it are
          deleted. This field only applies to and is required for network type
          `gre_tunnel` connections.
    :param datetime created_at: The date and time that this connection was created.
    :param int local_bgp_asn: (optional) Local network BGP ASN.  This field only
          applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str local_gateway_ip: (optional) Local gateway IP address.  This field
          only applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str local_tunnel_ip: (optional) Local tunnel IP address.  This field only
          applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param int mtu: (optional) GRE tunnel MTU.  This field only applies to network
          type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str network_account_id: (optional) The ID of the account which owns the
          connected network. Generally only used if the network is in a different IBM
          Cloud account than the gateway.
    :param List[TransitGatewayConnectionPrefixFilterReference] prefix_filters:
          (optional) Array of prefix route filters for a transit gateway connection. This
          is order dependent with those first in the array being applied first, and those
          at the end of the array is applied last, or just before the default.
          This field does not apply to the `redundant_gre` network types.
    :param str prefix_filters_default: (optional) Default setting of permit or deny
          which applies to any routes that don't match a specified filter.
          This field does not apply to the `redundant_gre` network types.
    :param int remote_bgp_asn: (optional) Remote network BGP ASN.  This field only
          applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str remote_gateway_ip: (optional) Remote gateway IP address.  This field
          only applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str remote_tunnel_ip: (optional) Remote tunnel IP address.  This field
          only applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str request_status: Only visible for cross account connections, this
          field represents the status of a connection request between IBM Cloud accounts.
          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 status: Connection's current configuration state. The list of
          enumerated values for this property may expand in the future. Code and processes
          using this field must tolerate unexpected values.
    :param TransitGatewayReference transit_gateway: Transit gateway reference.
    :param List[TransitGatewayTunnel] tunnels: (optional) Collection of all tunnels
          for `redundant_gre` and `vpn_gateway` connections.
    :param datetime updated_at: The date and time that this connection was last
          updated.
    :param ZoneReference zone: (optional) Availability zone reference.
    """

    def __init__(
        self,
        name: str,
        network_type: str,
        id: str,
        created_at: datetime,
        request_status: str,
        status: str,
        transit_gateway: 'TransitGatewayReference',
        updated_at: datetime,
        *,
        base_network_type: Optional[str] = None,
        network_id: Optional[str] = None,
        base_connection_id: Optional[str] = None,
        local_bgp_asn: Optional[int] = None,
        local_gateway_ip: Optional[str] = None,
        local_tunnel_ip: Optional[str] = None,
        mtu: Optional[int] = None,
        network_account_id: Optional[str] = None,
        prefix_filters: Optional[List['TransitGatewayConnectionPrefixFilterReference']] = None,
        prefix_filters_default: Optional[str] = None,
        remote_bgp_asn: Optional[int] = None,
        remote_gateway_ip: Optional[str] = None,
        remote_tunnel_ip: Optional[str] = None,
        tunnels: Optional[List['TransitGatewayTunnel']] = None,
        zone: Optional['ZoneReference'] = None,
    ) -> None:
        """
        Initialize a TransitConnection object.

        :param str name: The user-defined name for this transit gateway connection.
        :param str network_type: Defines what type of network is connected via this
               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 id: The unique identifier for this Transit Gateway connection.
        :param datetime created_at: The date and time that this connection was
               created.
        :param str request_status: Only visible for cross account connections, this
               field represents the status of a connection request between IBM Cloud
               accounts. 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 status: Connection's current configuration state. The list of
               enumerated values for this property may expand in the future. Code and
               processes using this field must tolerate unexpected values.
        :param TransitGatewayReference transit_gateway: Transit gateway reference.
        :param datetime updated_at: The date and time that this connection was last
               updated.
        :param str base_network_type: (optional) The type of network the GRE tunnel
               is targeting.
        :param str network_id: (optional) The ID of the network being connected via
               this connection. This field is required for some types, such as `vpc`,
               `power_virtual_server`, `directlink`, `vpn_gateway` and `redundant_gre`.
               For network types `vpc`, `redundant_gre`, `power_virtual_server` and
               `directlink` this is the CRN of the VPC  / PowerVS / VDC / Direct Link
               gateway respectively.
        :param str base_connection_id: (optional) Deprecated: network_type
               `gre_tunnel` connections use `base_connection_id` to specify the ID of a
               network_type `classic` connection the tunnel is configured over. The
               specified connection must reside in the same transit gateway and be in an
               active state. The `classic` connection cannot be deleted until any
               `gre_tunnel` connections using it are deleted. This field only applies to
               and is required for network type `gre_tunnel` connections.
        :param int local_bgp_asn: (optional) Local network BGP ASN.  This field
               only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str local_gateway_ip: (optional) Local gateway IP address.  This
               field only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str local_tunnel_ip: (optional) Local tunnel IP address.  This field
               only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param int mtu: (optional) GRE tunnel MTU.  This field only applies to
               network type `gre_tunnel` and `unbound_gre_tunnel` connections.
        :param str network_account_id: (optional) The ID of the account which owns
               the connected network. Generally only used if the network is in a different
               IBM Cloud account than the gateway.
        :param List[TransitGatewayConnectionPrefixFilterReference] prefix_filters:
               (optional) Array of prefix route filters for a transit gateway connection.
               This is order dependent with those first in the array being applied first,
               and those at the end of the array is applied last, or just before the
               default.
               This field does not apply to the `redundant_gre` network types.
        :param str prefix_filters_default: (optional) Default setting of permit or
               deny which applies to any routes that don't match a specified filter.
               This field does not apply to the `redundant_gre` network types.
        :param int remote_bgp_asn: (optional) Remote network BGP ASN.  This field
               only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str remote_gateway_ip: (optional) Remote gateway IP address.  This
               field only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str remote_tunnel_ip: (optional) Remote tunnel IP address.  This
               field only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param List[TransitGatewayTunnel] tunnels: (optional) Collection of all
               tunnels for `redundant_gre` and `vpn_gateway` connections.
        :param ZoneReference zone: (optional) Availability zone reference.
        """
        self.base_network_type = base_network_type
        self.name = name
        self.network_id = network_id
        self.network_type = network_type
        self.id = id
        self.base_connection_id = base_connection_id
        self.created_at = created_at
        self.local_bgp_asn = local_bgp_asn
        self.local_gateway_ip = local_gateway_ip
        self.local_tunnel_ip = local_tunnel_ip
        self.mtu = mtu
        self.network_account_id = network_account_id
        self.prefix_filters = prefix_filters
        self.prefix_filters_default = prefix_filters_default
        self.remote_bgp_asn = remote_bgp_asn
        self.remote_gateway_ip = remote_gateway_ip
        self.remote_tunnel_ip = remote_tunnel_ip
        self.request_status = request_status
        self.status = status
        self.transit_gateway = transit_gateway
        self.tunnels = tunnels
        self.updated_at = updated_at
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'TransitConnection':
        """Initialize a TransitConnection object from a json dictionary."""
        args = {}
        if (base_network_type := _dict.get('base_network_type')) is not None:
            args['base_network_type'] = base_network_type
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in TransitConnection JSON')
        if (network_id := _dict.get('network_id')) is not None:
            args['network_id'] = network_id
        if (network_type := _dict.get('network_type')) is not None:
            args['network_type'] = network_type
        else:
            raise ValueError('Required property \'network_type\' not present in TransitConnection JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in TransitConnection JSON')
        if (base_connection_id := _dict.get('base_connection_id')) is not None:
            args['base_connection_id'] = base_connection_id
        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 TransitConnection JSON')
        if (local_bgp_asn := _dict.get('local_bgp_asn')) is not None:
            args['local_bgp_asn'] = local_bgp_asn
        if (local_gateway_ip := _dict.get('local_gateway_ip')) is not None:
            args['local_gateway_ip'] = local_gateway_ip
        if (local_tunnel_ip := _dict.get('local_tunnel_ip')) is not None:
            args['local_tunnel_ip'] = local_tunnel_ip
        if (mtu := _dict.get('mtu')) is not None:
            args['mtu'] = mtu
        if (network_account_id := _dict.get('network_account_id')) is not None:
            args['network_account_id'] = network_account_id
        if (prefix_filters := _dict.get('prefix_filters')) is not None:
            args['prefix_filters'] = [TransitGatewayConnectionPrefixFilterReference.from_dict(v) for v in prefix_filters]
        if (prefix_filters_default := _dict.get('prefix_filters_default')) is not None:
            args['prefix_filters_default'] = prefix_filters_default
        if (remote_bgp_asn := _dict.get('remote_bgp_asn')) is not None:
            args['remote_bgp_asn'] = remote_bgp_asn
        if (remote_gateway_ip := _dict.get('remote_gateway_ip')) is not None:
            args['remote_gateway_ip'] = remote_gateway_ip
        if (remote_tunnel_ip := _dict.get('remote_tunnel_ip')) is not None:
            args['remote_tunnel_ip'] = remote_tunnel_ip
        if (request_status := _dict.get('request_status')) is not None:
            args['request_status'] = request_status
        else:
            raise ValueError('Required property \'request_status\' not present in TransitConnection JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in TransitConnection JSON')
        if (transit_gateway := _dict.get('transit_gateway')) is not None:
            args['transit_gateway'] = TransitGatewayReference.from_dict(transit_gateway)
        else:
            raise ValueError('Required property \'transit_gateway\' not present in TransitConnection JSON')
        if (tunnels := _dict.get('tunnels')) is not None:
            args['tunnels'] = [TransitGatewayTunnel.from_dict(v) for v in tunnels]
        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 TransitConnection JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(zone)
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'base_network_type') and self.base_network_type is not None:
            _dict['base_network_type'] = self.base_network_type
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_id') and self.network_id is not None:
            _dict['network_id'] = self.network_id
        if hasattr(self, 'network_type') and self.network_type is not None:
            _dict['network_type'] = self.network_type
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'base_connection_id') and self.base_connection_id is not None:
            _dict['base_connection_id'] = self.base_connection_id
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'local_bgp_asn') and self.local_bgp_asn is not None:
            _dict['local_bgp_asn'] = self.local_bgp_asn
        if hasattr(self, 'local_gateway_ip') and self.local_gateway_ip is not None:
            _dict['local_gateway_ip'] = self.local_gateway_ip
        if hasattr(self, 'local_tunnel_ip') and self.local_tunnel_ip is not None:
            _dict['local_tunnel_ip'] = self.local_tunnel_ip
        if hasattr(self, 'mtu') and self.mtu is not None:
            _dict['mtu'] = self.mtu
        if hasattr(self, 'network_account_id') and self.network_account_id is not None:
            _dict['network_account_id'] = self.network_account_id
        if hasattr(self, 'prefix_filters') and self.prefix_filters is not None:
            prefix_filters_list = []
            for v in self.prefix_filters:
                if isinstance(v, dict):
                    prefix_filters_list.append(v)
                else:
                    prefix_filters_list.append(v.to_dict())
            _dict['prefix_filters'] = prefix_filters_list
        if hasattr(self, 'prefix_filters_default') and self.prefix_filters_default is not None:
            _dict['prefix_filters_default'] = self.prefix_filters_default
        if hasattr(self, 'remote_bgp_asn') and self.remote_bgp_asn is not None:
            _dict['remote_bgp_asn'] = self.remote_bgp_asn
        if hasattr(self, 'remote_gateway_ip') and self.remote_gateway_ip is not None:
            _dict['remote_gateway_ip'] = self.remote_gateway_ip
        if hasattr(self, 'remote_tunnel_ip') and self.remote_tunnel_ip is not None:
            _dict['remote_tunnel_ip'] = self.remote_tunnel_ip
        if hasattr(self, 'request_status') and self.request_status is not None:
            _dict['request_status'] = self.request_status
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'transit_gateway') and self.transit_gateway is not None:
            if isinstance(self.transit_gateway, dict):
                _dict['transit_gateway'] = self.transit_gateway
            else:
                _dict['transit_gateway'] = self.transit_gateway.to_dict()
        if hasattr(self, 'tunnels') and self.tunnels is not None:
            tunnels_list = []
            for v in self.tunnels:
                if isinstance(v, dict):
                    tunnels_list.append(v)
                else:
                    tunnels_list.append(v.to_dict())
            _dict['tunnels'] = tunnels_list
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

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

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

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

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

    class BaseNetworkTypeEnum(str, Enum):
        """
        The type of network the GRE tunnel is targeting.
        """

        CLASSIC = 'classic'
        VPC = 'vpc'
        VPN = 'vpn'


    class NetworkTypeEnum(str, Enum):
        """
        Defines what type of network is connected via this connection. 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'
        DIRECTLINK = 'directlink'
        GRE_TUNNEL = 'gre_tunnel'
        UNBOUND_GRE_TUNNEL = 'unbound_gre_tunnel'
        VPC = 'vpc'
        POWER_VIRTUAL_SERVER = 'power_virtual_server'
        REDUNDANT_GRE = 'redundant_gre'
        VPN_GATEWAY = 'vpn_gateway'


    class PrefixFiltersDefaultEnum(str, Enum):
        """
        Default setting of permit or deny which applies to any routes that don't match a
        specified filter.
        This field does not apply to the `redundant_gre` network types.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class RequestStatusEnum(str, Enum):
        """
        Only visible for cross account connections, this field represents the status of a
        connection request between IBM Cloud accounts. 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'
        APPROVED = 'approved'
        REJECTED = 'rejected'
        EXPIRED = 'expired'
        DETACHED = 'detached'


    class StatusEnum(str, Enum):
        """
        Connection's current configuration state. The list of enumerated values for this
        property may expand in the future. Code and processes using this field must
        tolerate unexpected values.
        """

        ATTACHED = 'attached'
        FAILED = 'failed'
        PENDING = 'pending'
        NETWORK_PENDING = 'network_pending'
        DELETING = 'deleting'
        DETACHING = 'detaching'
        DETACHED = 'detached'
        SUSPENDING = 'suspending'
        SUSPENDED = 'suspended'



class TransitConnectionCollection:
    """
    Transit gateway connections.

    :param List[TransitConnection] connections: Array of transit gateway
          connections.
    :param PaginationFirstConnection first: A reference to the first page of
          resources.
    :param int limit: The maximum number of connections returned on one request.
    :param PaginationNextConnection next: (optional) A reference to the next page of
          resources; this reference is included for all pages except the last page.
    """

    def __init__(
        self,
        connections: List['TransitConnection'],
        first: 'PaginationFirstConnection',
        limit: int,
        *,
        next: Optional['PaginationNextConnection'] = None,
    ) -> None:
        """
        Initialize a TransitConnectionCollection object.

        :param List[TransitConnection] connections: Array of transit gateway
               connections.
        :param PaginationFirstConnection first: A reference to the first page of
               resources.
        :param int limit: The maximum number of connections returned on one
               request.
        :param PaginationNextConnection next: (optional) A reference to the next
               page of resources; this reference is included for all pages except the last
               page.
        """
        self.connections = connections
        self.first = first
        self.limit = limit
        self.next = next

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

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

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

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

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

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

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


class TransitGateway:
    """
    Details of a Transit Gateway.

    :param int connection_count: (optional) The number of connections associated
          with this Transit Gateway.
    :param bool connection_needs_attention: Indicates if this Transit Gateway has a
          connection that needs attention (Such as cross account approval).
    :param datetime created_at: The date and time that this gateway was created.
    :param str crn: (optional) Cloud Resource Name of a transit gateway.
    :param bool global_: Allow global routing for a Transit Gateway.
    :param bool gre_enhanced_route_propagation: Allow route propagation across all
          GREs connected to the same transit gateway. This affects connections on the
          gateway of type `redundant_gre`, `unbound_gre_tunnel` and `gre_tunnel`.
    :param str id: A unique identifier for this transit gateway.
    :param str location: Location of Transit Gateway Services.
    :param str name: A human readable name for the transit gateway.
    :param ResourceGroupReference resource_group: (optional) The resource group to
          use. If unspecified, the account's [default resource
          group](https://console.bluemix.net/apidocs/resource-manager#introduction) is
          used.
    :param str status: The status of the Transit Gateway. 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) The date and time that this gateway was
          last updated.
    """

    def __init__(
        self,
        connection_needs_attention: bool,
        created_at: datetime,
        global_: bool,
        gre_enhanced_route_propagation: bool,
        id: str,
        location: str,
        name: str,
        status: str,
        *,
        connection_count: Optional[int] = None,
        crn: Optional[str] = None,
        resource_group: Optional['ResourceGroupReference'] = None,
        updated_at: Optional[datetime] = None,
    ) -> None:
        """
        Initialize a TransitGateway object.

        :param bool connection_needs_attention: Indicates if this Transit Gateway
               has a connection that needs attention (Such as cross account approval).
        :param datetime created_at: The date and time that this gateway was
               created.
        :param bool global_: Allow global routing for a Transit Gateway.
        :param bool gre_enhanced_route_propagation: Allow route propagation across
               all GREs connected to the same transit gateway. This affects connections on
               the gateway of type `redundant_gre`, `unbound_gre_tunnel` and `gre_tunnel`.
        :param str id: A unique identifier for this transit gateway.
        :param str location: Location of Transit Gateway Services.
        :param str name: A human readable name for the transit gateway.
        :param str status: The status of the Transit Gateway. 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 connection_count: (optional) The number of connections
               associated with this Transit Gateway.
        :param str crn: (optional) Cloud Resource Name of a transit gateway.
        :param ResourceGroupReference resource_group: (optional) The resource group
               to use. If unspecified, the account's [default resource
               group](https://console.bluemix.net/apidocs/resource-manager#introduction)
               is used.
        :param datetime updated_at: (optional) The date and time that this gateway
               was last updated.
        """
        self.connection_count = connection_count
        self.connection_needs_attention = connection_needs_attention
        self.created_at = created_at
        self.crn = crn
        self.global_ = global_
        self.gre_enhanced_route_propagation = gre_enhanced_route_propagation
        self.id = id
        self.location = location
        self.name = name
        self.resource_group = resource_group
        self.status = status
        self.updated_at = updated_at

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'TransitGateway':
        """Initialize a TransitGateway object from a json dictionary."""
        args = {}
        if (connection_count := _dict.get('connection_count')) is not None:
            args['connection_count'] = connection_count
        if (connection_needs_attention := _dict.get('connection_needs_attention')) is not None:
            args['connection_needs_attention'] = connection_needs_attention
        else:
            raise ValueError('Required property \'connection_needs_attention\' not present in TransitGateway 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 TransitGateway JSON')
        if (crn := _dict.get('crn')) is not None:
            args['crn'] = crn
        if (global_ := _dict.get('global')) is not None:
            args['global_'] = global_
        else:
            raise ValueError('Required property \'global\' not present in TransitGateway JSON')
        if (gre_enhanced_route_propagation := _dict.get('gre_enhanced_route_propagation')) is not None:
            args['gre_enhanced_route_propagation'] = gre_enhanced_route_propagation
        else:
            raise ValueError('Required property \'gre_enhanced_route_propagation\' not present in TransitGateway JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in TransitGateway JSON')
        if (location := _dict.get('location')) is not None:
            args['location'] = location
        else:
            raise ValueError('Required property \'location\' not present in TransitGateway JSON')
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in TransitGateway JSON')
        if (resource_group := _dict.get('resource_group')) is not None:
            args['resource_group'] = ResourceGroupReference.from_dict(resource_group)
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in TransitGateway JSON')
        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 TransitGateway object from a json dictionary."""
        return cls.from_dict(_dict)

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'connection_count') and self.connection_count is not None:
            _dict['connection_count'] = self.connection_count
        if hasattr(self, 'connection_needs_attention') and self.connection_needs_attention is not None:
            _dict['connection_needs_attention'] = self.connection_needs_attention
        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, 'global_') and self.global_ is not None:
            _dict['global'] = self.global_
        if hasattr(self, 'gre_enhanced_route_propagation') and self.gre_enhanced_route_propagation is not None:
            _dict['gre_enhanced_route_propagation'] = self.gre_enhanced_route_propagation
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'location') and self.location is not None:
            _dict['location'] = self.location
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'resource_group') and self.resource_group is not None:
            if isinstance(self.resource_group, dict):
                _dict['resource_group'] = self.resource_group
            else:
                _dict['resource_group'] = self.resource_group.to_dict()
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, '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 TransitGateway object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

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

        AVAILABLE = 'available'
        FAILED = 'failed'
        PENDING = 'pending'
        DELETING = 'deleting'
        SUSPENDING = 'suspending'
        SUSPENDED = 'suspended'



class TransitGatewayCollection:
    """
    A list of Transit Gateways.

    :param PaginationFirstTG first: A reference to the first page of resources.
    :param int limit: The maximum number of gateways returned on one request.
    :param PaginationNextTG next: (optional) A reference to the next page of
          resources; this reference is included for all pages except the last page.
    :param List[TransitGateway] transit_gateways: Collection of Transit Services
          gateways.
    """

    def __init__(
        self,
        first: 'PaginationFirstTG',
        limit: int,
        transit_gateways: List['TransitGateway'],
        *,
        next: Optional['PaginationNextTG'] = None,
    ) -> None:
        """
        Initialize a TransitGatewayCollection object.

        :param PaginationFirstTG first: A reference to the first page of resources.
        :param int limit: The maximum number of gateways returned on one request.
        :param List[TransitGateway] transit_gateways: Collection of Transit
               Services gateways.
        :param PaginationNextTG next: (optional) A reference to the next page of
               resources; this reference is included for all pages except the last page.
        """
        self.first = first
        self.limit = limit
        self.next = next
        self.transit_gateways = transit_gateways

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

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

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

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


class TransitGatewayConnectionCollection:
    """
    A set of Transit Gateway network connections.

    :param List[TransitGatewayConnectionCust] connections: Array of transit gateways
          network Connections.
    :param PaginationFirstTGWConnection first: A reference to the first page of
          resources.
          This will be returned when number of connections in response are greater than
          max page limit.
    :param int limit: The maximum number of connections returned on one request.
          This will be returned when number of connections in response are greater than
          max page limit.
    :param PaginationNextTGWConnection 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: total number of resources across all pages (considering
          the supplied query parameter filters).
    """

    def __init__(
        self,
        connections: List['TransitGatewayConnectionCust'],
        first: 'PaginationFirstTGWConnection',
        limit: int,
        total_count: int,
        *,
        next: Optional['PaginationNextTGWConnection'] = None,
    ) -> None:
        """
        Initialize a TransitGatewayConnectionCollection object.

        :param List[TransitGatewayConnectionCust] connections: Array of transit
               gateways network Connections.
        :param PaginationFirstTGWConnection first: A reference to the first page of
               resources.
               This will be returned when number of connections in response are greater
               than max page limit.
        :param int limit: The maximum number of connections returned on one
               request. This will be returned when number of connections in response are
               greater than max page limit.
        :param int total_count: total number of resources across all pages
               (considering the supplied query parameter filters).
        :param PaginationNextTGWConnection next: (optional) A reference to the next
               page of resources; this reference is included for all pages except the last
               page.
        """
        self.connections = connections
        self.first = first
        self.limit = limit
        self.next = next
        self.total_count = total_count

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

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

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

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

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

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

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


class TransitGatewayConnectionCust:
    """
    Connection included in transit gateway.

    :param str base_connection_id: (optional) Deprecated: network_type `gre_tunnel`
          connections use `base_connection_id` to specify the ID of a network_type
          `classic` connection the tunnel is configured over. The specified connection
          must reside in the same transit gateway and be in an active state. The `classic`
          connection cannot be deleted until any `gre_tunnel` connections using it are
          deleted. This field only applies to and is required for network type
          `gre_tunnel` connections.
    :param str base_network_type: (optional) The type of network the Unbound GRE
          tunnel is targeting. This field is required for network type
          `unbound_gre_tunnel` and must be set to `classic`.  For a `redundant_gre`
          network type, the value is required and can be either VPC or Classic. This field
          is required to be unspecified for network type `classic`, `directlink`, `vpc`,
          `power_virtual_server`, `vpn_gateway` and `gre_tunnel` connections.
    :param str cidr: (optional) network_type 'vpn_gateway' connections use 'cidr' to
          specify the CIDR to use for the VPN GRE tunnels.
    :param datetime created_at: The date and time that this connection was created.
    :param str id: The unique identifier for this Transit Gateway connection.
    :param int local_bgp_asn: (optional) Local network BGP ASN.  This field only
          applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str local_gateway_ip: (optional) Local gateway IP address.  This field
          only applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str local_tunnel_ip: (optional) Local tunnel IP address.  This field only
          applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param int mtu: (optional) GRE tunnel MTU.  This field only applies to network
          type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str name: (optional) The user-defined name for this transit gateway
          connection. Network type `vpc`  connections are defaulted to the name of the
          VPC.  Network type `classic` connections are named `classic`.
          This field is required for network type `power_virtual_server`, `directlink`,
          `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway` and `redundant_gre`
          connections.
          This field is optional for network type `classic`, `vpc` connections.
    :param str network_account_id: (optional) The ID of the account which owns the
          connected network. Generally only used if the network is in a different IBM
          Cloud account than the gateway.
    :param str network_id: (optional) The ID of the network being connected via this
          connection. For network types `vpc`,`power_virtual_server`, `directlink` and
          `vpn_gateway` this is the CRN of the VPC / PowerVS / VDC / Direct Link / VPN
          gateway respectively. This field is required for network type `vpc`,
          `power_virtual_server`, `vpn_gateway`, and `directlink` connections.  It is also
          required for `redundant_gre` connections when the base_network_type is set to
          VPC. This field is required to be unspecified for network type `classic`,
          `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str network_type: (optional) Defines what type of network is connected
          via this connection.
    :param List[TransitGatewayConnectionPrefixFilterReference] prefix_filters:
          (optional) Array of prefix route filters for a transit gateway connection. This
          is order dependent with those first in the array being applied first, and those
          at the end of the array is applied last, or just before the default. This field
          does not apply to the `redundant_gre` network type.
    :param str prefix_filters_default: (optional) Default setting of permit or deny
          which applies to any routes that don't match a specified filter. This field does
          not apply to the `redundant_gre` network type.
    :param int remote_bgp_asn: (optional) Remote network BGP ASN.  This field only
          applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str remote_gateway_ip: (optional) Remote gateway IP address.  This field
          only applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str remote_tunnel_ip: (optional) Remote tunnel IP address.  This field
          only applies to network type `gre_tunnel` and `unbound_gre_tunnel` connections.
    :param str request_status: Only visible for cross account connections, this
          field represents the status of a connection request between IBM Cloud accounts.
          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 status: Connection's current configuration state. 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[TransitGatewayTunnel] tunnels: (optional) Collection of all tunnels
          for `redundant_gre` and `vpn_gateway` connections.
    :param datetime updated_at: The date and time that this connection was last
          updated.
    :param ZoneReference zone: (optional) Location of GRE tunnel. This field is
          required for network type `gre_tunnel` and `unbound_gre_tunnel` connections.
          This field is optional for network type `vpn_gateway` connections.
    """

    def __init__(
        self,
        created_at: datetime,
        id: str,
        request_status: str,
        status: str,
        updated_at: datetime,
        *,
        base_connection_id: Optional[str] = None,
        base_network_type: Optional[str] = None,
        cidr: Optional[str] = None,
        local_bgp_asn: Optional[int] = None,
        local_gateway_ip: Optional[str] = None,
        local_tunnel_ip: Optional[str] = None,
        mtu: Optional[int] = None,
        name: Optional[str] = None,
        network_account_id: Optional[str] = None,
        network_id: Optional[str] = None,
        network_type: Optional[str] = None,
        prefix_filters: Optional[List['TransitGatewayConnectionPrefixFilterReference']] = None,
        prefix_filters_default: Optional[str] = None,
        remote_bgp_asn: Optional[int] = None,
        remote_gateway_ip: Optional[str] = None,
        remote_tunnel_ip: Optional[str] = None,
        tunnels: Optional[List['TransitGatewayTunnel']] = None,
        zone: Optional['ZoneReference'] = None,
    ) -> None:
        """
        Initialize a TransitGatewayConnectionCust object.

        :param datetime created_at: The date and time that this connection was
               created.
        :param str id: The unique identifier for this Transit Gateway connection.
        :param str request_status: Only visible for cross account connections, this
               field represents the status of a connection request between IBM Cloud
               accounts. 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 status: Connection's current configuration state. 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: The date and time that this connection was last
               updated.
        :param str base_connection_id: (optional) Deprecated: network_type
               `gre_tunnel` connections use `base_connection_id` to specify the ID of a
               network_type `classic` connection the tunnel is configured over. The
               specified connection must reside in the same transit gateway and be in an
               active state. The `classic` connection cannot be deleted until any
               `gre_tunnel` connections using it are deleted. This field only applies to
               and is required for network type `gre_tunnel` connections.
        :param str base_network_type: (optional) The type of network the Unbound
               GRE tunnel is targeting. This field is required for network type
               `unbound_gre_tunnel` and must be set to `classic`.  For a `redundant_gre`
               network type, the value is required and can be either VPC or Classic. This
               field is required to be unspecified for network type `classic`,
               `directlink`, `vpc`, `power_virtual_server`, `vpn_gateway` and `gre_tunnel`
               connections.
        :param str cidr: (optional) network_type 'vpn_gateway' connections use
               'cidr' to specify the CIDR to use for the VPN GRE tunnels.
        :param int local_bgp_asn: (optional) Local network BGP ASN.  This field
               only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str local_gateway_ip: (optional) Local gateway IP address.  This
               field only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str local_tunnel_ip: (optional) Local tunnel IP address.  This field
               only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param int mtu: (optional) GRE tunnel MTU.  This field only applies to
               network type `gre_tunnel` and `unbound_gre_tunnel` connections.
        :param str name: (optional) The user-defined name for this transit gateway
               connection. Network type `vpc`  connections are defaulted to the name of
               the VPC.  Network type `classic` connections are named `classic`.
               This field is required for network type `power_virtual_server`,
               `directlink`, `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway` and
               `redundant_gre` connections.
               This field is optional for network type `classic`, `vpc` connections.
        :param str network_account_id: (optional) The ID of the account which owns
               the connected network. Generally only used if the network is in a different
               IBM Cloud account than the gateway.
        :param str network_id: (optional) The ID of the network being connected via
               this connection. For network types `vpc`,`power_virtual_server`,
               `directlink` and `vpn_gateway` this is the CRN of the VPC / PowerVS / VDC /
               Direct Link / VPN gateway respectively. This field is required for network
               type `vpc`, `power_virtual_server`, `vpn_gateway`, and `directlink`
               connections.  It is also required for `redundant_gre` connections when the
               base_network_type is set to VPC. This field is required to be unspecified
               for network type `classic`, `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str network_type: (optional) Defines what type of network is
               connected via this connection.
        :param List[TransitGatewayConnectionPrefixFilterReference] prefix_filters:
               (optional) Array of prefix route filters for a transit gateway connection.
               This is order dependent with those first in the array being applied first,
               and those at the end of the array is applied last, or just before the
               default. This field does not apply to the `redundant_gre` network type.
        :param str prefix_filters_default: (optional) Default setting of permit or
               deny which applies to any routes that don't match a specified filter. This
               field does not apply to the `redundant_gre` network type.
        :param int remote_bgp_asn: (optional) Remote network BGP ASN.  This field
               only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str remote_gateway_ip: (optional) Remote gateway IP address.  This
               field only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param str remote_tunnel_ip: (optional) Remote tunnel IP address.  This
               field only applies to network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
        :param List[TransitGatewayTunnel] tunnels: (optional) Collection of all
               tunnels for `redundant_gre` and `vpn_gateway` connections.
        :param ZoneReference zone: (optional) Location of GRE tunnel. This field is
               required for network type `gre_tunnel` and `unbound_gre_tunnel`
               connections.
               This field is optional for network type `vpn_gateway` connections.
        """
        self.base_connection_id = base_connection_id
        self.base_network_type = base_network_type
        self.cidr = cidr
        self.created_at = created_at
        self.id = id
        self.local_bgp_asn = local_bgp_asn
        self.local_gateway_ip = local_gateway_ip
        self.local_tunnel_ip = local_tunnel_ip
        self.mtu = mtu
        self.name = name
        self.network_account_id = network_account_id
        self.network_id = network_id
        self.network_type = network_type
        self.prefix_filters = prefix_filters
        self.prefix_filters_default = prefix_filters_default
        self.remote_bgp_asn = remote_bgp_asn
        self.remote_gateway_ip = remote_gateway_ip
        self.remote_tunnel_ip = remote_tunnel_ip
        self.request_status = request_status
        self.status = status
        self.tunnels = tunnels
        self.updated_at = updated_at
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'TransitGatewayConnectionCust':
        """Initialize a TransitGatewayConnectionCust object from a json dictionary."""
        args = {}
        if (base_connection_id := _dict.get('base_connection_id')) is not None:
            args['base_connection_id'] = base_connection_id
        if (base_network_type := _dict.get('base_network_type')) is not None:
            args['base_network_type'] = base_network_type
        if (cidr := _dict.get('cidr')) is not None:
            args['cidr'] = cidr
        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 TransitGatewayConnectionCust JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in TransitGatewayConnectionCust JSON')
        if (local_bgp_asn := _dict.get('local_bgp_asn')) is not None:
            args['local_bgp_asn'] = local_bgp_asn
        if (local_gateway_ip := _dict.get('local_gateway_ip')) is not None:
            args['local_gateway_ip'] = local_gateway_ip
        if (local_tunnel_ip := _dict.get('local_tunnel_ip')) is not None:
            args['local_tunnel_ip'] = local_tunnel_ip
        if (mtu := _dict.get('mtu')) is not None:
            args['mtu'] = mtu
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        if (network_account_id := _dict.get('network_account_id')) is not None:
            args['network_account_id'] = network_account_id
        if (network_id := _dict.get('network_id')) is not None:
            args['network_id'] = network_id
        if (network_type := _dict.get('network_type')) is not None:
            args['network_type'] = network_type
        if (prefix_filters := _dict.get('prefix_filters')) is not None:
            args['prefix_filters'] = [TransitGatewayConnectionPrefixFilterReference.from_dict(v) for v in prefix_filters]
        if (prefix_filters_default := _dict.get('prefix_filters_default')) is not None:
            args['prefix_filters_default'] = prefix_filters_default
        if (remote_bgp_asn := _dict.get('remote_bgp_asn')) is not None:
            args['remote_bgp_asn'] = remote_bgp_asn
        if (remote_gateway_ip := _dict.get('remote_gateway_ip')) is not None:
            args['remote_gateway_ip'] = remote_gateway_ip
        if (remote_tunnel_ip := _dict.get('remote_tunnel_ip')) is not None:
            args['remote_tunnel_ip'] = remote_tunnel_ip
        if (request_status := _dict.get('request_status')) is not None:
            args['request_status'] = request_status
        else:
            raise ValueError('Required property \'request_status\' not present in TransitGatewayConnectionCust JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in TransitGatewayConnectionCust JSON')
        if (tunnels := _dict.get('tunnels')) is not None:
            args['tunnels'] = [TransitGatewayTunnel.from_dict(v) for v in tunnels]
        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 TransitGatewayConnectionCust JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(zone)
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'base_connection_id') and self.base_connection_id is not None:
            _dict['base_connection_id'] = self.base_connection_id
        if hasattr(self, 'base_network_type') and self.base_network_type is not None:
            _dict['base_network_type'] = self.base_network_type
        if hasattr(self, 'cidr') and self.cidr is not None:
            _dict['cidr'] = self.cidr
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'local_bgp_asn') and self.local_bgp_asn is not None:
            _dict['local_bgp_asn'] = self.local_bgp_asn
        if hasattr(self, 'local_gateway_ip') and self.local_gateway_ip is not None:
            _dict['local_gateway_ip'] = self.local_gateway_ip
        if hasattr(self, 'local_tunnel_ip') and self.local_tunnel_ip is not None:
            _dict['local_tunnel_ip'] = self.local_tunnel_ip
        if hasattr(self, 'mtu') and self.mtu is not None:
            _dict['mtu'] = self.mtu
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_account_id') and self.network_account_id is not None:
            _dict['network_account_id'] = self.network_account_id
        if hasattr(self, 'network_id') and self.network_id is not None:
            _dict['network_id'] = self.network_id
        if hasattr(self, 'network_type') and self.network_type is not None:
            _dict['network_type'] = self.network_type
        if hasattr(self, 'prefix_filters') and self.prefix_filters is not None:
            prefix_filters_list = []
            for v in self.prefix_filters:
                if isinstance(v, dict):
                    prefix_filters_list.append(v)
                else:
                    prefix_filters_list.append(v.to_dict())
            _dict['prefix_filters'] = prefix_filters_list
        if hasattr(self, 'prefix_filters_default') and self.prefix_filters_default is not None:
            _dict['prefix_filters_default'] = self.prefix_filters_default
        if hasattr(self, 'remote_bgp_asn') and self.remote_bgp_asn is not None:
            _dict['remote_bgp_asn'] = self.remote_bgp_asn
        if hasattr(self, 'remote_gateway_ip') and self.remote_gateway_ip is not None:
            _dict['remote_gateway_ip'] = self.remote_gateway_ip
        if hasattr(self, 'remote_tunnel_ip') and self.remote_tunnel_ip is not None:
            _dict['remote_tunnel_ip'] = self.remote_tunnel_ip
        if hasattr(self, 'request_status') and self.request_status is not None:
            _dict['request_status'] = self.request_status
        if hasattr(self, 'status') and self.status is not None:
            _dict['status'] = self.status
        if hasattr(self, 'tunnels') and self.tunnels is not None:
            tunnels_list = []
            for v in self.tunnels:
                if isinstance(v, dict):
                    tunnels_list.append(v)
                else:
                    tunnels_list.append(v.to_dict())
            _dict['tunnels'] = tunnels_list
        if hasattr(self, 'updated_at') and self.updated_at is not None:
            _dict['updated_at'] = datetime_to_string(self.updated_at)
        if hasattr(self, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

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

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

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

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

    class BaseNetworkTypeEnum(str, Enum):
        """
        The type of network the Unbound GRE tunnel is targeting. This field is required
        for network type `unbound_gre_tunnel` and must be set to `classic`.  For a
        `redundant_gre` network type, the value is required and can be either VPC or
        Classic. This field is required to be unspecified for network type `classic`,
        `directlink`, `vpc`, `power_virtual_server`, `vpn_gateway` and `gre_tunnel`
        connections.
        """

        CLASSIC = 'classic'
        VPC = 'vpc'
        VPN = 'vpn'


    class NetworkTypeEnum(str, Enum):
        """
        Defines what type of network is connected via this connection.
        """

        CLASSIC = 'classic'
        DIRECTLINK = 'directlink'
        GRE_TUNNEL = 'gre_tunnel'
        UNBOUND_GRE_TUNNEL = 'unbound_gre_tunnel'
        VPC = 'vpc'
        POWER_VIRTUAL_SERVER = 'power_virtual_server'
        REDUNDANT_GRE = 'redundant_gre'
        VPN_GATEWAY = 'vpn_gateway'


    class PrefixFiltersDefaultEnum(str, Enum):
        """
        Default setting of permit or deny which applies to any routes that don't match a
        specified filter. This field does not apply to the `redundant_gre` network type.
        """

        PERMIT = 'permit'
        DENY = 'deny'


    class RequestStatusEnum(str, Enum):
        """
        Only visible for cross account connections, this field represents the status of a
        connection request between IBM Cloud accounts. 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'
        APPROVED = 'approved'
        REJECTED = 'rejected'
        EXPIRED = 'expired'
        DETACHED = 'detached'


    class StatusEnum(str, Enum):
        """
        Connection's current configuration state. The list of enumerated values for this
        property may expand in the future. Code and processes using this field must
        tolerate unexpected values.
        """

        ATTACHED = 'attached'
        FAILED = 'failed'
        PENDING = 'pending'
        NETWORK_PENDING = 'network_pending'
        DELETING = 'deleting'
        DETACHING = 'detaching'
        DETACHED = 'detached'
        SUSPENDING = 'suspending'
        SUSPENDED = 'suspended'



class TransitGatewayConnectionPrefixFilter:
    """
    A prefix filter for a Transit Gateway connection.

    :param str action: Whether to permit or deny prefix filter.
    :param int ge: (optional) IP Prefix GE.
    :param int le: (optional) IP Prefix LE.
    :param str prefix: IP Prefix.
    """

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

        :param str action: Whether to permit or deny prefix filter.
        :param str prefix: IP Prefix.
        :param int ge: (optional) IP Prefix GE.
        :param int le: (optional) IP Prefix LE.
        """
        self.action = action
        self.ge = ge
        self.le = le
        self.prefix = prefix

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

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

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

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

    class ActionEnum(str, Enum):
        """
        Whether to permit or deny prefix filter.
        """

        PERMIT = 'permit'
        DENY = 'deny'



class TransitGatewayConnectionPrefixFilterReference:
    """
    A prefix filter reference object for a Transit Gateway connection.

    :param str action: Whether to permit or deny prefix filter.
    :param str before: (optional) Identifier of prefix filter that handles the
          ordering and follow semantics:
          - When a filter reference another filter in it's before field, then the filter
          making the reference is applied before
            the referenced filter. For example: if filter A references filter B in its
          before field, A is applied before B.
          - When a new filter is added that has the same before as an existing filter,
          then the older filter will have its before
            field updated to point to the new filter. Starting with the above example: if
          filter C is added and it references B in its
            before field, then A's before field should be modified to point to C, so the
          order of application would be A, C and finally B.
          - A filter that has an empty before reference will be applied last (though the
          date order mentioned above will still apply).
            So continuing the above examples, if filter B has an empty before field, then
          it will be applied last, but if filter D
            is created with an empty before field, then B's before field will be modified
          to point to D, so B will be applied before D.
    :param datetime created_at: The date and time that this prefix filter was
          created.
    :param int ge: (optional) IP Prefix GE.
    :param str id: Prefix Filter identifier.
    :param int le: (optional) IP Prefix LE.
    :param str prefix: IP Prefix.
    :param datetime updated_at: (optional) The date and time that this prefix filter
          was last updated.
    """

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

        :param str action: Whether to permit or deny prefix filter.
        :param datetime created_at: The date and time that this prefix filter was
               created.
        :param str id: Prefix Filter identifier.
        :param str prefix: IP Prefix.
        :param str before: (optional) Identifier of prefix filter that handles the
               ordering and follow semantics:
               - When a filter reference another filter in it's before field, then the
               filter making the reference is applied before
                 the referenced filter. For example: if filter A references filter B in
               its before field, A is applied before B.
               - When a new filter is added that has the same before as an existing
               filter, then the older filter will have its before
                 field updated to point to the new filter. Starting with the above
               example: if filter C is added and it references B in its
                 before field, then A's before field should be modified to point to C, so
               the order of application would be A, C and finally B.
               - A filter that has an empty before reference will be applied last (though
               the date order mentioned above will still apply).
                 So continuing the above examples, if filter B has an empty before field,
               then it will be applied last, but if filter D
                 is created with an empty before field, then B's before field will be
               modified to point to D, so B will be applied before D.
        :param int ge: (optional) IP Prefix GE.
        :param int le: (optional) IP Prefix LE.
        :param datetime updated_at: (optional) The date and time that this prefix
               filter was last updated.
        """
        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) -> 'TransitGatewayConnectionPrefixFilterReference':
        """Initialize a TransitGatewayConnectionPrefixFilterReference 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 TransitGatewayConnectionPrefixFilterReference 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 TransitGatewayConnectionPrefixFilterReference 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 TransitGatewayConnectionPrefixFilterReference 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 TransitGatewayConnectionPrefixFilterReference JSON')
        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 TransitGatewayConnectionPrefixFilterReference object from 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 TransitGatewayConnectionPrefixFilterReference object."""
        return json.dumps(self.to_dict(), indent=2)

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

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

    class ActionEnum(str, Enum):
        """
        Whether to permit or deny prefix filter.
        """

        PERMIT = 'permit'
        DENY = 'deny'



class TransitGatewayReference:
    """
    Transit gateway reference.

    :param str crn: gateway CRN.
    :param str id: gateway ID.
    :param str name: transit gateway name.
    """

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

        :param str crn: gateway CRN.
        :param str id: gateway ID.
        :param str name: transit gateway name.
        """
        self.crn = crn
        self.id = id
        self.name = name

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

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

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

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

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


class TransitGatewayTunnel:
    """
    Details for a redundant GRE tunnel.

    :param str base_network_type: The type of network the redundant GRE tunnel is
          targeting.
    :param datetime created_at: The date and time that this GRE tunnel was created.
    :param str id: The unique identifier for this redundant GRE tunnel.
    :param int local_bgp_asn: Local network BGP ASN.  It is assigned by IBM when the
          tunnel is created.
    :param str local_gateway_ip: Local gateway IP address.
    :param str local_tunnel_ip: Local tunnel IP address. The local_tunnel_ip and
          remote_tunnel_ip addresses must be in the same /30 network. Neither can be the
          network nor broadcast addresses.
    :param int mtu: (optional) GRE tunnel MTU.
    :param str name: The user-defined name for this tunnel.
    :param str network_account_id: (optional) The ID of the account for cross
          account Classic connections.  This field is required when the GRE tunnel is in a
          different account than the gateway and the base network is Classic.
    :param str network_id: (optional) The ID of the network VPC being connected via
          this connection.
    :param int remote_bgp_asn: Remote network BGP ASN. The following ASN values are
          reserved and unavailable 0, 13884, 36351, 64512, 64513, 65100, 65200-65234,
          65402-65433, 65500, 65516, 65519, 65521, 65531 and 4201065000-4201065999 If
          `remote_bgp_asn` is omitted on create requests, IBM will assign an ASN.
    :param str remote_gateway_ip: Remote gateway IP address.
    :param str remote_tunnel_ip: Remote tunnel IP address. The local_tunnel_ip and
          remote_tunnel_ip addresses must be in the same /30 network. Neither can be the
          network nor broadcast addresses.
    :param str status: Tunnel's current configuration state. 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: The date and time that this tunnel was last updated.
    :param ZoneReference zone: Availability zone reference.
    """

    def __init__(
        self,
        base_network_type: str,
        created_at: datetime,
        id: str,
        local_bgp_asn: int,
        local_gateway_ip: str,
        local_tunnel_ip: str,
        name: str,
        remote_bgp_asn: int,
        remote_gateway_ip: str,
        remote_tunnel_ip: str,
        status: str,
        updated_at: datetime,
        zone: 'ZoneReference',
        *,
        mtu: Optional[int] = None,
        network_account_id: Optional[str] = None,
        network_id: Optional[str] = None,
    ) -> None:
        """
        Initialize a TransitGatewayTunnel object.

        :param str base_network_type: The type of network the redundant GRE tunnel
               is targeting.
        :param datetime created_at: The date and time that this GRE tunnel was
               created.
        :param str id: The unique identifier for this redundant GRE tunnel.
        :param int local_bgp_asn: Local network BGP ASN.  It is assigned by IBM
               when the tunnel is created.
        :param str local_gateway_ip: Local gateway IP address.
        :param str local_tunnel_ip: Local tunnel IP address. The local_tunnel_ip
               and remote_tunnel_ip addresses must be in the same /30 network. Neither can
               be the network nor broadcast addresses.
        :param str name: The user-defined name for this tunnel.
        :param int remote_bgp_asn: Remote network BGP ASN. The following ASN values
               are reserved and unavailable 0, 13884, 36351, 64512, 64513, 65100,
               65200-65234, 65402-65433, 65500, 65516, 65519, 65521, 65531 and
               4201065000-4201065999 If `remote_bgp_asn` is omitted on create requests,
               IBM will assign an ASN.
        :param str remote_gateway_ip: Remote gateway IP address.
        :param str remote_tunnel_ip: Remote tunnel IP address. The local_tunnel_ip
               and remote_tunnel_ip addresses must be in the same /30 network. Neither can
               be the network nor broadcast addresses.
        :param str status: Tunnel's current configuration state. 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: The date and time that this tunnel was last
               updated.
        :param ZoneReference zone: Availability zone reference.
        :param int mtu: (optional) GRE tunnel MTU.
        :param str network_account_id: (optional) The ID of the account for cross
               account Classic connections.  This field is required when the GRE tunnel is
               in a different account than the gateway and the base network is Classic.
        :param str network_id: (optional) The ID of the network VPC being connected
               via this connection.
        """
        self.base_network_type = base_network_type
        self.created_at = created_at
        self.id = id
        self.local_bgp_asn = local_bgp_asn
        self.local_gateway_ip = local_gateway_ip
        self.local_tunnel_ip = local_tunnel_ip
        self.mtu = mtu
        self.name = name
        self.network_account_id = network_account_id
        self.network_id = network_id
        self.remote_bgp_asn = remote_bgp_asn
        self.remote_gateway_ip = remote_gateway_ip
        self.remote_tunnel_ip = remote_tunnel_ip
        self.status = status
        self.updated_at = updated_at
        self.zone = zone

    @classmethod
    def from_dict(cls, _dict: Dict) -> 'TransitGatewayTunnel':
        """Initialize a TransitGatewayTunnel object from a json dictionary."""
        args = {}
        if (base_network_type := _dict.get('base_network_type')) is not None:
            args['base_network_type'] = base_network_type
        else:
            raise ValueError('Required property \'base_network_type\' not present in TransitGatewayTunnel 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 TransitGatewayTunnel JSON')
        if (id := _dict.get('id')) is not None:
            args['id'] = id
        else:
            raise ValueError('Required property \'id\' not present in TransitGatewayTunnel JSON')
        if (local_bgp_asn := _dict.get('local_bgp_asn')) is not None:
            args['local_bgp_asn'] = local_bgp_asn
        else:
            raise ValueError('Required property \'local_bgp_asn\' not present in TransitGatewayTunnel JSON')
        if (local_gateway_ip := _dict.get('local_gateway_ip')) is not None:
            args['local_gateway_ip'] = local_gateway_ip
        else:
            raise ValueError('Required property \'local_gateway_ip\' not present in TransitGatewayTunnel JSON')
        if (local_tunnel_ip := _dict.get('local_tunnel_ip')) is not None:
            args['local_tunnel_ip'] = local_tunnel_ip
        else:
            raise ValueError('Required property \'local_tunnel_ip\' not present in TransitGatewayTunnel JSON')
        if (mtu := _dict.get('mtu')) is not None:
            args['mtu'] = mtu
        if (name := _dict.get('name')) is not None:
            args['name'] = name
        else:
            raise ValueError('Required property \'name\' not present in TransitGatewayTunnel JSON')
        if (network_account_id := _dict.get('network_account_id')) is not None:
            args['network_account_id'] = network_account_id
        if (network_id := _dict.get('network_id')) is not None:
            args['network_id'] = network_id
        if (remote_bgp_asn := _dict.get('remote_bgp_asn')) is not None:
            args['remote_bgp_asn'] = remote_bgp_asn
        else:
            raise ValueError('Required property \'remote_bgp_asn\' not present in TransitGatewayTunnel JSON')
        if (remote_gateway_ip := _dict.get('remote_gateway_ip')) is not None:
            args['remote_gateway_ip'] = remote_gateway_ip
        else:
            raise ValueError('Required property \'remote_gateway_ip\' not present in TransitGatewayTunnel JSON')
        if (remote_tunnel_ip := _dict.get('remote_tunnel_ip')) is not None:
            args['remote_tunnel_ip'] = remote_tunnel_ip
        else:
            raise ValueError('Required property \'remote_tunnel_ip\' not present in TransitGatewayTunnel JSON')
        if (status := _dict.get('status')) is not None:
            args['status'] = status
        else:
            raise ValueError('Required property \'status\' not present in TransitGatewayTunnel 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 TransitGatewayTunnel JSON')
        if (zone := _dict.get('zone')) is not None:
            args['zone'] = ZoneReference.from_dict(zone)
        else:
            raise ValueError('Required property \'zone\' not present in TransitGatewayTunnel JSON')
        return cls(**args)

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

    def to_dict(self) -> Dict:
        """Return a json dictionary representing this model."""
        _dict = {}
        if hasattr(self, 'base_network_type') and self.base_network_type is not None:
            _dict['base_network_type'] = self.base_network_type
        if hasattr(self, 'created_at') and self.created_at is not None:
            _dict['created_at'] = datetime_to_string(self.created_at)
        if hasattr(self, 'id') and self.id is not None:
            _dict['id'] = self.id
        if hasattr(self, 'local_bgp_asn') and self.local_bgp_asn is not None:
            _dict['local_bgp_asn'] = self.local_bgp_asn
        if hasattr(self, 'local_gateway_ip') and self.local_gateway_ip is not None:
            _dict['local_gateway_ip'] = self.local_gateway_ip
        if hasattr(self, 'local_tunnel_ip') and self.local_tunnel_ip is not None:
            _dict['local_tunnel_ip'] = self.local_tunnel_ip
        if hasattr(self, 'mtu') and self.mtu is not None:
            _dict['mtu'] = self.mtu
        if hasattr(self, 'name') and self.name is not None:
            _dict['name'] = self.name
        if hasattr(self, 'network_account_id') and self.network_account_id is not None:
            _dict['network_account_id'] = self.network_account_id
        if hasattr(self, 'network_id') and self.network_id is not None:
            _dict['network_id'] = self.network_id
        if hasattr(self, 'remote_bgp_asn') and self.remote_bgp_asn is not None:
            _dict['remote_bgp_asn'] = self.remote_bgp_asn
        if hasattr(self, 'remote_gateway_ip') and self.remote_gateway_ip is not None:
            _dict['remote_gateway_ip'] = self.remote_gateway_ip
        if hasattr(self, 'remote_tunnel_ip') and self.remote_tunnel_ip is not None:
            _dict['remote_tunnel_ip'] = self.remote_tunnel_ip
        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, 'zone') and self.zone is not None:
            if isinstance(self.zone, dict):
                _dict['zone'] = self.zone
            else:
                _dict['zone'] = self.zone.to_dict()
        return _dict

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

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

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

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

    class BaseNetworkTypeEnum(str, Enum):
        """
        The type of network the redundant GRE tunnel is targeting.
        """

        CLASSIC = 'classic'
        VPC = 'vpc'
        VPN = 'vpn'


    class StatusEnum(str, Enum):
        """
        Tunnel's current configuration state. The list of enumerated values for this
        property may expand in the future. Code and processes using this field must
        tolerate unexpected values.
        """

        ATTACHED = 'attached'
        FAILED = 'failed'
        PENDING = 'pending'
        DELETING = 'deleting'
        DETACHING = 'detaching'
        DETACHED = 'detached'
        SUSPENDING = 'suspending'
        SUSPENDED = 'suspended'



class TransitGatewayTunnelCollection:
    """
    Collection of all tunnels for `redundant_gre` and `vpn_gateway` connections.

    :param List[TransitGatewayTunnel] tunnels: Collection of all tunnels for
          `redundant_gre` and `vpn_gateway` connections.
    """

    def __init__(
        self,
        tunnels: List['TransitGatewayTunnel'],
    ) -> None:
        """
        Initialize a TransitGatewayTunnelCollection object.

        :param List[TransitGatewayTunnel] tunnels: Collection of all tunnels for
               `redundant_gre` and `vpn_gateway` connections.
        """
        self.tunnels = tunnels

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

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

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

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

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

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

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


class TransitGatewayTunnelPatch:
    """
    An update template for a Transit Gateway connection tunnel.

    :param str name: (optional) The user-defined name for this connection tunnel.
    """

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

        :param str name: (optional) The user-defined name for this connection
               tunnel.
        """
        self.name = name

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

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

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

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

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

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

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


class TransitGatewayTunnelTemplate:
    """
    A create template with information for redundant GRE tunnel.

    :param str local_gateway_ip: Local gateway IP address.
    :param str local_tunnel_ip: Local tunnel IP address. The local_tunnel_ip and
          remote_tunnel_ip addresses must be in the same /30 network. Neither can be the
          network nor broadcast addresses.
    :param str name: The user-defined name for this tunnel connection.
    :param int remote_bgp_asn: (optional) Remote network BGP ASN. The following ASN
          values are reserved and unavailable 0, 13884, 36351, 64512, 64513, 65100,
          65200-65234, 65402-65433, 65500, 65516, 65519, 65521, 65531 and
          4201065000-4201065999 If `remote_bgp_asn` is omitted on create requests, IBM
          will assign an ASN.
    :param str remote_gateway_ip: Remote gateway IP address.
    :param str remote_tunnel_ip: Remote tunnel IP address. The local_tunnel_ip and
          remote_tunnel_ip addresses must be in the same /30 network. Neither can be the
          network nor broadcast addresses.
    :param ZoneIdentity zone: Specify the connection's location.  The specified
          availability zone must reside in the gateway's region.
          Use the IBM Cloud global catalog to list zones within the desired region.
    """

    def __init__(
        self,
        local_gateway_ip: str,
        local_tunnel_ip: str,
        name: str,
        remote_gateway_ip: str,
        remote_tunnel_ip: str,
        zone: 'ZoneIdentity',
        *,
        remote_bgp_asn: Optional[int] = None,
    ) -> None:
        """
        Initialize a TransitGatewayTunnelTemplate object.

        :param str local_gateway_ip: Local gateway IP address.
        :param str local_tunnel_ip: Local tunnel IP address. The local_tunnel_ip
               and remote_tunnel_ip addresses must be in the same /30 network. Neither can
               be the network nor broadcast addresses.
        :param str name: The user-defined name for this tunnel connection.
        :param str remote_gateway_ip: Remote gateway IP address.
        :param str remote_tunnel_ip: Remote tunnel IP address. The local_tunnel_ip
               and remote_tunnel_ip addresses must be in the same /30 network. Neither can
               be the network nor broadcast addresses.
        :param ZoneIdentity zone: Specify the connection's location.  The specified
               availability zone must reside in the gateway's region.
               Use the IBM Cloud global catalog to list zones within the desired region.
        :param int remote_bgp_asn: (optional) Remote network BGP ASN. The following
               ASN values are reserved and unavailable 0, 13884, 36351, 64512, 64513,
               65100, 65200-65234, 65402-65433, 65500, 65516, 65519, 65521, 65531 and
               4201065000-4201065999 If `remote_bgp_asn` is omitted on create requests,
               IBM will assign an ASN.
        """
        self.local_gateway_ip = local_gateway_ip
        self.local_tunnel_ip = local_tunnel_ip
        self.name = name
        self.remote_bgp_asn = remote_bgp_asn
        self.remote_gateway_ip = remote_gateway_ip
        self.remote_tunnel_ip = remote_tunnel_ip
        self.zone = zone

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

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

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

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

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

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

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


class ZoneIdentity:
    """
    ZoneIdentity.

    """

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

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


class ZoneReference:
    """
    Availability zone reference.

    :param str name: Availability zone name.
    """

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

        :param str name: Availability zone name.
        """
        self.name = name

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

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

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

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

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

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

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


class ZoneIdentityByName(ZoneIdentity):
    """
    Availability zone.

    :param str name: (optional) Availability zone name.
    """

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

        :param str name: (optional) Availability zone name.
        """
        # pylint: disable=super-init-not-called
        self.name = name

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

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

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

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

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

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

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

##############################################################################
# Pagers
##############################################################################


class TransitGatewaysPager:
    """
    TransitGatewaysPager can be used to simplify the use of the "list_transit_gateways" method.
    """

    def __init__(
        self,
        *,
        client: TransitGatewayApisV1,
        limit: int = None,
    ) -> None:
        """
        Initialize a TransitGatewaysPager object.
        :param int limit: (optional) The maximum number of resources to return per
               page.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of TransitGateway.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_transit_gateways(
            limit=self._limit,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = next_page_link.get('start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('transit_gateways')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of TransitGateway.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class ConnectionsPager:
    """
    ConnectionsPager can be used to simplify the use of the "list_connections" method.
    """

    def __init__(
        self,
        *,
        client: TransitGatewayApisV1,
        limit: int = None,
        network_id: str = None,
        network_type: str = None,
    ) -> None:
        """
        Initialize a ConnectionsPager object.
        :param int limit: (optional) The maximum number of resources to return per
               page.
        :param str network_id: (optional) Search for connections with the given
               network_id value.
        :param str network_type: (optional) Search for connections with the given
               network_type value.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._limit = limit
        self._network_id = network_id
        self._network_type = network_type

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of TransitConnection.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_connections(
            limit=self._limit,
            network_id=self._network_id,
            network_type=self._network_type,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = next_page_link.get('start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('connections')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of TransitConnection.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results


class TransitGatewayConnectionsPager:
    """
    TransitGatewayConnectionsPager can be used to simplify the use of the "list_transit_gateway_connections" method.
    """

    def __init__(
        self,
        *,
        client: TransitGatewayApisV1,
        transit_gateway_id: str,
        limit: int = None,
        name: str = None,
    ) -> None:
        """
        Initialize a TransitGatewayConnectionsPager object.
        :param str transit_gateway_id: The Transit Gateway identifier.
        :param int limit: (optional) The maximum number of resources to return per
               page.
        :param str name: (optional) Search for connections with the given name.
        """
        self._has_next = True
        self._client = client
        self._page_context = {'next': None}
        self._transit_gateway_id = transit_gateway_id
        self._limit = limit
        self._name = name

    def has_next(self) -> bool:
        """
        Returns true if there are potentially more results to be retrieved.
        """
        return self._has_next

    def get_next(self) -> List[dict]:
        """
        Returns the next page of results.
        :return: A List[dict], where each element is a dict that represents an instance of TransitGatewayConnectionCust.
        :rtype: List[dict]
        """
        if not self.has_next():
            raise StopIteration(message='No more results available')

        result = self._client.list_transit_gateway_connections(
            transit_gateway_id=self._transit_gateway_id,
            limit=self._limit,
            name=self._name,
            start=self._page_context.get('next'),
        ).get_result()

        next = None
        next_page_link = result.get('next')
        if next_page_link is not None:
            next = next_page_link.get('start')
        self._page_context['next'] = next
        if next is None:
            self._has_next = False

        return result.get('connections')

    def get_all(self) -> List[dict]:
        """
        Returns all results by invoking get_next() repeatedly
        until all pages of results have been retrieved.
        :return: A List[dict], where each element is a dict that represents an instance of TransitGatewayConnectionCust.
        :rtype: List[dict]
        """
        results = []
        while self.has_next():
            next_page = self.get_next()
            results.extend(next_page)
        return results
