summaryrefslogtreecommitdiffstats
path: root/components/pm-subscription-handler/pmsh_service/mod/aai_client.py
blob: 747846f126eefe781861d8d3fa0ded9d7b02f29c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# ============LICENSE_START===================================================
#  Copyright (C) 2019-2020 Nordix Foundation.
# ============================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=====================================================
import json
import uuid
from os import environ

import requests
from requests.auth import HTTPBasicAuth

import mod.pmsh_logging as logger
from mod.network_function import NetworkFunction
from mod.subscription import Subscription, NetworkFunctionFilter


def get_pmsh_subscription_data(cbs_data):
    """
    Returns the PMSH subscription data

    Args:
        cbs_data: json app config from the Config Binding Service.

    Returns:
        Subscription, set(NetworkFunctions): `Subscription` <Subscription> object,
        set of NetworkFunctions to be added.

    Raises:
        RuntimeError: if AAI data cannot be retrieved.
    """
    aai_nf_data = _get_all_aai_nf_data()
    if aai_nf_data:
        sub = Subscription(**cbs_data['policy']['subscription'])
        nfs = _filter_nf_data(aai_nf_data, NetworkFunctionFilter(**sub.nfFilter))
    else:
        raise RuntimeError('Failed to get data from AAI')
    return sub, nfs


def _get_all_aai_nf_data():
    """
    Return queried nf data from the AAI service.

    Returns:
        json: the json response from AAI query, else None.
    """
    nf_data = None
    try:
        session = requests.Session()
        aai_endpoint = f'{_get_aai_service_url()}{"/aai/v16/query"}'
        headers = {'accept': 'application/json',
                   'content-type': 'application/json',
                   'x-fromappid': 'dcae-pmsh',
                   'x-transactionid': str(uuid.uuid1())}
        json_data = """
                    {'start':
                        ['network/pnfs',
                        'network/generic-vnfs']
                    }"""
        params = {'format': 'simple', 'nodesOnly': 'true'}
        response = session.put(aai_endpoint, headers=headers,
                               auth=HTTPBasicAuth('AAI', 'AAI'),
                               data=json_data, params=params, verify=False)
        response.raise_for_status()
        if response.ok:
            nf_data = json.loads(response.text)
    except Exception as e:
        logger.debug(e)
    return nf_data


def _get_aai_service_url():
    """
    Returns the URL of the AAI kubernetes service.

    Returns:
        str: the AAI k8s service URL.

    Raises:
        KeyError: if AAI env vars not found.
    """
    try:
        aai_service = environ['AAI_SERVICE_HOST']
        aai_ssl_port = environ['AAI_SERVICE_PORT_AAI_SSL']
        return f'https://{aai_service}:{aai_ssl_port}'
    except KeyError as e:
        logger.debug(f'Failed to get AAI env vars: {e}')
        raise


def _filter_nf_data(nf_data, nf_filter):
    """
    Returns a list of filtered NetworkFunctions using the nf_filter.

    Args:
        nf_data : the nf json data from AAI.
        nf_filter: the `NetworkFunctionFilter <NetworkFunctionFilter>` to be applied.

    Returns:
        set: a set of filtered NetworkFunctions.

    Raises:
        KeyError: if AAI data cannot be parsed.
    """
    nf_set = set()
    try:
        for nf in nf_data['results']:
            name_identifier = 'pnf-name' if nf['node-type'] == 'pnf' else 'vnf-name'
            if nf_filter.is_nf_in_filter(nf['properties'].get(name_identifier)):
                nf_set.add(NetworkFunction(
                    nf_name=nf['properties'].get(name_identifier),
                    orchestration_status=nf['properties'].get('orchestration-status')))
    except KeyError as e:
        logger.debug(f'Failed to parse AAI data: {e}')
        raise
    return nf_set