from f5sdk.cs import ManagementClient
from f5sdk.cs.accounts import AccountClient
from f5sdk.cs.subscriptions import SubscriptionClient
from f5sdk.logger import Logger

LOGGER = Logger(__name__).get_logger()


def run_example():
    """ Get Cloud Services configuration """
    # create management client
    mgmt_client = ManagementClient(user=os.environ['F5_CS_USER'],
                                   password=os.environ['F5_CS_PWD'])

    # create account/subscription client
    account_client = AccountClient(mgmt_client)
    subscription_client = SubscriptionClient(mgmt_client)

    # discover account/subscription ID
    account_id = account_client.show_user()['primary_account_id']
    subscription_id = subscription_client.list(
        query_parameters={'account_id': account_id
                          })['subscriptions'][0]['subscription_id']

    # get subscription details
    return subscription_client.show(name=subscription_id)


if __name__ == '__main__':
    LOGGER.info(json.dumps(run_example(), indent=4))
Пример #2
0
    # configure service
    return client.service.create(config_file='./files/{}.{}.json'.format(
        data['hostname'].split('.')[0], atc_type))


if __name__ == '__main__':
    # Read BIG-IP data from YAML file or environment variables
    inputfile = ''
    bigip_data = {}
    try:
        # Ensure data file is provided
        if len(sys.argv) == 1:
            print(
                "Please provide a yaml file containing variables.\nExample:\n")
            print("python3 bigip.py data.yml\n")
    # Set BIG-IP data from the YAML file
        else:
            inputfile = sys.argv[1]
            stream = open(inputfile, 'r')
            bigip_data = yaml.load(stream, Loader=yaml.BaseLoader)
            stream.close()
    except OSError as err:
        print(str(err))
        sys.exit(2)

    # Loop through the BIG-IPs
    for bigip in bigip_data['bigips']:
        # LOGGER.info(create_declaration({ **bigip,  **bigip_data['dataCenters'][bigip['dataCenter']] },"do"))
        LOGGER.info(create_declaration(bigip, "as3"))
        # LOGGER.info(update_config(bigip, "do"))
        LOGGER.info(update_config(bigip, "as3"))
