b17403cb8614749f678853696e22e16b4d65e951
[dcaegen2/platform/plugins.git] / relationships / relationshipplugin / tasks.py
1 # ============LICENSE_START=======================================================
2 # org.onap.dcae
3 # ================================================================================
4 # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
5 # ================================================================================
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #      http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 # ============LICENSE_END=========================================================
18 #
19 # ECOMP is a trademark and service mark of AT&T Intellectual Property.
20
21 import json
22 from cloudify import ctx
23 from cloudify.decorators import operation
24 from cloudify.exceptions import NonRecoverableError
25 from relationshipplugin import discovery as dis
26 import requests
27
28
29 SERVICE_COMPONENT_NAME = "service_component_name"
30 SELECTED_CONTAINER_DESTINATION = "selected_container_destination"
31 CONSUL_HOST = "consul_host"
32
33 CONSUL_HOSTNAME = "localhost"
34
35
36 # Lifecycle interface calls for component_connect_to
37
38 # NOTE: ctx.source and ctx.target are RelationshipSubjectContext
39 # Order of operation of relationships is bit confusing. These operations are
40 # implemented for `target_interfaces`. By observation, the target node processed,
41 # then the source is created, the relationship is run then the source is started.
42 # http://getcloudify.org/guide/3.1/dsl-spec-relationships.html#relationship-interfaces
43
44 @operation
45 def add_relationship(**kwargs):
46     """Adds target to the source relationship list"""
47     try:
48         conn = dis.create_kv_conn(CONSUL_HOSTNAME)
49
50         source_name = ctx.source.instance.runtime_properties[SERVICE_COMPONENT_NAME]
51         # The use case for using the target name override is for the platform
52         # blueprint where the cdap broker needs to connect to a cdap cluster but
53         # the cdap cluster does not not use the component plugins so the name is
54         # not generated.
55         # REVIEW: Re-review this
56         target_name = kwargs["target_name_override"] \
57             if "target_name_override" in kwargs \
58             else ctx.target.instance.runtime_properties[SERVICE_COMPONENT_NAME]
59
60         dis.store_relationship(conn, source_name, target_name)
61         ctx.logger.info("Created relationship: {0} to {1}".format(source_name,
62             target_name))
63     except Exception as e:
64         ctx.logger.error("Unexpected error while adding relationship: {0}"
65                 .format(str(e)))
66         raise NonRecoverableError(e)
67
68 @operation
69 def remove_relationship(**kwargs):
70     """Removes target from the source relationship list"""
71     try:
72         conn = dis.create_kv_conn(CONSUL_HOSTNAME)
73
74         source_name = ctx.source.instance.runtime_properties[SERVICE_COMPONENT_NAME]
75         dis.delete_relationship(conn, source_name)
76         ctx.logger.info("Removed relationship: {0}".format(source_name))
77     except Exception as e:
78         ctx.logger.error("Unexpected error while removing relationship: {0}"
79                 .format(str(e)))
80         raise NonRecoverableError(e)
81
82
83 # Lifecycle interface calls for component_contained_in
84
85 @operation
86 def forward_destination_info(**kwargs):
87     try:
88         selected_target = ctx.target.instance.runtime_properties[SERVICE_COMPONENT_NAME]
89         ctx.source.instance.runtime_properties[SELECTED_CONTAINER_DESTINATION] = selected_target
90         ctx.logger.info("Forwarding selected target: {0}".format(ctx.source.instance.id))
91     except Exception as e:
92         ctx.logger.error("Unexpected error while forwarding selected target: {0}"
93                 .format(str(e)))
94         raise NonRecoverableError(e)
95
96 @operation
97 def registered_to(**kwargs):
98     """
99     Intended to be used in platform blueprints, but possible to be reused elsewhere
100     """
101     ctx.logger.info(str(kwargs))
102     address = kwargs["address_to_register"]
103     name = kwargs["name_to_register"]
104     port = kwargs["port_to_register"]
105
106     (consul_host, consul_port) = (CONSUL_HOSTNAME, 8500)
107     #Storing in source because that's who is getting registered
108     ctx.source.instance.runtime_properties[CONSUL_HOST] = "http://{0}:{1}".format(consul_host, consul_port)
109     ctx.source.instance.runtime_properties["name_to_register"] = name #careful! delete does not have access to inputs
110     
111     try:
112         response = requests.put(url = "{0}/v1/agent/service/register".format(ctx.source.instance.runtime_properties[CONSUL_HOST]),
113                      json = {
114                               "name" : name,
115                               "Address" : address,
116                               "Port" : int(port)
117                             },
118                      headers={'Content-Type': 'application/json'})
119         response.raise_for_status() #bomb if not 2xx
120     except Exception as e:
121         ctx.logger.error("Error while registering: {0}".format(str(e)))
122         raise NonRecoverableError(e)
123
124 @operation
125 def registered_to_delete(**kwargs):
126     """
127     The deletion/opposite of registered_to
128     """
129     requests.put(url = "{0}/v1/agent/service/deregister/{1}".format(ctx.source.instance.runtime_properties[CONSUL_HOST], ctx.source.instance.runtime_properties["name_to_register"]),
130                  headers={'Content-Type': 'Content-Type: application/json'})
131     #this is on delete so do not do any checking