summaryrefslogtreecommitdiffstats
path: root/lcm/lcm/pub/msapi/gvnfmdriver.py
blob: 91b4a363ef595c2a6670a85cfcce0d971253e16b (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# Copyright 2017 ZTE Corporation.
#
# 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.

import json
import logging
import uuid

from lcm.pub.exceptions import NFLCMException
from lcm.pub.utils.restcall import req_by_msb
from lcm.pub.utils.timeutil import now_time
from lcm.pub.database.models import (
    NfInstModel, VmInstModel, NetworkInstModel,
    PortInstModel, StorageInstModel, VNFCInstModel
)

logger = logging.getLogger(__name__)


def get_packageinfo_by_vnfdid(vnfdid):
    ret = req_by_msb('api/gvnfmdriver/v1/vnfpackages', 'GET')
    if ret[0] != 0:
        logger.error('Status code is %s, detail is %s.', ret[2], ret[1])
        raise NFLCMException('Failed to query package_info of vnfdid(%s) from nslcm.' % vnfdid)
    return json.JSONDecoder().decode(ret[1])


def apply_grant_to_nfvo(data):
    ret = req_by_msb('api/gvnfmdriver/v1/resource/grant', 'PUT', data)
    if ret[0] != 0:
        logger.error('Status code is %s, detail is %s.', ret[2], ret[1])
        raise NFLCMException('Nf instancing apply grant exception')
    return json.JSONDecoder().decode(ret[1])


def notify_lcm_to_nfvo(data):
    ret = req_by_msb('api/gvnfmdriver/v1/vnfs/lifecyclechangesnotification', 'POST', data)
    if ret[0] != 0:
        logger.error('Status code is %s, detail is %s.', ret[2], ret[1])
        raise NFLCMException('Nf lcm notify exception')
    return ret[1]


def prepare_notification_data(nfinstid, jobid, changetype, operation):
    logger.info('Send notify request to nfvo')
    affected_vnfcs = []
    vnfcs = VNFCInstModel.objects.filter(instid=nfinstid)
    for vnfc in vnfcs:
        vm_resource = {}
        if vnfc.vmid:
            vm = VmInstModel.objects.filter(vmid=vnfc.vmid)
            if vm:
                vm_resource = {
                    'vimConnectionId': vm[0].vimid,
                    'resourceId': vm[0].resourceid,
                    'resourceProviderId': vm[0].vmname,  # TODO: is resourceName mapped to resourceProviderId?
                    'vimLevelResourceType': 'vm'
                }
        affected_vnfcs.append({
            'id': vnfc.vnfcinstanceid,
            'vduId': vnfc.vduid,
            'changeType': changetype,
            'computeResource': vm_resource
        })
    affected_vls = []
    networks = NetworkInstModel.objects.filter(instid=nfinstid)
    for network in networks:
        network_resource = {
            'vimConnectionId': network.vimid,
            'resourceId': network.resourceid,
            'resourceProviderId': network.name,  # TODO: is resourceName mapped to resourceProviderId?
            'vimLevelResourceType': 'network'
        }
        affected_vls.append({
            'id': network.networkid,
            'virtualLinkDescId': network.nodeId,
            'changeType': changetype,
            'networkResource': network_resource
        })
    ext_connectivity = []
    ext_connectivity_map = {}
    ports = PortInstModel.objects.filter(instid=nfinstid)
    for port in ports:
        if port.networkid not in ext_connectivity_map:
            ext_connectivity_map[port.networkid] = []
        ext_connectivity_map[port.networkid].append({
            'id': port.portid,  # TODO: port.portid or port.nodeid?
            'resourceHandle': {
                'vimConnectionId': port.vimid,
                'resourceId': port.resourceid,
                'resourceProviderId': port.name,  # TODO: is resourceName mapped to resourceProviderId?
                'vimLevelResourceType': 'port'
            },
            'cpInstanceId': port.portid  # TODO: port.cpinstanceid is not initiated when create port resource.
        })
    for network_id, ext_link_ports in ext_connectivity_map.items():
        networks = NetworkInstModel.objects.filter(networkid=network_id)
        net_name = networks[0].name if networks else network_id
        network_resource = {
            'vimConnectionId': ext_link_ports[0]['resourceHandle']['vimConnectionId'],
            'resourceId': network_id,
            'resourceProviderId': net_name,  # TODO: is resourceName mapped to resourceProviderId?
            'vimLevelResourceType': 'network'
        }
        ext_connectivity.append({
            'id': network_id,
            'resourceHandle': network_resource,
            'extLinkPorts': ext_link_ports
        })
    logger.debug("ext_connectivity=%s", ext_connectivity)
    affected_vss = []
    vss = StorageInstModel.objects.filter(instid=nfinstid)
    for vs in vss:
        affected_vss.append({
            'id': vs.storageid,
            'virtualStorageDescId': vs.nodeId,
            'changeType': changetype,
            'storageResource': {
                'vimConnectionId': vs.vimid,
                'resourceId': vs.resourceid,
                'resourceProviderId': vs.name,  # TODO: is resourceName mapped to resourceProviderId?
                'vimLevelResourceType': 'volume'
            }
        })
    notification_content = {
        'id': str(uuid.uuid4()),  # shall be the same if sent multiple times due to multiple subscriptions.
        'notificationType': 'VnfLcmOperationOccurrenceNotification',
        # set 'subscriptionId' after filtering for subscribers
        'timeStamp': now_time(),
        'notificationStatus': 'RESULT',
        'operationState': 'COMPLETED',
        'vnfInstanceId': nfinstid,
        'operation': operation,
        'isAutomaticInvocation': False,
        'vnfLcmOpOccId': jobid,
        'affectedVnfcs': affected_vnfcs,
        'affectedVirtualLinks': affected_vls,
        'affectedVirtualStorages': affected_vss,
        'changedExtConnectivity': [],  # TODO: will add in R4
        '_links': {
            'vnfInstance': {'href': '/api/vnflcm/v1/vnf_instances/%s' % nfinstid},
            # set 'subscription' link after filtering for subscribers
            'vnfLcmOpOcc': {'href': '/api/vnflcm/v1/vnf_lcm_op_occs/%s' % jobid}
        }
    }
    nfInsts = NfInstModel.objects.filter(nfinstid=nfinstid)
    notification_content['vnfmInstId'] = nfInsts[0].vnfminstid if nfInsts[0].vnfminstid else '1'
    logger.info('Notify request data = %s' % notification_content)
    return notification_content