예제 #1
0
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 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
예제 #3
0
    def testCleanupFields(self):
        obj = {'name': 'testpool',
               'scalar_field': {'state': 'absent'},
               'list_fields': [{'x': '1'}, {'y': {'state': 'absent'}}]}

        cleanup_absent_fields(obj)
        assert 'scalar_field' not in obj
        for elem in obj['list_fields']:
            print elem
            assert 'y' not in elem
예제 #4
0
    def testCleanupFields(self):
        obj = {'name': 'testpool',
               'scalar_field': {'state': 'absent'},
               'list_fields': [{'x': '1'}, {'y': {'state': 'absent'}}]}

        cleanup_absent_fields(obj)
        assert 'scalar_field' not in obj
        for elem in obj['list_fields']:
            print elem
            assert 'y' not in elem
예제 #5
0
    def test_cleanup_abset(self):
        obj = {
            'x': 10,
            'y': {
                'state': 'absent'
            },
            'z': {
                'a': {
                    'state': 'absent'
                }
            }
        }
        cleanup_absent_fields(obj)

        assert 'y' not in obj
        assert 'a' not in obj['z']
예제 #6
0
    def test_cleanup_abset(self):
        obj = {
            'x': 10,
            'y': {
                'state': 'absent'
            },
            'z': {
                'a': {
                    'state': 'absent'
                }
            },
            'l': [{
                'y1': {
                    'state': 'absent'
                }
            }],
            'z1': {
                'a': {
                    'state': 'absent'
                },
                'b': {},
                'c': 42
            },
            'empty': []
        }

        obj = cleanup_absent_fields(obj)

        assert 'y' not in obj
        assert 'z' not in obj
        assert 'l' not in obj
        assert 'z1' in obj
        assert 'b' not in obj['z1']
        assert 'a' not in obj['z1']
        assert 'empty' not in obj
예제 #7
0
    def test_cleanup_abset(self):
        obj = {'x': 10,
               'y': {'state': 'absent'},
               'z': {'a': {'state': 'absent'}},
               'l': [{'y1': {'state': 'absent'}}],
               'z1': {'a': {'state': 'absent'}, 'b': {}, 'c': 42},
               'empty': []}

        obj = cleanup_absent_fields(obj)

        assert 'y' not in obj
        assert 'z' not in obj
        assert 'l' not in obj
        assert 'z1' in obj
        assert 'b' not in obj['z1']
        assert 'a' not in obj['z1']
        assert 'empty' not in obj
예제 #8
0
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)
예제 #9
0
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)
예제 #10
0
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)
예제 #11
0
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