def test_avi_obj_cmp_w_refs_n_name(self): existing_obj = { 'use_service_port': False, 'server_auto_scale': False, 'host_check_enabled': False, 'enabled': True, 'capacity_estimation': False, 'fewest_tasks_feedback_delay': 10, '_last_modified': '1471377748747040', 'cloud_ref': 'https://10.130.2.252/api/cloud/cloud-afe8bf2c-9821-4272-9bc6-67634c84bec9', 'vrf_ref': 'https://10.130.2.252/api/vrfcontext/vrfcontext-0e8ce760-fed2-4650-9397-5b3e4966376e', 'inline_health_monitor': True, 'default_server_port': 80, 'request_queue_depth': 128, 'graceful_disable_timeout': 1, 'server_count': 0, 'sni_enabled': True, 'request_queue_enabled': False, 'name': 'testpool', 'max_concurrent_connections_per_server': 0, 'url': 'https://10.130.2.252/api/pool/pool-20084ee1-872e-4103-98e1-899103e2242a', 'tenant_ref': 'https://10.130.2.252/api/tenant/admin', 'uuid': 'pool-20084ee1-872e-4103-98e1-899103e2242a', 'connection_ramp_duration': 10, 'health_monitor_refs': [ "https://10.130.2.252/api/healthmonitor/healthmonitor-6d07b57f-126b-476c-baba-a8c8c8b06dc9#System-HTTP", "https://10.130.2.252/api/healthmonitor/healthmonitor-6d07b57f-126b-476c-baba-a8c8c8b06dc8", ], } obj = {'name': 'testpool', 'health_monitor_refs': ['https://10.130.2.252/api/healthmonitor/healthmonitor-6d07b57f-126b-476c-baba-a8c8c8b06dc9', "https://10.130.2.252/api/healthmonitor/healthmonitor-6d07b57f-126b-476c-baba-a8c8c8b06dc8"], 'server_count': 0} diff = avi_obj_cmp(obj, existing_obj) assert diff obj = {'name': 'testpool', 'health_monitor_refs': [ 'https://10.130.2.252/api/healthmonitor/healthmonitor-6d07b57f-126b-476c-baba-a8c8c8b06dc9#System-HTTP', "https://10.130.2.252/api/healthmonitor/healthmonitor-6d07b57f-126b-476c-baba-a8c8c8b06dc8"], 'server_count': 0} diff = avi_obj_cmp(obj, existing_obj) assert diff obj = {'name': 'testpool', 'health_monitor_refs': [ 'https://10.130.2.252/api/healthmonitor/healthmonitor-6d07b57f-126b-476c-baba-a8c8c8b06dc9#System-HTTP', "https://10.130.2.252/api/healthmonitor/healthmonitor-6d07b57f-126b-476c-baba-a8c8c8b06dc8#System-HTTP2"], 'server_count': 0, 'cloud_ref': 'https://10.130.2.252/api/cloud/cloud-afe8bf2c-9821-4272-9bc6-67634c84bec9#Default-Cloud', } diff = avi_obj_cmp(obj, existing_obj) assert diff
def test_avi_list_update(self): existing_obj = { 'services': [ { "enable_ssl": False, "port_range_end": 80, "port": 80 }, { "enable_ssl": False, "port_range_end": 443, "port": 443 } ], "name": "vs-health-test", "url": "https://10.10.25.42/api/virtualservice/virtualservice-526c55c2-df89-40b9-9de6-e45a472290aa", } obj = { 'services': [ { "enable_ssl": False, "port_range_end": 80, "port": 80 } ] } diff = avi_obj_cmp(obj, existing_obj) assert not diff obj = { 'services': [ { "enable_ssl": False, "port_range_end": 80, "port": 80 }, { "enable_ssl": False, "port_range_end": 443, "port": None } ], "name": "vs-health-test", "url": "https://10.10.25.42/api/virtualservice/virtualservice-526c55c2-df89-40b9-9de6-e45a472290aa", } diff = avi_obj_cmp(obj, existing_obj) assert not diff
def test_avi_list_update(self): existing_obj = { 'services': [ { "enable_ssl": False, "port_range_end": 80, "port": 80 }, { "enable_ssl": False, "port_range_end": 443, "port": 443 } ], "name": "vs-health-test", "url": "https://10.10.25.42/api/virtualservice/virtualservice-526c55c2-df89-40b9-9de6-e45a472290aa", } obj = { 'services': [ { "enable_ssl": False, "port_range_end": 80, "port": 80 } ] } diff = avi_obj_cmp(obj, existing_obj) assert not diff obj = { 'services': [ { "enable_ssl": False, "port_range_end": 80, "port": 80 }, { "enable_ssl": False, "port_range_end": 443, "port": 80 } ], "name": "vs-health-test", "url": "https://10.10.25.42/api/virtualservice/virtualservice-526c55c2-df89-40b9-9de6-e45a472290aa", } diff = avi_obj_cmp(obj, existing_obj) assert not diff
def test_avi_obj_cmp(self): obj = {'name': 'testpool'} existing_obj = { 'lb_algorithm': 'LB_ALGORITHM_LEAST_CONNECTIONS', 'use_service_port': False, 'server_auto_scale': False, 'host_check_enabled': False, 'enabled': True, 'capacity_estimation': False, 'fewest_tasks_feedback_delay': 10, '_last_modified': '1471377748747040', 'cloud_ref': 'https://10.130.2.252/api/cloud/cloud-afe8bf2c-9821-4272-9bc6-67634c84bec9', 'vrf_ref': 'https://10.130.2.252/api/vrfcontext/vrfcontext-0e8ce760-fed2-4650-9397-5b3e4966376e', 'inline_health_monitor': True, 'default_server_port': 80, 'request_queue_depth': 128, 'graceful_disable_timeout': 1, 'server_count': 0, 'sni_enabled': True, 'request_queue_enabled': False, 'name': 'testpool', 'max_concurrent_connections_per_server': 0, 'url': 'https://10.130.2.252/api/pool/pool-20084ee1-872e-4103-98e1-899103e2242a', 'tenant_ref': 'https://10.130.2.252/api/tenant/admin', 'uuid': 'pool-20084ee1-872e-4103-98e1-899103e2242a', 'connection_ramp_duration': 10} diff = avi_obj_cmp(obj, existing_obj) assert diff x = not diff assert not x
def test_avi_obj_cmp_empty_list(self): obj = {'name': 'testpool', 'health_monitor_refs': [], 'enabled': True} existing_obj = { 'lb_algorithm': 'LB_ALGORITHM_LEAST_CONNECTIONS', 'use_service_port': False, 'server_auto_scale': False, 'host_check_enabled': False, 'enabled': True, 'capacity_estimation': False, 'fewest_tasks_feedback_delay': 10, '_last_modified': u'1471377748747040', 'cloud_ref': u'https://10.130.2.252/api/cloud/cloud-afe8bf2c-9821-4272-9bc6-67634c84bec9', 'vrf_ref': u'https://10.130.2.252/api/vrfcontext/vrfcontext-0e8ce760-fed2-4650-9397-5b3e4966376e', 'inline_health_monitor': True, 'default_server_port': 80, 'request_queue_depth': 128, 'graceful_disable_timeout': 1, 'server_count': 0, 'sni_enabled': True, 'request_queue_enabled': False, 'name': u'testpool', 'max_concurrent_connections_per_server': 0, 'url': 'https://10.130.2.252/api/pool/pool-20084ee1-872e-4103-98e1-899103e2242a', 'tenant_ref': u'https://10.130.2.252/api/tenant/admin', 'uuid': u'pool-20084ee1-872e-4103-98e1-899103e2242a', 'connection_ramp_duration': 10 } diff = avi_obj_cmp(obj, existing_obj) assert diff
def testhttppolicy(self): existing_obj = { "http_request_policy": { "rules": [ {"enable": True, "index": 0, "match": { "path": { "match_case": "INSENSITIVE", "match_criteria": "CONTAINS", "match_str": [ "xvz", "rst" ] } }, "name": "blah", "switching_action": { "action": "HTTP_SWITCHING_SELECT_POOL", "pool_ref": "https://12.97.16.202/api/pool/pool-d7f6f5e7-bd26-49ad-aeed-965719eb140b#abc", "status_code": "HTTP_LOCAL_RESPONSE_STATUS_CODE_200" } } ] }, "is_internal_policy": False, "name": "blah", "tenant_ref": "https://12.97.16.202/api/tenant/tenant-f52f7a3e-6876-4bb9-b8f7-3cab636dadf2#Sales", "url": "https://12.97.16.202/api/httppolicyset/httppolicyset-ffd8354b-671b-48d5-92cc-69a9057aad0c#blah", "uuid": "httppolicyset-ffd8354b-671b-48d5-92cc-69a9057aad0c" } obj = { "http_request_policy": { "rules": [ {"enable": True, "index": "0", "match": { "path": { "match_case": "INSENSITIVE", "match_criteria": "CONTAINS", "match_str": [ "xvz", "rst" ] }}, "name": "blah", "switching_action": { "action": "HTTP_SWITCHING_SELECT_POOL", "pool_ref": "/api/pool?name=abc", "status_code": "HTTP_LOCAL_RESPONSE_STATUS_CODE_200" } } ] }, "is_internal_policy": False, "tenant": "Sales" } diff = avi_obj_cmp(obj, existing_obj) assert diff
def add_member(module, check_mode, api, tenant, tenant_uuid, existing_obj, data, name, api_version): rsp = None if not existing_obj: # create the object changed = True if check_mode: rsp = AviCheckModeResponse(obj=None) else: # creates group with single member req = {'name': name, 'groups': [data['group']] } # added api version for AVI api call. rsp = api.post('gslbservice', data=req, tenant=tenant, tenant_uuid=tenant_uuid, api_version=api_version) else: # found GSLB object req = deepcopy(existing_obj) if 'groups' not in req: req['groups'] = [] groups = [group for group in req['groups'] if group['name'] == data['group']['name']] if not groups: # did not find the group req['groups'].append(data['group']) else: # just update the existing group with members group = groups[0] group_info_wo_members = deepcopy(data['group']) group_info_wo_members.pop('members', None) group.update(group_info_wo_members) if 'members' not in group: group['members'] = [] new_members = [] for patch_member in data['group'].get('members', []): found = False for m in group['members']: if 'fqdn' in patch_member and m.get('fqdn', '') == patch_member['fqdn']: found = True break elif m['ip']['addr'] == patch_member['ip']['addr']: found = True break if not found: new_members.append(patch_member) else: m.update(patch_member) # add any new members group['members'].extend(new_members) cleanup_absent_fields(req) changed = not avi_obj_cmp(req, existing_obj) if changed and not check_mode: obj_path = '%s/%s' % ('gslbservice', existing_obj['uuid']) # added api version for AVI api call. rsp = api.put(obj_path, data=req, tenant=tenant, tenant_uuid=tenant_uuid, api_version=api_version) return changed, rsp
def testNoneParams(self): objwnone = {'name': 'testpool', 'scalar_field': None, 'list_fields': {'y': None, 'z': 'zz'}} obj = {'name': 'testpool', 'list_fields': {'z': 'zz'}} result = avi_obj_cmp(objwnone, obj) assert result
def testNoneParams(self): objwnone = { 'name': 'testpool', 'scalar_field': None, 'list_fields': { 'y': None, 'z': 'zz' } } obj = {'name': 'testpool', 'list_fields': {'z': 'zz'}} result = avi_obj_cmp(objwnone, obj) assert result
def testAWSVs(self): existing_obj = {'network_profile_ref': 'https://12.97.16.202/api/networkprofile/networkprofile-9a0a9896-6876-44c8-a3ee-512a968905f2#System-TCP-Proxy', 'port_uuid': 'eni-4144e73c', 'weight': 1, 'availability_zone': 'us-west-2a', 'enabled': True, 'flow_dist': 'LOAD_AWARE', 'subnet_uuid': 'subnet-91f0b6f4', 'delay_fairness': False, 'avi_allocated_vip': True, 'vrf_context_ref': 'https://12.97.16.202/api/vrfcontext/vrfcontext-722b280d-b555-4d82-9b35-af9442c0cb86#global', 'subnet': {'ip_addr': {'type': 'V4', 'addr': '10.144.0.0'}, 'mask': 24}, 'cloud_type': 'CLOUD_AWS', 'uuid': 'virtualservice-a5f49b99-22c8-42e6-aa65-3ca5f1e36b9e', 'network_ref': 'https://12.97.16.202/api/network/subnet-91f0b6f4', 'cloud_ref': 'https://12.97.16.202/api/cloud/cloud-49829414-c704-43ca-9dff-05b9e8474dcb#AWS Cloud', 'avi_allocated_fip': False, 'se_group_ref': 'https://12.97.16.202/api/serviceenginegroup/serviceenginegroup-3bef6320-5a2d-4801-85c4-ef4f9841f235#Default-Group', 'scaleout_ecmp': False, 'max_cps_per_client': 0, 'type': 'VS_TYPE_NORMAL', 'analytics_profile_ref': 'https://12.97.16.202/api/analyticsprofile/analyticsprofile-70f8b06f-7b6a-4500-b829-c869bbca2009#System-Analytics-Profile', 'use_bridge_ip_as_vip': False, 'application_profile_ref': 'https://12.97.16.202/api/applicationprofile/applicationprofile-103cbc31-cac5-46ab-8e66-bbbb2c8f551f#System-HTTP', 'auto_allocate_floating_ip': False, 'services': [{'enable_ssl': False, 'port_range_end': 80, 'port': 80}], 'active_standby_se_tag': 'ACTIVE_STANDBY_SE_1', 'ip_address': {'type': 'V4', 'addr': '10.144.0.33'}, 'ign_pool_net_reach': False, 'east_west_placement': False, 'limit_doser': False, 'name': 'wwwawssit.ebiz.verizon.com', 'url': 'https://12.97.16.202/api/virtualservice/virtualservice-a5f49b99-22c8-42e6-aa65-3ca5f1e36b9e#wwwawssit.ebiz.verizon.com', 'ssl_sess_cache_avg_size': 1024, 'enable_autogw': True, 'auto_allocate_ip': True, 'tenant_ref': 'https://12.97.16.202/api/tenant/tenant-f52f7a3e-6876-4bb9-b8f7-3cab636dadf2#Sales', 'remove_listening_port_on_vs_down': False } obj = {'auto_allocate_ip': True, 'subnet_uuid': 'subnet-91f0b6f4', 'cloud_ref': '/api/cloud?name=AWS Cloud', 'services': [{'port': 80}], 'name': 'wwwawssit.ebiz.verizon.com'} diff = avi_obj_cmp(obj, existing_obj) assert diff
def testGSLB(self): obj = { 'domain_names': ['cloud5.avi.com', 'cloud6.avi.com'], 'health_monitor_scope': 'GSLB_SERVICE_HEALTH_MONITOR_ALL_MEMBERS', 'groups': [{'priority': 20, 'members': [{'ip': {'type': 'V4', 'addr': '10.30.10.1'}, 'enabled': True, 'ratio': 1}, {'ip': {'type': 'V4', 'addr': '10.30.10.10'}, 'enabled': True, 'ratio': 1}], 'algorithm': 'GSLB_ALGORITHM_CONSISTENT_HASH', 'name': 'sc'}, {'priority': 14, 'members': [{'ip': {'type': 'V4', 'addr': '10.30.10.2'}, 'enabled': True, 'ratio': 1}], 'algorithm': 'GSLB_ALGORITHM_ROUND_ROBIN', 'name': 'cn'}, {'priority': 15, 'members': [{'ip': {'type': 'V4', 'addr': '10.30.10.3'}, 'enabled': True, 'ratio': 1}], 'algorithm': 'GSLB_ALGORITHM_ROUND_ROBIN', 'name': 'in'}], 'name': 'gs-3', 'num_dns_ip': 2} existing_obj = { u'controller_health_status_enabled': True, u'uuid': u'gslbservice-ab9b36bd-3e95-4c2e-80f8-92905c2eccb2', u'wildcard_match': False, u'url': u'https://10.10.25.20/api/gslbservice/gslbservice-ab9b36bd-3e95-4c2e-80f8-92905c2eccb2#gs-3', u'tenant_ref': u'https://10.10.25.20/api/tenant/admin#admin', u'enabled': True, u'domain_names': [u'cloud5.avi.com', u'cloud6.avi.com'], u'use_edns_client_subnet': True, u'groups': [{u'priority': 20, u'members': [{u'ip': {u'type': u'V4', u'addr': u'10.30.10.1'}, u'ratio': 1, u'enabled': True}, {u'ip': {u'type': u'V4', u'addr': u'10.30.10.10'}, u'ratio': 1, u'enabled': True}], u'name': u'sc', u'algorithm': u'GSLB_ALGORITHM_CONSISTENT_HASH'}, {u'priority': 14, u'members': [{u'ip': {u'type': u'V4', u'addr': u'10.30.10.2'}, u'ratio': 1, u'enabled': True}], u'name': u'cn', u'algorithm': u'GSLB_ALGORITHM_ROUND_ROBIN'}, {u'priority': 15, u'members': [{u'ip': {u'type': u'V4', u'addr': u'10.30.10.3'}, u'ratio': 1, u'enabled': True}], u'name': u'in', u'algorithm': u'GSLB_ALGORITHM_ROUND_ROBIN'}], u'num_dns_ip': 2, u'health_monitor_scope': u'GSLB_SERVICE_HEALTH_MONITOR_ALL_MEMBERS', u'name': u'gs-3'} diff = avi_obj_cmp(obj, existing_obj) assert diff
def test_complex_obj(self): obj = { 'lb_algorithm': 'LB_ALGORITHM_ROUND_ROBIN', 'use_service_port': False, 'server_auto_scale': False, 'host_check_enabled': False, 'tenant_ref': 'https://10.10.25.42/api/tenant/admin#admin', 'capacity_estimation': False, 'servers': [ {'hostname': 'grastogi-server6', 'ratio': 1, 'ip': {'type': 'V4', 'addr': '10.90.64.62'}, 'discovered_networks': [ {'subnet': [ {'ip_addr': { 'type': 'V4', 'addr': '10.90.64.0'}, 'mask': 24}], 'network_ref': 'https://10.10.25.42/api/network/dvportgroup-53975-10.10.2.10#PG-964'}], 'enabled': True, 'nw_ref': 'https://10.10.25.42/api/vimgrnwruntime/dvportgroup-53975-10.10.2.10#PG-964', 'verify_network': False, 'static': False, 'resolve_server_by_dns': False, 'external_uuid': 'vm-4230615e-bc0b-3d33-3929-1c7328575993', 'vm_ref': 'https://10.10.25.42/api/vimgrvmruntime/vm-4230615e-bc0b-3d33-3929-1c7328575993#grastogi-server6'}, {'hostname': 'grastogi-server6', 'ratio': 1, 'ip': {'type': 'V4', 'addr': '10.90.64.61'}, 'discovered_networks': [{'subnet': [{'ip_addr': {'type': 'V4', 'addr': '10.90.64.0'}, 'mask': 24}], 'network_ref': 'https://10.10.25.42/api/network/dvportgroup-53975-10.10.2.10#PG-964'}], 'enabled': True, 'nw_ref': 'https://10.10.25.42/api/vimgrnwruntime/dvportgroup-53975-10.10.2.10#PG-964', 'verify_network': False, 'static': False, 'resolve_server_by_dns': False, 'external_uuid': 'vm-4230615e-bc0b-3d33-3929-1c7328575993', 'vm_ref': 'https://10.10.25.42/api/vimgrvmruntime/vm-4230615e-bc0b-3d33-3929-1c7328575993#grastogi-server6'}, {'hostname': 'grastogi-server6', 'ratio': 1, 'ip': {'type': 'V4', 'addr': '10.90.64.65'}, 'discovered_networks': [{'subnet': [{'ip_addr': {'type': 'V4', 'addr': '10.90.64.0'}, 'mask': 24}], 'network_ref': 'https://10.10.25.42/api/network/dvportgroup-53975-10.10.2.10#PG-964'}], 'enabled': True, 'verify_network': False, 'static': False, 'resolve_server_by_dns': False}], 'fewest_tasks_feedback_delay': 10, '_last_modified': '1473292763246107', 'cloud_ref': 'https://10.10.25.42/api/cloud/cloud-e0696a58-8b72-4026-923c-9a87c38a2489#Default-Cloud', 'vrf_ref': 'https://10.10.25.42/api/vrfcontext/vrfcontext-33dfbcd7-867c-4e3e-acf7-96bf679d5a0d#global', 'inline_health_monitor': True, 'default_server_port': 8000, 'request_queue_depth': 128, 'graceful_disable_timeout': 1, 'sni_enabled': True, 'server_count': 3, 'uuid': 'pool-09201181-747e-41ea-872d-e9a7df71b726', 'request_queue_enabled': False, 'name': 'p1', 'max_concurrent_connections_per_server': 0, 'url': 'https://10.10.25.42/api/pool/pool-09201181-747e-41ea-872d-e9a7df71b726#p1', 'enabled': True, 'connection_ramp_duration': 10} existing_obj = { 'lb_algorithm': 'LB_ALGORITHM_ROUND_ROBIN', 'use_service_port': False, 'server_auto_scale': False, 'host_check_enabled': False, 'tenant_ref': 'https://10.10.25.42/api/tenant/admin', 'capacity_estimation': False, 'servers': [ {'hostname': 'grastogi-server6', 'ratio': 1, 'ip': {'type': 'V4', 'addr': '10.90.64.62'}, 'discovered_networks': [ {'subnet': [ {'mask': 24, 'ip_addr': { 'type': 'V4', 'addr': '10.90.64.0'}}], 'network_ref': 'https://10.10.25.42/api/network/dvportgroup-53975-10.10.2.10'}], 'enabled': True, 'nw_ref': 'https://10.10.25.42/api/vimgrnwruntime/dvportgroup-53975-10.10.2.10', 'verify_network': False, 'static': False, 'resolve_server_by_dns': False, 'external_uuid': 'vm-4230615e-bc0b-3d33-3929-1c7328575993', 'vm_ref': 'https://10.10.25.42/api/vimgrvmruntime/vm-4230615e-bc0b-3d33-3929-1c7328575993'}, {'hostname': 'grastogi-server6', 'ratio': 1, 'ip': {'type': 'V4', 'addr': '10.90.64.61'}, 'discovered_networks': [{'subnet': [{'mask': 24, 'ip_addr': {'type': 'V4', 'addr': '10.90.64.0'}}], 'network_ref': 'https://10.10.25.42/api/network/dvportgroup-53975-10.10.2.10'}], 'enabled': True, 'nw_ref': 'https://10.10.25.42/api/vimgrnwruntime/dvportgroup-53975-10.10.2.10', 'verify_network': False, 'static': False, 'resolve_server_by_dns': False, 'external_uuid': 'vm-4230615e-bc0b-3d33-3929-1c7328575993', 'vm_ref': 'https://10.10.25.42/api/vimgrvmruntime/vm-4230615e-bc0b-3d33-3929-1c7328575993'}, {'hostname': 'grastogi-server6', 'ratio': 1, 'ip': {'type': 'V4', 'addr': '10.90.64.65'}, 'discovered_networks': [{'subnet': [{'mask': 24, 'ip_addr': {'type': 'V4', 'addr': '10.90.64.0'}}], 'network_ref': 'https://10.10.25.42/api/network/dvportgroup-53975-10.10.2.10'}], 'enabled': True, 'nw_ref': 'https://10.10.25.42/api/vimgrnwruntime/dvportgroup-53975-10.10.2.10', 'verify_network': False, 'static': False, 'resolve_server_by_dns': False, 'external_uuid': 'vm-4230615e-bc0b-3d33-3929-1c7328575993', 'vm_ref': 'https://10.10.25.42/api/vimgrvmruntime/vm-4230615e-bc0b-3d33-3929-1c7328575993'}], 'fewest_tasks_feedback_delay': 10, 'cloud_ref': 'https://10.10.25.42/api/cloud/cloud-e0696a58-8b72-4026-923c-9a87c38a2489', 'vrf_ref': 'https://10.10.25.42/api/vrfcontext/vrfcontext-33dfbcd7-867c-4e3e-acf7-96bf679d5a0d', 'inline_health_monitor': True, 'default_server_port': 8000, 'request_queue_depth': 128, 'graceful_disable_timeout': 1, 'sni_enabled': True, 'server_count': 3, 'uuid': 'pool-09201181-747e-41ea-872d-e9a7df71b726', 'request_queue_enabled': False, 'name': 'p1', 'max_concurrent_connections_per_server': 0, 'url': 'https://10.10.25.42/api/pool/pool-09201181-747e-41ea-872d-e9a7df71b726', 'enabled': True, 'connection_ramp_duration': 10} diff = avi_obj_cmp(obj, existing_obj) assert diff
def main(): argument_specs = dict( http_method=dict(required=True, choices=['get', 'put', 'post', 'patch', 'delete']), path=dict(type='str', required=True), params=dict(type='dict'), data=dict(type='jsonarg'), timeout=dict(type='int', default=60) ) argument_specs.update(avi_common_argument_spec()) module = AnsibleModule(argument_spec=argument_specs) if not HAS_AVI: return module.fail_json(msg=( 'Avi python API SDK (avisdk) is not installed. ' 'For more details visit https://github.com/avinetworks/sdk.')) tenant_uuid = module.params.get('tenant_uuid', None) api = ApiSession.get_session( module.params['controller'], module.params['username'], module.params['password'], tenant=module.params['tenant'], tenant_uuid=tenant_uuid) tenant = module.params.get('tenant', '') timeout = int(module.params.get('timeout')) # path is a required argument path = module.params.get('path', '') params = module.params.get('params', None) data = module.params.get('data', None) # Get the api_version from module. api_version = module.params.get('api_version', '16.4') if data is not None: data = json.loads(data) method = module.params['http_method'] existing_obj = None changed = method != 'get' gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) if method == 'post': # need to check if object already exists. In that case # change the method to be put gparams['name'] = data['name'] rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) try: existing_obj = rsp.json()['results'][0] except IndexError: # object is not found pass else: # object is present method = 'put' path += '/' + existing_obj['uuid'] if method == 'put': # put can happen with when full path is specified or it is put + post if existing_obj is None: using_collection = False if (len(path.split('/')) == 1) and ('name' in data): gparams['name'] = data['name'] using_collection = True rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) rsp_data = rsp.json() if using_collection: if rsp_data['results']: existing_obj = rsp_data['results'][0] path += '/' + existing_obj['uuid'] else: method = 'post' else: if rsp.status_code == 404: method = 'post' else: existing_obj = rsp_data if existing_obj: changed = not avi_obj_cmp(data, existing_obj) cleanup_absent_fields(data) if method == 'patch': rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) existing_obj = rsp.json() if (method == 'put' and changed) or (method != 'put'): fn = getattr(api, method) rsp = fn(path, tenant=tenant, tenant_uuid=tenant, timeout=timeout, params=params, data=data, api_version=api_version) else: rsp = None if method == 'delete' and rsp.status_code == 404: changed = False rsp.status_code = 200 if method == 'patch' and existing_obj and rsp.status_code < 299: # Ideally the comparison should happen with the return values # from the patch API call. However, currently Avi API are # returning different hostname when GET is used vs Patch. # tracked as AV-12561 if path.startswith('pool'): time.sleep(1) gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) new_obj = rsp.json() changed = not avi_obj_cmp(new_obj, existing_obj) if rsp is None: return module.exit_json(changed=changed, obj=existing_obj) return ansible_return(module, rsp, changed, req=data)
def main(): argument_specs = dict( state=dict(default='present', choices=['absent', 'present']), avi_api_update_method=dict(default='put', choices=['put', 'patch']), avi_api_patch_op=dict(choices=['add', 'replace', 'delete']), allow_mode_delegation=dict(type='bool', ), created_by=dict(type='str', ), crs_groups=dict(type='list', ), description=dict(type='str', ), enable_app_learning=dict(type='bool', ), failure_mode=dict(type='str', ), learning=dict(type='dict', ), mode=dict(type='str'), name=dict(type='str', required=True), paranoia_level=dict(type='str', ), positive_security_model=dict(type='dict', ), post_crs_groups=dict(type='list', ), pre_crs_groups=dict(type='list', ), tenant_ref=dict(type='str', ), url=dict(type='str', ), uuid=dict(type='str', ), waf_crs_ref=dict(type='str', ), waf_profile_ref=dict(type='str'), whitelist=dict(type='dict', ), base_waf_policy=dict(type='str', required=True), patch_file=dict(type='str', required=True), ) argument_specs.update(avi_common_argument_spec()) module = AnsibleModule(argument_spec=argument_specs, supports_check_mode=True) if not HAS_AVI: return module.fail_json(msg=( 'Avi python API SDK (avisdk>=17.1) or requests is not installed. ' 'For more details visit https://github.com/avinetworks/sdk.')) api_creds = AviCredentials() api_creds.update_from_ansible_module(module) api = ApiSession.get_session(api_creds.controller, api_creds.username, password=api_creds.password, timeout=api_creds.timeout, tenant=api_creds.tenant, tenant_uuid=api_creds.tenant_uuid, token=api_creds.token, port=api_creds.port, api_version=api_creds.api_version) obj_uuid = None existing_obj = api.get_object_by_name('wafpolicy', module.params.get('name'), params={"include_name": True}) if existing_obj: obj_uuid = existing_obj.pop('uuid', None) changed = False # Delete call if state is absent if module.params.get('state') == 'absent': if obj_uuid: changed = True if changed and not module.check_mode: api.delete_by_name('wafpolicy', module.params.get('name')) ansible_return(module, None, changed, existing_obj=existing_obj, api_context=api.get_context()) if not existing_obj: existing_obj = api.get_object_by_name( 'wafpolicy', module.params.get('base_waf_policy'), params={"include_name": True}) with open(module.params.get('patch_file'), "r+") as f: waf_patch = json.loads(f.read()) waf_patch.update((k, v) for k, v in module.params.items() if v and k not in waf_patch) new_obj = deepcopy(existing_obj) update_patch(new_obj, waf_patch) changed = not avi_obj_cmp(new_obj, existing_obj) if module.check_mode: ansible_return(module, None, changed, existing_obj=existing_obj, api_context=api.get_context()) rsp = None if changed: if obj_uuid: new_obj['uuid'] = obj_uuid rsp = api.put('wafpolicy/%s' % obj_uuid, data=new_obj) else: rsp = api.post('wafpolicy', data=new_obj) ansible_return(module, rsp, changed, req=new_obj)
def main(): argument_specs = dict(http_method=dict( required=True, choices=['get', 'put', 'post', 'patch', 'delete']), path=dict(type='str', required=True), params=dict(type='dict'), data=dict(type='jsonarg'), timeout=dict(type='int', default=60)) argument_specs.update(avi_common_argument_spec()) module = AnsibleModule(argument_spec=argument_specs) if not HAS_AVI: return module.fail_json(msg=( 'Avi python API SDK (avisdk>=17.1) or requests is not installed. ' 'For more details visit https://github.com/avinetworks/sdk.')) api_creds = AviCredentials() api_creds.update_from_ansible_module(module) api = ApiSession.get_session(api_creds.controller, api_creds.username, password=api_creds.password, timeout=api_creds.timeout, tenant=api_creds.tenant, tenant_uuid=api_creds.tenant_uuid, token=api_creds.token, port=api_creds.port) tenant_uuid = api_creds.tenant_uuid tenant = api_creds.tenant timeout = int(module.params.get('timeout')) # path is a required argument path = module.params.get('path', '') params = module.params.get('params', None) data = module.params.get('data', None) # Get the api_version from module. api_version = api_creds.api_version if data is not None: data = json.loads(data) method = module.params['http_method'] existing_obj = None changed = method != 'get' gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) # API methods not allowed api_get_not_allowed = ["cluster", "gslbsiteops", "server", "nsxt"] sub_api_get_not_allowed = ["scaleout", "scalein", "upgrade", "rollback"] api_post_not_allowed = ["alert", "fileservice"] api_put_not_allowed = ["backup"] if method == 'post' and not any( path.startswith(uri) for uri in api_post_not_allowed): # TODO: Above condition should be updated after AV-38981 is fixed # need to check if object already exists. In that case # change the method to be put try: using_collection = False if (not any(path.startswith(uri) for uri in api_get_not_allowed) and not any( path.endswith(uri) for uri in sub_api_get_not_allowed)): if 'name' in data: gparams['name'] = data['name'] using_collection = True if (not any(path.startswith(uri) for uri in api_get_not_allowed) and not any( path.endswith(uri) for uri in sub_api_get_not_allowed)): rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) existing_obj = rsp.json() if using_collection: existing_obj = existing_obj['results'][0] except (IndexError, KeyError): # object is not found pass else: if (not any(path.startswith(uri) for uri in api_get_not_allowed) and not any( path.endswith(uri) for uri in sub_api_get_not_allowed)): # object is present method = 'put' path += '/' + existing_obj['uuid'] if method == 'put' and not any( path.startswith(uri) for uri in api_put_not_allowed): # put can happen with when full path is specified or it is put + post get_path = path data_for_cmp = data if existing_obj is None: using_collection = False if ((len(path.split('/')) == 1) and ('name' in data) and (not any(path.startswith(uri) for uri in api_get_not_allowed))): gparams['name'] = data['name'] using_collection = True if path.startswith('wafpolicy') and path.endswith( 'update-crs-rules'): get_path = path.rstrip('/update-crs-rules') data_for_cmp = deepcopy(data) if data else {} _ = data_for_cmp.pop("commit", None) rsp = api.get(get_path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) rsp_data = rsp.json() if using_collection: if rsp_data['results']: existing_obj = rsp_data['results'][0] path += '/' + existing_obj['uuid'] else: method = 'post' else: if rsp.status_code == 404: method = 'post' else: existing_obj = rsp_data if existing_obj: changed = not avi_obj_cmp(data_for_cmp, existing_obj) cleanup_absent_fields(data) if method == 'patch': rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) existing_obj = rsp.json() if (method == 'put' and changed) or (method != 'put'): fn = getattr(api, method) rsp = fn(path, tenant=tenant, tenant_uuid=tenant, timeout=timeout, params=params, data=data, api_version=api_version) else: rsp = None if method == 'delete' and rsp.status_code == 404: changed = False rsp.status_code = 200 if method == 'patch' and existing_obj and rsp.status_code < 299: # Ideally the comparison should happen with the return values # from the patch API call. However, currently Avi API are # returning different hostname when GET is used vs Patch. # tracked as AV-12561 if path.startswith('pool'): time.sleep(1) gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) new_obj = rsp.json() changed = not avi_obj_cmp(new_obj, existing_obj) if rsp is None: return module.exit_json(changed=changed, obj=existing_obj) return ansible_return(module, rsp, changed, req=data)
def main(): argument_specs = dict(http_method=dict( required=True, choices=['get', 'put', 'post', 'patch', 'delete']), path=dict(type='str', required=True), params=dict(type='dict'), data=dict(type='jsonarg'), timeout=dict(type='int', default=60)) argument_specs.update(avi_common_argument_spec()) module = AnsibleModule(argument_spec=argument_specs) if not HAS_AVI: return module.fail_json( msg=('Avi python API SDK (avisdk) is not installed. ' 'For more details visit https://github.com/avinetworks/sdk.')) tenant_uuid = module.params.get('tenant_uuid', None) api = ApiSession.get_session(module.params['controller'], module.params['username'], module.params['password'], tenant=module.params['tenant'], tenant_uuid=tenant_uuid) tenant = module.params.get('tenant', '') timeout = int(module.params.get('timeout')) # path is a required argument path = module.params.get('path', '') params = module.params.get('params', None) data = module.params.get('data', None) # Get the api_version from module. api_version = module.params.get('api_version', '16.4') if data is not None: data = json.loads(data) method = module.params['http_method'] existing_obj = None changed = method != 'get' gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) if method == 'post': # need to check if object already exists. In that case # change the method to be put gparams['name'] = data['name'] rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) try: existing_obj = rsp.json()['results'][0] except IndexError: # object is not found pass else: # object is present method = 'put' path += '/' + existing_obj['uuid'] if method == 'put': # put can happen with when full path is specified or it is put + post if existing_obj is None: using_collection = False if (len(path.split('/')) == 1) and ('name' in data): gparams['name'] = data['name'] using_collection = True rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) rsp_data = rsp.json() if using_collection: if rsp_data['results']: existing_obj = rsp_data['results'][0] path += '/' + existing_obj['uuid'] else: method = 'post' else: if rsp.status_code == 404: method = 'post' else: existing_obj = rsp_data if existing_obj: changed = not avi_obj_cmp(data, existing_obj) cleanup_absent_fields(data) if method == 'patch': rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) existing_obj = rsp.json() if (method == 'put' and changed) or (method != 'put'): fn = getattr(api, method) rsp = fn(path, tenant=tenant, tenant_uuid=tenant, timeout=timeout, params=params, data=data, api_version=api_version) else: rsp = None if method == 'delete' and rsp.status_code == 404: changed = False rsp.status_code = 200 if method == 'patch' and existing_obj and rsp.status_code < 299: # Ideally the comparison should happen with the return values # from the patch API call. However, currently Avi API are # returning different hostname when GET is used vs Patch. # tracked as AV-12561 if path.startswith('pool'): time.sleep(1) gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) new_obj = rsp.json() changed = not avi_obj_cmp(new_obj, existing_obj) if rsp is None: return module.exit_json(changed=changed, obj=existing_obj) return ansible_return(module, rsp, changed, req=data)
def main(): try: module = AnsibleModule(argument_spec=dict( controller=dict(required=True), username=dict(required=True), password=dict(required=True), tenant=dict(default='admin'), tenant_uuid=dict(default=''), state=dict(default='present', choices=['absent', 'present']), clear_on_max_retries=dict(type='int', ), dns_configs=dict(type='list', ), name=dict(type='str', ), owner_controller_cluster_uuid=dict(type='str', ), send_interval=dict(type='int', ), site_controller_clusters=dict(type='list', ), tenant_ref=dict(type='str', ), url=dict(type='str', ), uuid=dict(type='str', ), view_id=dict(type='int', ), ), ) api = ApiSession.get_session(module.params['controller'], module.params['username'], module.params['password'], tenant=module.params['tenant']) state = module.params['state'] name = module.params['name'] obj = deepcopy(module.params) obj.pop('state', None) obj.pop('controller', None) obj.pop('username', None) obj.pop('password', None) tenant = obj.pop('tenant', '') tenant_uuid = obj.pop('tenant_uuid', '') obj.pop('cloud_ref', None) purge_optional_fields(obj, module) if state == 'absent': try: rsp = api.delete_by_name('globallb', name, tenant=tenant, tenant_uuid=tenant_uuid) except ObjectNotFound: return module.exit_json(changed=False) if rsp.status_code == 204: return module.exit_json(changed=True) return module.fail_json(msg=rsp.text) existing_obj = api.get_object_by_name('globallb', name, tenant=tenant, tenant_uuid=tenant_uuid, params={ 'include_refs': '', 'include_name': '' }) changed = False rsp = None if existing_obj: # this is case of modify as object exists. should find out # if changed is true or not changed = not avi_obj_cmp(obj, existing_obj) cleanup_absent_fields(obj) if changed: obj_uuid = existing_obj['uuid'] rsp = api.put('globallb/%s' % obj_uuid, data=obj, tenant=tenant, tenant_uuid=tenant_uuid) else: changed = True rsp = api.post('globallb', data=obj, tenant=tenant, tenant_uuid=tenant_uuid) if rsp is None: return module.exit_json(changed=changed, obj=existing_obj) else: return ansible_return(module, rsp, changed) except: raise