summaryrefslogtreecommitdiffstats
path: root/controlloop/common/controller-usecases/pom.xml
blob: 1509f0c3f1485d3b2886d92d20b29183738b9042 (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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ============LICENSE_START=======================================================
  ONAP
  ================================================================================
  Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  ================================================================================
  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.
  ============LICENSE_END=========================================================
  -->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.onap.policy.drools-applications.controlloop.common</groupId>
        <artifactId>drools-applications-common</artifactId>
        <version>1.10.0</version>
    </parent>

    <artifactId>controller-usecases</artifactId>
    <packaging>kjar</packaging>

    <name>${project.artifactId}</name>
    <description>Usecases Experimental Controller</description>

    <build>
        <plugins>
            <plugin>
                <groupId>org.kie</groupId>
                <artifactId>kie-maven-plugin</artifactId>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>events</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>aai</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>appc</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>appclcm</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>cds</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>sdnc</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>sdnr</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>so</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
            <artifactId>vfc</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.drools-applications.controlloop.common</groupId>
            <artifactId>eventmanager</artifactId>
            <version>${project.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actorServiceProvider</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.aai</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.appc</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.appclcm</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.cds</artifactId>
            <version>${policy.models.version}</version>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.xacml</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.sdnc</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.sdnr</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.so</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
            <artifactId>actor.vfc</artifactId>
            <version>${policy.models.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.drools-pdp</groupId>
            <artifactId>policy-management</artifactId>
            <version>${version.policy.drools-pdp}</version>
            <scope>provided</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.drools-applications.controlloop.common</groupId>
            <artifactId>rules-test</artifactId>
            <version>${project.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.onap.policy.common</groupId>
            <artifactId>utils-test</artifactId>
            <version>${version.policy.common}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <!--This profile is used to store Eclipse m2e settings only. It has no
                influence on the Maven build itself. -->
            <id>only-eclipse</id>
            <activation>
                <property>
                    <name>m2e.version</name>
                </property>
            </activation>
            <build>
                <pluginManagement>
                    <plugins>
                        <plugin>
                            <groupId>org.eclipse.m2e</groupId>
                            <artifactId>lifecycle-mapping</artifactId>
                            <version>1.0.0</version>
                            <configuration>
                                <lifecycleMappingMetadata>
                                    <pluginExecutions>
                                        <pluginExecution>
                                            <pluginExecutionFilter>
                                                <groupId>org.kie</groupId>
                                                <artifactId>kie-maven-plugin</artifactId>
                                                <goals>
                                                    <goal>build</goal>
                                                </goals>
                                            </pluginExecutionFilter>
                                            <action>
                                                <ignore />
                                            </action>
                                        </pluginExecution>
                                    </pluginExecutions>
                                </lifecycleMappingMetadata>
                            </configuration>
                        </plugin>
                    </plugins>
                </pluginManagement>
            </build>
        </profile>
    </profiles>
</project>
span>]) total = obj["metadata"]["pagination"]["total"] for item in obj["items"]: yield NodeInstance(item) def update_node_instance(self, node_instance_id, body, **kwargs): headers = copy.deepcopy(self._headers_with_tenant) headers['Content-Type'] = "application/json" url_mask = "{}://{}:{}/api/v3.1/node-instances/{}".format( self._protocol, self._host, self._port, node_instance_id) response = requests.patch(url_mask, json=body, headers=headers, timeout=30) obj = response.json() return obj class NodeInstance(object): """quick replacement for cloudify_rest_client""" def __init__(self, instance): self.id = instance.get("id") self.deployment_id = instance.get("deployment_id") self.host_id = instance.get("host_id") self.runtime_properties = instance.get("runtime_properties") self.relationships = instance.get("relationships") self.state = instance.get("state") self.version = instance.get("version") self.node_id = instance.get("node_id") self.scaling_groups = instance.get("scaling_groups") class CfyClient(object): _logger = logging.getLogger("oti_handler.cfy_client") _client = None @staticmethod def __set_cloudify_manager_client(): """Create connection to Cloudify_Manager.""" if CfyClient._client: return host = None port = None obj = json.loads(os.environ.get("CLOUDIFY", "{}")).get("cloudify") source = "CLOUDIFY environment variable" if not obj: CM_KEY = 'cloudify_manager' source = "Consul key '{}'".format(CM_KEY) try: results = ConsulClient.lookup_service(CM_KEY) except Exception as e: msg = "Unexpected exception {}: {!s} from ConsulClient.lookup_service({})".format(type(e).__name__, e, CM_KEY) CfyClient._logger.error(msg) raise CfyClientConsulError(msg) result = results[0] host = result['ServiceAddress'] port = result['ServicePort'] try: obj = ConsulClient.get_value(CM_KEY) except Exception as e: msg = "Unexpected exception {}: {!s} from ConsulClient.get_value({})".format(type(e).__name__, e, CM_KEY) CfyClient._logger.error(msg) raise CfyClientConsulError(msg) if not obj: raise CfyClientConsulError("{} value is empty or invalid".format(source)) obj = obj.get('cloudify') if not obj: raise CfyClientConsulError("{} value is missing 'cloudify' key or value".format(source)) host = obj.get('address', host) if not host: raise CfyClientConsulError("{} value is missing 'cloudify.address'".format(source)) port = obj.get('port', port) if not port: raise CfyClientConsulError("{} value is missing 'cloudify.port'".format(source)) protocol = obj.get('protocol') if not protocol: raise CfyClientConsulError("{} value is missing 'cloudify.protocol'".format(source)) username = obj.get('user') if not username: raise CfyClientConsulError("{} value is missing 'cloudify.user'".format(source)) password = obj.get('password') if not password: raise CfyClientConsulError("{} value is missing 'cloudify.password'".format(source)) b64_encoded_str = base64.b64encode(bytes("{}:{}".format(username, password), "utf-8")).decode("utf-8") headers = {'Authorization': 'Basic ' + b64_encoded_str.rstrip('\n')} #headers = {'Authorization': 'Basic ' + '{}:{}'.format(username, password).encode("base64").rstrip('\n')} CfyClient._client = CloudifyClient(host=host, port=port, protocol=protocol, headers=headers) @staticmethod def query_k8_components(in_cluster_fqdn): """ Iterate components that belong to a cluster fqdn. Parameters ---------- in_cluster_fqdn : string k8s cluster FQDN Returns ------- A generator of tuples of component information [ (proxy_fqdn, namespace, scn, replicas, scn_port), ... ] """ cnt_found = 0 CfyClient.__set_cloudify_manager_client() for node_instance in CfyClient._client.node_instances.list(_sort="deployment_id"): rtp = node_instance.runtime_properties scn_port = None cluster_fqdn = None proxy_fqdn = None dti_info = rtp.get('dti_info') if dti_info: env_items = dti_info.get('env') for env in env_items: if env.get("name") == 'KUBE_CLUSTER_FQDN': cluster_fqdn = env.get("value") if env.get("name") == 'KUBE_PROXY_FQDN': proxy_fqdn = env.get("value") ports = dti_info.get('ports') if ports: scn_port = ports[0].split(':')[0] else: continue if in_cluster_fqdn != cluster_fqdn: continue controller_type = rtp.get('k8s_controller_type') if not controller_type: CfyClient._logger.debug("controller type is missing") continue elif controller_type != "statefulset": CfyClient._logger.debug("not a stateful set") continue container_id = rtp.get('k8s_deployment') if not container_id: CfyClient._logger.debug("{} {} runtime_properties has no container_id or k8s_deployment".format( node_instance.deployment_id, node_instance.id)) continue try: namespace = container_id.get('namespace') except: namespace = '' pass replicas = 1 try: replicas = rtp.get('replicas') except: pass scn = rtp.get('service_component_name') if not scn: CfyClient._logger.debug( "{} {} runtime_properties has no service_component_name".format(node_instance.deployment_id, node_instance.id)) continue cnt_found += 1 yield (proxy_fqdn, namespace, scn, replicas, scn_port) continue msg = "Found {} components (collectors) for cluster={}" \ .format(cnt_found, in_cluster_fqdn) CfyClient._logger.debug(msg) @staticmethod def iter_components(dcae_target_type, dcae_service_location='', component_type=''): """ Iterate components that handle a given dcae_target_type. Parameters ---------- dcae_target_type : string VNF Type dcae_service_location : string Location of the component (optional) component_type : string Type of the component (optional) Returns ------- A generator of tuples of component information [ (scn, deployment_id, container_id, node_id, node_instance_id, node_instance_state, docker_host, reconfig_script, "docker"), ... ] or [ (scn, deployment_id, k8s_deployment, node_id, node_instance_id, node_instance_state, config_content, reconfig_script, "k8s"), ... ] """ cnt_found = 0 # get dockerhost and kubernetes_master services that are TAGged for the dcae_service_location (CLLI) dockerhosts = [] k8s_svcs_tagged_with_clli = [] if dcae_service_location: try: dockerhosts = ConsulClient.search_services("-component-dockerhost-", [dcae_service_location]) except Exception as e: msg = "Unexpected exception {}: {!s} from ConsulClient.search_services({}, {!s})".format(type(e).__name__, e, "-component-dockerhost-", [dcae_service_location]) CfyClient._logger.error(msg) raise CfyClientConsulError(msg) try: k8s_svcs_tagged_with_clli = ConsulClient.search_services("_component_kubernetes_master", [dcae_service_location]) except Exception as e: msg = "Unexpected exception {}: {!s} from ConsulClient.search_services({}, {!s})".format(type(e).__name__, e, "_component_kubernetes_master", [dcae_service_location]) CfyClient._logger.error(msg) raise CfyClientConsulError(msg) CfyClient.__set_cloudify_manager_client() for node_instance in CfyClient._client.node_instances.list(_sort="deployment_id"): rtp = node_instance.runtime_properties # Skip this node_instance if it is not a collector container_type = "docker" container_id = rtp.get('container_id') docker_host = '' svc_with_my_clli_tags = '' if not container_id: container_type = "k8s" container_id = rtp.get('k8s_deployment') if not container_id: CfyClient._logger.debug("{} {} runtime_properties has no container_id or k8s_deployment".format(node_instance.deployment_id, node_instance.id)) continue docker_config = rtp.get('docker_config') if not docker_config: CfyClient._logger.debug("{} {} runtime_properties has no docker_config".format(node_instance.deployment_id, node_instance.id)) continue dti_reconfig_script = "" if container_type == "docker": dti_reconfig_script = rtp.get('dti_reconfig_script') if not dti_reconfig_script: CfyClient._logger.debug("{} {} runtime_properties has no dti_reconfig_script".format(node_instance.deployment_id, node_instance.id)) continue elif container_type == "k8s": dti_reconfig_script = docker_config.get('reconfigs',{}).get('dti') if not dti_reconfig_script: CfyClient._logger.debug("{} {} runtime_properties docker_config has no reconfigs.dti".format(node_instance.deployment_id, node_instance.id)) continue scn = rtp.get('service_component_name') scn_address = None scn_port = None if not scn: CfyClient._logger.debug("{} {} runtime_properties has no service_component_name".format(node_instance.deployment_id, node_instance.id)) continue if container_type == "docker": docker_host = rtp.get('selected_container_destination') if not docker_host: CfyClient._logger.debug("{} {} runtime_properties has no selected_container_destination".format(node_instance.deployment_id, node_instance.id)) continue elif container_type == "k8s": try: srvcCatalogItem = ConsulClient.lookup_service(scn)[0] scn_address = srvcCatalogItem.get("ServiceAddress") except: CfyClient._logger.debug( "{} {} runtime_properties has no consul svc catalog registry".format(node_instance.deployment_id, node_instance.id)) continue svc_with_my_clli_tags = rtp.get('svc_with_my_clli_tags') # e.g., scn="s908d92e232ed43..." if not svc_with_my_clli_tags: # We should not incur this burden. k8splugin should store this into runtime properties. try: node_name = srvcCatalogItem.get("Node") if node_name: # e.g., node_name="zldcdyh1adce3kpma00" services = ConsulClient.lookup_node(node_name).get("Services") if services: for node_svc in list(services.keys()): if "_component_kubernetes_master" in node_svc: # e.g., node_svc="zldcdyh1adce3_kp_component_kubernetes_master" svc_with_my_clli_tags = node_svc break except: pass # ... cache results we find into runtime properties to avoid searching again if svc_with_my_clli_tags: CfyClient._logger.debug("{} {} storing runtime property svc_with_my_clli_tags={}".format( node_instance.deployment_id, node_instance.id, svc_with_my_clli_tags)) rtp['svc_with_my_clli_tags'] = svc_with_my_clli_tags body = { "runtime_properties": rtp, "state": node_instance.state, "version": 1 + int(node_instance.version) } try: CfyClient._client.update_node_instance(node_instance.id, body) except: pass if not svc_with_my_clli_tags: CfyClient._logger.debug("{} {} runtime_properties has no svc_with_my_clli_tags".format(node_instance.deployment_id, node_instance.id)) continue # get the nodeport for statefulset sidecar service dti_info = rtp.get('dti_info') if dti_info: ports = dti_info.get('ports') if ports: scn_port = ports[0].split(':')[1] docker_host = rtp.get('configuration',{}).get('file_content') if not docker_host: CfyClient._logger.debug("{} {} runtime_properties has no configuration.file_content".format(node_instance.deployment_id, node_instance.id)) continue # If DTI Event specifies dcae_service_location, then collector's dockerhost service in Consul must have that TAG if dcae_service_location: if container_type == "docker" and docker_host not in dockerhosts: CfyClient._logger.debug("{} {} dockerhost {} is not TAGged with DTI Event dcae_service_location {}" .format(node_instance.deployment_id, node_instance.id, docker_host, dcae_service_location)) continue elif container_type == "k8s" and svc_with_my_clli_tags not in k8s_svcs_tagged_with_clli: CfyClient._logger.debug("{} {} svc_with_my_clli_tags {} is not TAGged with DTI Event dcae_service_location {}" .format(node_instance.deployment_id, node_instance.id, svc_with_my_clli_tags, dcae_service_location)) continue # If DTI Event specifies component_type, then collector's service_component_type must match if component_type: c_component_type = rtp.get('service_component_type') if component_type != c_component_type: CfyClient._logger.debug("{} {} component_types don't match".format(node_instance.deployment_id, node_instance.id)) continue # Check if the collector supports this VNF Type # scn:oti Consul key is authoritative for vnfTypes that a collector supports (not docker_config) dti_key = scn + ':oti' try: obj = ConsulClient.get_value(dti_key) except Exception as e: CfyClient._logger.error( "Unexpected exception {}: {!s} from ConsulClient.get_value({}) for {} {}" .format(type(e).__name__, e, dti_key, node_instance.deployment_id, node_instance.id) ) continue if not obj: CfyClient._logger.debug("{} {} Consul key '{}' is empty or invalid".format(node_instance.deployment_id, node_instance.id, dti_key)) continue obj_types = set(k.lower() for k in obj) if dcae_target_type.lower() in obj_types: CfyClient._logger.debug("{} {} is a valid collector for VNF Type {}".format(node_instance.deployment_id, node_instance.id, dcae_target_type)) cnt_found += 1 yield (scn, node_instance.deployment_id, container_id, node_instance.node_id, node_instance.id, node_instance.state, docker_host, dti_reconfig_script, container_type, scn_address, scn_port ) continue else: CfyClient._logger.debug("{} {} VNF Type {} is not in Consul key '{}'".format(node_instance.deployment_id, node_instance.id, dcae_target_type, dti_key)) continue msg = "Found {} components (collectors) for dcae_target_type={}, dcae_service_location={}, component_type={}"\ .format(cnt_found, dcae_target_type, dcae_service_location, component_type) CfyClient._logger.debug(msg) @staticmethod def iter_components_for_docker(dcae_target_type, dcae_service_location='', component_type=''): """ Iterate components that handle a given dcae_target_type to find the components of docker type Parameters ---------- dcae_target_type : string VNF Type dcae_service_location : string Location of the component (optional) component_type : string Type of the component (optional) Returns ------- A generator of tuples of component information [ (scn, deployment_id, container_id, node_id, node_instance_id, node_instance_state, docker_host, reconfig_script, "docker"), ... ] """ cnt_found = 0 # get dockerhost and kubernetes_master services that are TAGged for the dcae_service_location (CLLI) dockerhosts = [] if dcae_service_location: try: dockerhosts = ConsulClient.search_services("-component-dockerhost-", [dcae_service_location]) except Exception as e: msg = "Unexpected exception {}: {!s} from ConsulClient.search_services({}, {!s})".format( type(e).__name__, e, "-component-dockerhost-", [dcae_service_location]) CfyClient._logger.error(msg) raise CfyClientConsulError(msg) CfyClient.__set_cloudify_manager_client() for node_instance in CfyClient._client.node_instances.list(_sort="deployment_id"): rtp = node_instance.runtime_properties # Skip this node_instance if it is not a collector container_type = "docker" container_id = rtp.get('container_id') if not container_id: if not container_id: CfyClient._logger.debug("{} {} runtime_properties has no container_id".format( node_instance.deployment_id, node_instance.id)) continue docker_config = rtp.get('docker_config') if not docker_config: CfyClient._logger.debug( "{} {} runtime_properties has no docker_config".format(node_instance.deployment_id, node_instance.id)) continue dti_reconfig_script = "" dti_reconfig_script = rtp.get('dti_reconfig_script') if not dti_reconfig_script: CfyClient._logger.debug( "{} {} runtime_properties has no dti_reconfig_script".format(node_instance.deployment_id, node_instance.id)) continue scn = rtp.get('service_component_name') if not scn: CfyClient._logger.debug( "{} {} runtime_properties has no service_component_name".format(node_instance.deployment_id, node_instance.id)) continue docker_host = rtp.get('selected_container_destination') if not docker_host: CfyClient._logger.debug("{} {} runtime_properties has no selected_container_destination".format( node_instance.deployment_id, node_instance.id)) continue # If DTI Event specifies dcae_service_location, then collector's dockerhost service in Consul must have that TAG if dcae_service_location: if docker_host not in dockerhosts: CfyClient._logger.debug("{} {} dockerhost {} is not TAGged with DTI Event dcae_service_location {}" .format(node_instance.deployment_id, node_instance.id, docker_host, dcae_service_location)) continue # If DTI Event specifies component_type, then collector's service_component_type must match if component_type: c_component_type = rtp.get('service_component_type') if component_type != c_component_type: CfyClient._logger.debug( "{} {} component_types don't match".format(node_instance.deployment_id, node_instance.id)) continue # Check if the collector supports this VNF Type # scn:oti Consul key is authoritative for vnfTypes that a collector supports (not docker_config) dti_key = scn + ':oti' try: obj = ConsulClient.get_value(dti_key) except Exception as e: CfyClient._logger.error( "Unexpected exception {}: {!s} from ConsulClient.get_value({}) for {} {}" .format(type(e).__name__, e, dti_key, node_instance.deployment_id, node_instance.id) ) continue if not obj: CfyClient._logger.debug( "{} {} Consul key '{}' is empty or invalid".format(node_instance.deployment_id, node_instance.id, dti_key)) continue obj_types = set(k.lower() for k in obj) if dcae_target_type.lower() in obj_types: CfyClient._logger.debug( "{} {} is a valid collector for VNF Type {}".format(node_instance.deployment_id, node_instance.id, dcae_target_type)) cnt_found += 1 yield (scn, node_instance.deployment_id, container_id, node_instance.node_id, node_instance.id, node_instance.state, docker_host, dti_reconfig_script, container_type, '', '') continue else: CfyClient._logger.debug( "{} {} VNF Type {} is not in Consul key '{}'".format(node_instance.deployment_id, node_instance.id, dcae_target_type, dti_key)) continue msg = "Found {} components (collectors) for dcae_target_type={}, dcae_service_location={}, component_type={}" \ .format(cnt_found, dcae_target_type, dcae_service_location, component_type) CfyClient._logger.debug(msg) @staticmethod def iter_components_of_deployment(deployment_id, node_id=None, reconfig_type="app"): """ Iterate components of a specific deployment_id. Parameters ---------- deployment_id : string Cloudify deployment ID that created the component(s). node_id : string Cloudify node ID that created the component. reconfig_type : string "app" Returns ------- A generator of tuples of component information [ (scn, deployment_id, container_id, node_id, node_instance_id, node_instance_state, docker_host, reconfig_script, "docker"), ... ] or [ (scn, deployment_id, k8s_deployment, node_id, node_instance_id, node_instance_state, config_content, reconfig_script, "k8s"), ... ] """ cnt_found = 0 CfyClient.__set_cloudify_manager_client() for node_instance in CfyClient._client.node_instances.list( deployment_id=deployment_id, _include=['id','node_id','deployment_id','state','runtime_properties'] ): if node_id and node_instance.node_id != node_id: continue rtp = node_instance.runtime_properties # Skip this node_instance if it is not a collector container_type = "docker" container_id = rtp.get('container_id') if not container_id: container_type = "k8s" container_id = rtp.get('k8s_deployment') if not container_id: CfyClient._logger.debug("{} {} runtime_properties has no container_id or k8s_deployment".format(node_instance.deployment_id, node_instance.id)) continue reconfig_script = rtp.get('docker_config',{}).get('reconfigs',{}).get(reconfig_type) if not reconfig_script: CfyClient._logger.debug("{} {} runtime_properties has no docker_config.reconfigs.{}".format(node_instance.deployment_id, node_instance.id, reconfig_type)) continue scn = rtp.get('service_component_name') if not scn: CfyClient._logger.debug("{} {} runtime_properties has no service_component_name".format(node_instance.deployment_id, node_instance.id)) continue if container_type == "docker": docker_host = rtp.get('selected_container_destination') if not docker_host: CfyClient._logger.debug("{} {} runtime_properties has no selected_container_destination".format(node_instance.deployment_id, node_instance.id)) continue elif container_type == "k8s": docker_host = rtp.get('configuration',{}).get('file_content') if not docker_host: CfyClient._logger.debug("{} {} runtime_properties has no configuration.file_content".format(node_instance.deployment_id, node_instance.id)) continue CfyClient._logger.debug("{} {} is a {}-reconfigurable component".format(node_instance.deployment_id, node_instance.id, reconfig_type)) cnt_found += 1 yield (scn, node_instance.deployment_id, container_id, node_instance.node_id, node_instance.id, node_instance.state, docker_host, reconfig_script, container_type) continue msg = "Found {} {}-reconfigurable components".format(cnt_found, reconfig_type) CfyClient._logger.debug(msg)