def test_set_log_level(uparts): pp("start test_set_log_level") real_iCRS = session.iControlRESTSession('admin', 'admin', loglevel=logging.DEBUG) with pytest.raises(ConnectionError): real_iCRS.put(uparts['base_uri'], partition='AFN', name='AIN', data={'b': 2}, uri_as_parts=True)
def disconnect(self): """disconnect the device for this particular alias""" try: log.info("Deleting token: '{t}'".format(t=self.token)) delete_url = "https://{0}:{1}/mgmt/shared/authz/tokens/{2}".format( self.ip, self.port, self.token ) delete_icr_session = iControlRESTSession( self.username, self.password, verify=self.verify, token_to_use=self.token ) # Extending the timeout for the token received delete_icr_session.delete(delete_url) log.info("Token Deleted") finally: self._is_connected = False log.info( "'{t}' token deleted successfully.".format(t=self.token) )
def __init__(self, hostname, username, password, **kwargs): timeout = kwargs.pop('timeout', 30) port = kwargs.pop('port', 443) icontrol_version = kwargs.pop('icontrol_version', '') # The BIG-IQ token is called "local", as opposed to BIG-IP's which # is called "tmos" auth_provider = kwargs.pop('auth_provider', 'local') verify = kwargs.pop('verify', False) if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs) # _meta_data variable values iCRS = iControlRESTSession(username, password, timeout=timeout, auth_provider=auth_provider, verify=verify) # define _meta_data self._meta_data = { 'allowed_lazy_attributes': [Cm, Shared, Tm], 'hostname': hostname, 'port': port, 'uri': 'https://%s:%s/mgmt/' % (hostname, port), 'icr_session': iCRS, 'device_name': None, 'local_ip': None, 'bigip': self, 'icontrol_version': icontrol_version, 'username': username, 'password': password, 'tmos_version': None, } self._get_os_version()
def invalid_token_credentials(user, password, url): '''Reusable test to make sure that we get 401 for invalid token creds ''' icr = iControlRESTSession(user, password, token=True) with pytest.raises(HTTPError) as err: icr.get(url) return (err.value.response.status_code == 401 and 'Authentication required!' in err.value.message)
def disconnect(self): """disconnect the device for this particular alias""" if self.token: try: log.info("Deleting token: '%s'", self.token) delete_url = ( f"{self.base_url}/mgmt/shared/authz/tokens/{self.token}") delete_icr_session = iControlRESTSession( self.username, self.password, verify=self.verify, token_to_use=self.token) # Revoking the token received response = delete_icr_session.delete(delete_url) if not response.ok or response.status_code != 200: log.error("Failed to delete session token for device %s", self.device.name) else: log.info( "Session token for device %s successfully deleted", self.device.name) finally: self.token = None self._is_connected = False
def invalid_credentials(user, password, url): '''Reusable test to make sure that we get 401 for invalid creds ''' icr = iControlRESTSession(user, password) with pytest.raises(HTTPError) as err: icr.get(url) return (err.value.response.status_code == 401 and '401 Client Error: F5 Authorization Required' in err.value.message)
def test_nonadmin_token_auth(opt_nonadmin_username, opt_nonadmin_password, GET_URL): if not opt_nonadmin_username or not opt_nonadmin_password: pytest.skip("No non-admin username/password configured") icr = iControlRESTSession(opt_nonadmin_username, opt_nonadmin_password, token=True) response = icr.get(GET_URL) assert response.status_code == 200
def test_token_auth_twice(opt_username, opt_password, GET_URL): icr = iControlRESTSession(opt_username, opt_password, token=True) assert icr.session.auth.attempts == 0 response = icr.get(GET_URL) assert response.status_code == 200 assert icr.session.auth.attempts == 1 response = icr.get(GET_URL) assert response.status_code == 200 # This token should still be valid, so we should reuse it. assert icr.session.auth.attempts == 1
def test_iCRS(self, mock_connect_post): iCRS = iControlRESTSession(self.username, self.password) mock_connect_post.return_value.status_code = 200 mock_connect_post.return_value = FakeResponse() response = iCRS.post(self.url, json=self.payload,) self.assertEqual(response.status_code, 200) self.assertEqual( response.json()["token"]["token"], "3UCPWZW66ZHOR6BUMVW56F6Q6K" ) self.assertEqual(response.json()["token"]["timeout"], 1200)
def iCRS(): fake_iCRS = session.iControlRESTSession('admin', 'admin') fake_iCRS.session = mock.MagicMock() mock_response = mock.MagicMock() mock_response.status_code = 200 fake_iCRS.session.delete.return_value = mock_response fake_iCRS.session.get.return_value = mock_response fake_iCRS.session.patch.return_value = mock_response fake_iCRS.session.post.return_value = mock_response fake_iCRS.session.put.return_value = mock_response return fake_iCRS
def test_delete(self, mock_connect_delete): full_url = "https://" + self.ip + "/mgmt/tm/ltm/pool/wa12" token = "3UCPWZW66ZHOR6BUMVW56F6Q6K" mock_connect_delete.return_value.status_code = 200 icr_session = iControlRESTSession(self.username, self.password, token_to_use=token) delete_icr_session = icr_session.delete(full_url) self.assertEqual(delete_icr_session.status_code, 200)
def _get_icr_session(self, *args, **kwargs): params = dict(username=kwargs['username'], password=kwargs['password'], timeout=kwargs['timeout'], verify=kwargs['verify']) if kwargs['auth_provider']: params['auth_provider'] = kwargs['auth_provider'] else: params['token'] = kwargs['token'] result = iControlRESTSession(**params) result.debug = kwargs['debug'] return result
def test_token_auth_expired(opt_username, opt_password, GET_URL): icr = iControlRESTSession(opt_username, opt_password, token=True) assert icr.session.auth.attempts == 0 response = icr.get(GET_URL) assert response.status_code == 200 assert icr.session.auth.attempts == 1 assert icr.session.auth.expiration >= time.time() # Artificially expire the token icr.session.auth.expiration = time.time() - 1.0 # Since token is expired, we should get a new one. response = icr.get(GET_URL) assert response.status_code == 200 assert icr.session.auth.attempts == 2
def _authenticate(self, timeout: int, retries: int, retry_wait: int): """ Authenticates with the device and retrieves a session token to be used in actual requests Args: timeout: The timeout to use when establishing the connection retries: How many times to retry to connect to the device if it fails retry_wait: Time in seconds to wait between retries """ # URL to authenticate and receive the token url = f"{self.base_url}/mgmt/shared/authn/login" payload = { 'username': self.username, 'password': self.password, 'loginProviderName': self._auth_provider } iCRS = iControlRESTSession(self.username, self.password, timeout=timeout, verify=self.verify) log.info("Connecting to '%s'", self.device.name) response = iCRS.post( url, json=payload, ) log.debug(response.json()) if response.status_code != 200: if b'Configuration Utility restarting...' in response.content: if retries > 0: time.sleep(retry_wait) return self._authenticate(timeout, retries - 1, retry_wait) else: raise iControlUnexpectedHTTPError( f"Failed to connect to {self.device.name}: " f"{response.content}") else: raise iControlUnexpectedHTTPError( f"Failed to authenticate with {self.device.name}") self.token = response.json()['token']['token'] log.debug("The following token is used to connect: '%s'", self.token)
def test_post(self, mock_connect_post): full_url = "https://" + self.ip + "/mgmt/tm/ltm/node/" token = "3UCPWZW66ZHOR6BUMVW56F6Q6K" mock_connect_post.return_value.status_code = 200 mock_connect_post.return_value = FakeResponsePost() icr_session = iControlRESTSession(self.username, self.password, token_to_use=token) data = { "name": "wa122", "partition": "Common", "address": "198.51.100.7" } post_icr_session = icr_session.post(full_url, json=data) output = { "kind": "tm:ltm:node:nodestate", "name": "wa122", "partition": "Common", "fullPath": "/Common/wa122", "generation": 2139, "selfLink": "https://localhost/mgmt/tm/ltm/node/~Common~wa122?ver=13.0.1", "address": "198.51.100.7", "connectionLimit": 0, "dynamicRatio": 1, "ephemeral": "false", "fqdn": { "addressFamily": "ipv4", "autopopulate": "disabled", "downInterval": 5, "interval": "3600", }, "logging": "disabled", "monitor": "default", "rateLimit": "disabled", "ratio": 1, "session": "user-enabled", "state": "unchecked", } self.assertEqual(post_icr_session.json(), output) self.assertEqual(post_icr_session.json()["name"], "wa122") self.assertEqual(post_icr_session.json()["session"], "user-enabled")
def test_put(self, mock_connect_put): full_url = "https://" + self.ip + "/mgmt/tm/ltm/pool/wa12" token = "3UCPWZW66ZHOR6BUMVW56F6Q6K" mock_connect_put.return_value.status_code = 200 mock_connect_put.return_value = FakeResponsePut() icr_session = iControlRESTSession(self.username, self.password, token_to_use=token) data = {"members": "wa122:80"} put_icr_session = icr_session.put(full_url, json=data) output = { "kind": "tm:ltm:pool:poolstate", "name": "wa12", "fullPath": "wa12", "generation": 2142, "selfLink": "https://localhost/mgmt/tm/ltm/pool/wa12?ver=13.0.1", "allowNat": "yes", "allowSnat": "yes", "ignorePersistedWeight": "disabled", "ipTosToClient": "pass-through", "ipTosToServer": "pass-through", "linkQosToClient": "pass-through", "linkQosToServer": "pass-through", "loadBalancingMode": "round-robin", "minActiveMembers": 0, "minUpMembers": 0, "minUpMembersAction": "failover", "minUpMembersChecking": "disabled", "queueDepthLimit": 0, "queueOnConnectionLimit": "disabled", "queueTimeLimit": 0, "reselectTries": 0, "serviceDownAction": "none", "slowRampTime": 10, "membersReference": { "link": "https://localhost/mgmt/tm/ltm/pool/~Common~wa12/members?ver=13.0.1", "isSubcollection": True, }, } self.assertEqual(put_icr_session.json(), output)
def test_iCRS_token(self, mock_connect_patch): token = FakeResponse().json()["token"]["token"] timeout_payload = {"timeout": "3600"} timeout_url = "https://" + self.ip + "/mgmt/shared/authz/tokens/token" mock_connect_patch.return_value.status_code = 200 mock_connect_patch.return_value = FakeResponseTimout() token_icr_session = iControlRESTSession(self.username, self.password, token_to_use=token) t_timeout = token_icr_session.patch(timeout_url, json=timeout_payload) self.assertEqual(t_timeout.json()["token"]["token"], "3UCPWZW66ZHOR6BUMVW56F6Q6K") self.assertEqual(t_timeout.json()["token"]["timeout"], 3600)
def __init__(self, hostname, username, password, **kwargs): timeout = kwargs.pop('timeout', 30) loglevel = kwargs.pop('loglevel', logging.WARNING) allowed_lazy_attrs = kwargs.pop('allowed_lazy_attributes', allowed_lazy_attributes) if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs) # _meta_data variable values iCRS = iControlRESTSession(username, password, timeout=timeout, loglevel=loglevel) # define _meta_data self._meta_data = {'allowed_lazy_attributes': allowed_lazy_attrs, 'hostname': hostname, 'uri': 'https://%s/mgmt/tm/' % hostname, 'icr_session': iCRS, 'device_name': None, 'local_ip': None, 'bigip': self}
def test_get(self, mock_connect_get): full_url = "https://" + self.ip + "/mgmt/tm/ltm/global-settings" token = "3UCPWZW66ZHOR6BUMVW56F6Q6K" mock_connect_get.return_value.status_code = 200 mock_connect_get.return_value = FakeResponseGet() icr_session = iControlRESTSession( self.username, self.password, token_to_use=token ) get_icr_session = icr_session.get(full_url) output = { "kind": "tm:ltm:global-settings:global-settingscollectionstate", "selfLink": "https://localhost/mgmt/tm/ltm/global-settings?ver=13.0.1", } self.assertEqual(get_icr_session.json(), output)
def _extend_session_ttl(self, ttl: int) -> None: """ Sets the TTL for the active session Args: ttl: The TTL to be set for the session """ # Self-link of the token timeout_url = f"{self.base_url}/mgmt/shared/authz/tokens/{self.token}" timeout_payload = {"timeout": ttl} token_icr_session = iControlRESTSession(self.username, self.password, verify=self.verify, token_to_use=self.token) # Extending the timeout for the token received response = token_icr_session.patch(timeout_url, json=timeout_payload) if response.status_code != 200 or not response.ok: raise iControlUnexpectedHTTPError( "Failed to refresh session: " f"{response.reason} ({response.status_code})") log.debug("Token TTL extended to '%d' seconds", ttl)
def __init__(self, hostname, username, password, **kwargs): timeout = kwargs.pop('timeout', 30) loglevel = kwargs.pop('loglevel', logging.WARNING) allowed_lazy_attrs = kwargs.pop('allowed_lazy_attributes', allowed_lazy_attributes) if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs) # _meta_data variable values iCRS = iControlRESTSession(username, password, timeout=timeout, loglevel=loglevel) # define _meta_data self._meta_data = { 'allowed_lazy_attributes': allowed_lazy_attrs, 'hostname': hostname, 'uri': 'https://%s/mgmt/tm/' % hostname, 'icr_session': iCRS, 'device_name': None, 'local_ip': None, 'bigip': self }
def _connect(self, timeout: int, retries: int, retry_wait: int): """ Authenticate and initiate a session with the device Args: timeout: The timeout to use when establishing the connection retries: How many times to retry to connect to the device if it fails retry_wait: Time in seconds to wait between retries """ self._authenticate(timeout, retries, retry_wait) self._extend_session_ttl(self._ttl) params = dict(username=self.username, password=self.password, verify=self.verify, token_to_use=self.token) # creating an object to be used all new requests self.icr_session = iControlRESTSession(**params) self._is_connected = True log.info("Connected successfully to '%s'", self.device.name)
def connect(self, auth_provider='tmos', verify=False, *args, **kwargs): if self.connected: return self.username, self.password = get_username_password(self) self.ip = self.connection_info["ip"].exploded self.port = self.connection_info.get("port", "443") self.base_url = "https://{ip}:{port}".format(ip=self.ip, port=self.port) self.header = "Content-Type: application/json" self.verify = verify # URL to authenticate and receive the token url = "https://{0}:{1}/mgmt/shared/authn/login".format( self.ip, self.port ) payload = { 'username': self.username, 'password': self.password, 'loginProviderName': auth_provider } iCRS = iControlRESTSession( self.username, self.password, verify=self.verify ) log.info( "Connecting to '{d}' with alias " "'{a}'".format(d=self.device.name, a=self.alias) ) response = iCRS.post( url, json=payload, ) log.info(response.json()) if response.status_code not in [200]: if b'Configuration Utility restarting...' in response.content: time.sleep(30) # self.retries += 1 return self.connect() else: # self.retries = 0 return None, response.content self.token = response.json()['token']['token'] log.info("The following toke is used to connect'{t}'".format(t=self.token)) # Self-link of the token timeout_url = "https://{0}:{1}/mgmt/shared/authz/tokens/{2}".format( self.ip, self.port, self.token ) timeout_payload = {"timeout": "3600"} token_icr_session = iControlRESTSession( self.username, self.password, verify=self.verify, token_to_use=self.token ) # Extending the timeout for the token received token_icr_session.patch(timeout_url, json=timeout_payload) log.info("'{t}' - Token timeout extended to '{time}'".format(t=self.token, time=timeout_payload)) params = dict( username=self.username, password=self.password, verify=self.verify, token_to_use=self.token ) # creating an object to be used all new requests self.icr_session = iControlRESTSession(**params) self._is_connected = True log.info("Connected successfully to '{d}' using token: '{t}'".format(d=self.device.name, t=self.token)) return self._is_connected, self.icr_session
def test_iCRS_with_invalid_construction(): with pytest.raises(TypeError) as UTE: session.iControlRESTSession('admin', 'admin', what='foble') assert UTE.value.message == "Unexpected **kwargs: {'what': 'foble'}"
def ICR(opt_bigip, opt_username, opt_password): icr = iControlRESTSession(opt_username, opt_password) return icr
def __init__(self, host, username, password, admin_username, admin_password): self.iwf = iControlRESTSession(username,password) self.iwf_admin = iControlRESTSession(admin_username,admin_password) self.host = host
def connect(self, auth_provider='tmos', verify=False, port='443', protocol='https', *args, **kwargs): if self.connected: return # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError( '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' ) try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: ip = self.device.connections[self.via].sshtunnel.tunnel_ip port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: ip = self.connection_info['ip'].exploded port = self.connection_info.get('port', port) if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.base_url = '{protocol}://{ip}:{port}'.format(protocol=protocol, ip=ip, port=port) self.username, self.password = get_username_password(self) self.header = "Content-Type: application/json" self.verify = verify # URL to authenticate and receive the token url = "https://{0}:{1}/mgmt/shared/authn/login".format( self.ip, self.port) payload = { 'username': self.username, 'password': self.password, 'loginProviderName': auth_provider } iCRS = iControlRESTSession(self.username, self.password, verify=self.verify) log.info("Connecting to '{d}' with alias " "'{a}'".format(d=self.device.name, a=self.alias)) response = iCRS.post( url, json=payload, ) log.info(response.json()) if response.status_code not in [200]: if b'Configuration Utility restarting...' in response.content: time.sleep(30) # self.retries += 1 return self.connect() else: # self.retries = 0 return None, response.content self.token = response.json()['token']['token'] log.info( "The following toke is used to connect'{t}'".format(t=self.token)) # Self-link of the token timeout_url = "https://{0}:{1}/mgmt/shared/authz/tokens/{2}".format( self.ip, self.port, self.token) timeout_payload = {"timeout": "3600"} token_icr_session = iControlRESTSession(self.username, self.password, verify=self.verify, token_to_use=self.token) # Extending the timeout for the token received token_icr_session.patch(timeout_url, json=timeout_payload) log.info("'{t}' - Token timeout extended to '{time}'".format( t=self.token, time=timeout_payload)) params = dict(username=self.username, password=self.password, verify=self.verify, token_to_use=self.token) # creating an object to be used all new requests self.icr_session = iControlRESTSession(**params) self._is_connected = True log.info("Connected successfully to '{d}' using token: '{t}'".format( d=self.device.name, t=self.token)) return self._is_connected, self.icr_session
def test_token_auth(opt_username, opt_password, GET_URL): icr = iControlRESTSession(opt_username, opt_password, token=True) response = icr.get(GET_URL) assert response.status_code == 200
import argparse #logger = logging.getLogger() #logger = logging.getLogger('requests') #logger.setLevel(logging.DEBUG) parser = argparse.ArgumentParser(description='Script to create a pool on a BIG-IP device') parser.add_argument("host", help="The IP/Hostname of the BIG-IP device",default='10.1.1.246') parser.add_argument("-a","--action",help="create/read/update/delete") parser.add_argument("--template",help="template") parser.add_argument("--tenant",help="tenant") parser.add_argument("--iapp",help="iapp") parser.add_argument("-f","--file",help="template file") args = parser.parse_args() icr_admin = iControlRESTSession('admin','admin') icr_tenant = iControlRESTSession('pcfdev','pcfdev') iwf = args.host #resp = icr_admin.get('https://%s/mgmt/cm/cloud/tenants' %(iwf)) #print pprint(resp.json()) #resp = icr_admin.get('https://%s/mgmt/cm/cloud/connectors/local' %(iwf)) #print pprint(resp.json()) if args.action == 'list_templates': resp = icr_admin.get('https://%s/mgmt/cm/cloud/provider/templates/iapp' %(iwf)) data = resp.json() for item in data['items']: print item['templateName'] if args.action == 'export_template': resp = icr_admin.get('https://%s/mgmt/cm/cloud/provider/templates/iapp/%s' %(iwf,args.template))
#logger = logging.getLogger('requests') #logger.setLevel(logging.DEBUG) parser = argparse.ArgumentParser( description='Script to create a pool on a BIG-IP device') parser.add_argument("host", help="The IP/Hostname of the BIG-IP device", default='10.1.1.246') parser.add_argument("-a", "--action", help="create/read/update/delete") parser.add_argument("--template", help="template") parser.add_argument("--tenant", help="tenant") parser.add_argument("--iapp", help="iapp") parser.add_argument("-f", "--file", help="template file") args = parser.parse_args() icr_admin = iControlRESTSession('admin', 'admin') icr_tenant = iControlRESTSession('pcfdev', 'pcfdev') iwf = args.host #resp = icr_admin.get('https://%s/mgmt/cm/cloud/tenants' %(iwf)) #print pprint(resp.json()) #resp = icr_admin.get('https://%s/mgmt/cm/cloud/connectors/local' %(iwf)) #print pprint(resp.json()) if args.action == 'list_templates': resp = icr_admin.get('https://%s/mgmt/cm/cloud/provider/templates/iapp' % (iwf)) data = resp.json() for item in data['items']: print item['templateName'] if args.action == 'export_template':
def __init__(self, host, username, password, admin_username, admin_password): self.iwf = iControlRESTSession(username, password) self.iwf_admin = iControlRESTSession(admin_username, admin_password) self.host = host