Пример #3
0
    maintaining idempotency
    """
    # create management client
    mgmt_client = ManagementClient(
        os.environ['F5_SDK_HOST'],
        user=os.environ['F5_SDK_USERNAME'],
        password=os.environ['F5_SDK_PWD'])

    # create extension client
    as3_client = AS3Client(mgmt_client)

    # Get installed package version info
    version_info = as3_client.package.is_installed()
    LOGGER.info(version_info['installed'])
    LOGGER.info(version_info['installed_version'])
    LOGGER.info(version_info['latest_version'])

    # install package
    if not version_info['installed']:
        as3_client.package.install()

    # ensure service is available
    as3_client.service.is_available()

    # configure AS3
    return as3_client.service.create(config_file=os.environ['F5_SDK_AS3_DECL'])


if __name__ == '__main__':
    LOGGER.info(run_example())
Пример #4
0
    # create assignment client, member management client
    assignment_client = AssignmentClient(mgmt_client)
    member_mgmt_client = MemberManagementClient(mgmt_client)

    # list assignments
    assignments = assignment_client.list()

    # get address assignment - there should only be one
    assignments = assignments['items']
    assignment = [i for i in assignments if i['deviceAddress'] == address][0]

    if not assignment:
        raise Exception('Unable to locate assignment from BIG-IQ assignments')

    # perform revoke - unreachable device
    return member_mgmt_client.create(
        config={
            'licensePoolName': pool,
            'command': 'revoke',
            'address': assignment['deviceAddress'],
            'assignmentType': 'UNREACHABLE',
            'macAddress': assignment['macAddress']
        })


if __name__ == '__main__':
    RESPONSE = run_example(os.environ['F5_SDK_ADDRESS_TO_REVOKE'],
                           os.environ['F5_SDK_LICENSE_POOL'])
    LOGGER.info('Response: %s', RESPONSE)
Пример #5
0
class ManagementClient(object):
    """A class used as a management client for F5 Cloud Services

    Attributes
    ----------
    access_token : str
        the access token for the service
    token_details : dict
        the token details for the service
    logger : object
        instantiated logger object

    Methods
    -------
    make_request()
        Refer to method documentation
    """
    def __init__(self, **kwargs):
        """Class initialization

        Parameters
        ----------
        **kwargs :
            optional keyword arguments

        Keyword Arguments
        -----------------
        user : str
            the username for service authentication
        password : str
            the password for service authentication

        Returns
        -------
        None
        """

        self.logger = Logger(__name__).get_logger()

        # process kwargs
        self._api_endpoint = kwargs.pop('api_endpoint', None)
        if self._api_endpoint is None:
            self._api_endpoint = API_ENDPOINT

        self._user = kwargs.pop('user', None)
        self._password = kwargs.pop('password', None)
        self._subscription_id = kwargs.pop('subscription_id', None)

        self.access_token = None
        self.token_details = None

        if self._user and self._password:
            self._login_using_credentials()
        else:
            raise InputRequiredError('user|password required')

    @retry(exceptions=HTTPError,
           tries=constants.RETRIES['DEFAULT'],
           delay=constants.RETRIES['DELAY_IN_SECS'])
    def _get_token(self):
        """Gets access token

        Retries if unsuccessful, up to maximum allotment

        Parameters
        ----------
        None

        Returns
        -------
        dict
            a dictionary containing access token and expiration in seconds:
            {'accessToken': 'token', 'expirationIn': 3600}
        """

        try:
            response = http_utils.make_request(self._api_endpoint,
                                               '/v1/svc-auth/login',
                                               method='POST',
                                               body={
                                                   'username': self._user,
                                                   'password': self._password
                                               })
        except HTTPError as error:
            if constants.HTTP_STATUS_CODE['BAD_REQUEST_BODY'] in str(error) or \
                constants.HTTP_STATUS_CODE['FAILED_AUTHENTICATION'] in str(error):
                _exception = InvalidAuthError(error)
                _exception.__cause__ = None
                raise _exception
            raise error
        return {
            'accessToken': response['access_token'],
            'expirationIn': response['expires_at']
        }

    def _login_using_credentials(self):
        """Logs in to service using user + password

        Parameters
        ----------
        None

        Returns
        -------
        None
        """

        self.logger.info('Logging in using user + password')
        self.token_details = self._get_token()
        self.access_token = self.token_details['accessToken']

    def make_request(self, uri, **kwargs):
        """Makes request to service (HTTP/S)

        Parameters
        ----------
        uri : str
            the URI where the request should be made
        **kwargs :
            optional keyword arguments

        Keyword Arguments
        -----------------
        method : str
            the HTTP method to use
        headers : str
            the HTTP headers to use
        body : str
            the HTTP body to use
        body_content_type : str
            the HTTP body content type to use
        bool_response : bool
            return boolean based on HTTP success/failure

        Returns
        -------
        dict
            a dictionary containing the JSON response
        """

        # merge default authentication headers with any user supplied ones
        dfl_headers = {AUTH_TOKEN_HEADER: 'Bearer %s' % self.access_token}
        dfl_headers.update(kwargs.pop('headers', {}))

        return http_utils.make_request(self._api_endpoint,
                                       uri,
                                       headers=dfl_headers,
                                       **kwargs)
Пример #6
0
# export F5_SDK_USERNAME='******'
# export F5_SDK_PWD='admin'
# export F5_SDK_CS_SUBSCRIPTION_ID=''
# export F5_SDK_LOG_LEVEL='DEBUG'

import os

from f5sdk.cloud_services import ManagementClient
from f5sdk.cloud_services.subscriptions import SubscriptionClient
from f5sdk.logger import Logger

LOGGER = Logger(__name__).get_logger()


def get_cs_config():
    """ Get Cloud Services configuration """
    # create management client
    cs_client = ManagementClient(
        user=os.environ['F5_SDK_USERNAME'], password=os.environ['F5_SDK_PWD'])

    # create subscription client
    subscription_client = SubscriptionClient(cs_client)

    # get subscription details
    return subscription_client.show(name=os.environ['F5_SDK_CS_SUBSCRIPTION_ID'])


if __name__ == '__main__':
    LOGGER.info(get_cs_config())
Пример #7
0
class ManagementClient(object):
    """A class used as a management client for BIG-IQ

    Attributes
    ----------
    host : str
        the hostname of the device
    port : str
        the port of the device

    Methods
    -------
    get_info()
        Refer to method documentation
    make_request()
        Refer to method documentation
    """
    def __init__(self, host, **kwargs):
        """Class initialization

        Parameters
        ----------
        host : str
            the hostname of the device
        **kwargs :
            optional keyword arguments

        Keyword Arguments
        -----------------
        port : int
            the port to assign to the port attribute
        user : str
            the username for device authentication
        password : str
            the password for device authentication

        Returns
        -------
        None
        """

        self.logger = Logger(__name__).get_logger()

        self.host = host.split(':')[0]
        self.port = kwargs.pop('port', 443)

        self._user = kwargs.pop('user', None)
        self._password = kwargs.pop('password', None)

        # account for multiple authentication schemes
        if self._user and self._password:
            self._login_using_credentials()
        else:
            raise Exception('user|password required')

    @retry(tries=constants.RETRIES['DEFAULT'],
           delay=constants.RETRIES['DELAY_IN_SECS'])
    def _get_token(self):
        """Gets authentication token

        Retries if unsuccessful, up to maximum allotment

        Parameters
        ----------
        None

        Returns
        -------
        dict
            a dictionary containing authentication token, expiration date and expiration in seconds:
            {
                'token': 'token',
                'expirationDate': '2019-01-01T01:01:01.00'
            }
        """

        self.logger.debug('Getting authentication token')

        response = http_utils.make_request(self.host,
                                           '/mgmt/shared/authn/login',
                                           port=self.port,
                                           method='POST',
                                           body={
                                               'username': self._user,
                                               'password': self._password
                                           },
                                           basic_auth={
                                               'user': self._user,
                                               'password': self._password
                                           })
        token_details = response['token']

        return {
            'token':
            token_details['token'],
            'expirationDate':
            (datetime.now() +
             timedelta(seconds=token_details['timeout'])).isoformat()
        }

    def _login_using_credentials(self):
        """Login to device using user + password

        Parameters
        ----------
        None

        Returns
        -------
        None
        """

        self.logger.info('Logging in using user + password')

        self.token = self._get_token()['token']

    @check_auth
    @add_auth_header
    def make_request(self, uri, **kwargs):
        """Makes request to device (HTTP/S)

        Parameters
        ----------
        uri : str
            the URI where the request should be made
        **kwargs :
            optional keyword arguments

        Keyword Arguments
        -----------------
        method : str
            the HTTP method to use
        headers : str
            the HTTP headers to use
        body : str
            the HTTP body to use
        body_content_type : str
            the HTTP body content type to use
        bool_response : bool
            return boolean based on HTTP success/failure
        advanced_return : bool
            return additional information, like HTTP status code to caller

        Returns
        -------
        dict
            a dictionary containing the JSON response
        """

        return http_utils.make_request(self.host,
                                       uri,
                                       port=self.port,
                                       **kwargs)

    def get_info(self):
        """Gets device info

        Parameters
        ----------
        None

        Returns
        -------
        dict
            the device information

            ::

                {
                    'version': 'x.x.x.x'
                }

        """

        response = self.make_request('/mgmt/tm/sys/version')

        version_info = response['entries'][
            'https://localhost/mgmt/tm/sys/version/0']['nestedStats'][
                'entries']
        return {'version': version_info['Version']['description']}
Пример #8
0
    Includes package installation, service check while
    maintaining idempotency
    """
    # create management client
    mgmt_client = ManagementClient(os.environ['F5_SDK_HOST'],
                                   user=os.environ['F5_SDK_USERNAME'],
                                   password=os.environ['F5_SDK_PWD'])

    # create extension client
    as3_client = ExtensionClient(mgmt_client, 'as3')

    # Get installed package version info
    version_info = as3_client.package.is_installed()
    LOGGER.info(version_info['installed'])
    LOGGER.info(version_info['installed_version'])
    LOGGER.info(version_info['latest_version'])

    # install package
    if not version_info['installed']:
        as3_client.package.install()

    # ensure service is available
    as3_client.service.is_available()

    # configure AS3
    return as3_client.service.create(config_file=os.environ['F5_SDK_AS3_DECL'])


if __name__ == '__main__':
    LOGGER.info(update_as3_config())