summaryrefslogtreecommitdiffstats
path: root/conductor/conductor/solver/utils/constraint_engine_interface.py
blob: bbb782d22d0e3162a60bdaae97fbf73a9f018fce (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
#!/usr/bin/env python
#
# -------------------------------------------------------------------------
#   Copyright (c) 2015-2017 AT&T Intellectual Property
#
#   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.
#
# -------------------------------------------------------------------------
#


"""Constraint/Engine Interface

Utility library that defines the interface between
the constraints and the conductor data engine.

"""

from oslo_log import log

LOG = log.getLogger(__name__)


class ConstraintEngineInterface(object):
    def __init__(self, client):
        self.client = client

    def get_candidate_location(self, candidate):
        # Try calling a method (remember, "calls" are synchronous)
        # FIXME(jdandrea): Doing this because Music calls are expensive.
        lat = candidate.get('latitude')
        lon = candidate.get('longitude')
        if lat and lon:
            response = (float(lat), float(lon))
        else:
            ctxt = {}
            args = {"candidate": candidate}
            response = self.client.call(ctxt=ctxt,
                                        method="get_candidate_location",
                                        args=args)
            LOG.debug("get_candidate_location response: {}".format(response))
        return response

    def get_candidate_zone(self, candidate, _category=None):
        # FIXME(jdandrea): Doing this because Music calls are expensive.
        if _category == 'region':
            response = candidate['location_id']
        elif _category == 'complex':
            response = candidate['complex_name']
        elif _category == 'country':
            response = candidate['country']
        else:
            ctxt = {}
            args = {"candidate": candidate, "category": _category}
            response = self.client.call(ctxt=ctxt,
                                        method="get_candidate_zone",
                                        args=args)
            LOG.debug("get_candidate_zone response: {}".format(response))
        return response

    def get_candidates_from_service(self, constraint_name,
                                    constraint_type, candidate_list,
                                    controller, inventory_type,
                                    request, cost, demand_name,
                                    request_type):
        ctxt = {}
        args = {"constraint_name": constraint_name,
                "constraint_type": constraint_type,
                "candidate_list": candidate_list,
                "controller": controller,
                "inventory_type": inventory_type,
                "request": request,
                "cost": cost,
                "demand_name": demand_name,
                "request_type": request_type}
        response = self.client.call(ctxt=ctxt,
                                    method="get_candidates_from_service",
                                    args=args)
        LOG.debug("get_candidates_from_service response: {}".format(response))
        # response is a list of (candidate, cost) tuples
        return response

    def get_inventory_group_candidates(self, candidate_list,
                                       demand_name, resolved_candidate):
        # return a list of the "pair" candidates for the given candidate
        ctxt = {}
        args = {"candidate_list": candidate_list,
                "demand_name": demand_name,
                "resolved_candidate": resolved_candidate}
        response = self.client.call(ctxt=ctxt,
                                    method="get_inventory_group_candidates",
                                    args=args)
        LOG.debug("get_inventory_group_candidates \
                   response: {}".format(response))
        return response

    def get_candidates_by_attributes(self, demand_name,
                                     candidate_list, properties):
        ctxt = {}
        args = {"candidate_list": candidate_list,
                "properties": properties,
                "demand_name": demand_name}
        response = self.client.call(ctxt=ctxt,
                                    method="get_candidates_by_attributes",
                                    args=args)
        LOG.debug("get_candidates_by_attribute response: {}".format(response))
        # response is a list of (candidate, cost) tuples
        return response

    def get_candidates_with_hpa(self, id, type, directives, candidate_list,
                                flavorProperties):
        '''
        Returns the candidate_list with an addition of flavor_mapping for
        matching cloud candidates with hpa constraints.
        :param label_name: vm_label_name passed from the SO/Policy
        :param candidate_list: list of candidates to process
        :param flavorProperties: hpa features for this vm_label_name
        :return: candidate_list with hpa features and flavor mapping
        '''
        ctxt = {}
        args = {"candidate_list": candidate_list,
                "flavorProperties": flavorProperties,
                "id": id,
                "type": type,
                "directives": directives}
        response = self.client.call(ctxt=ctxt,
                                    method="get_candidates_with_hpa",
                                    args=args)
        LOG.debug("get_candidates_with_hpa response: {}".format(response))
        return response

    def get_candidates_with_vim_capacity(self, candidate_list, vim_request):
        '''
        Returns the candidate_list with required vim capacity.
        :param candidate_list: list of candidates to process
        :param requests: vim requests with required cpu, memory and disk
        :return: candidate_list with required vim capacity.
        '''
        ctxt = {}
        args = {"candidate_list": candidate_list,
                "request": vim_request}
        response = self.client.call(ctxt=ctxt,
                                    method="get_candidates_with_vim_capacity",
                                    args=args)
        LOG.debug(
            "get_candidates_with_vim_capacity response: {}".format(response))
        return response