1 # ============LICENSE_START=======================================================
3 # ================================================================================
4 # Copyright (c) 2017-2020 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
10 # http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 from cloudify import ctx
22 from cloudify.decorators import operation
23 from cloudify.exceptions import NonRecoverableError
24 from relationshipplugin import discovery as dis
28 SERVICE_COMPONENT_NAME = "service_component_name"
29 SELECTED_CONTAINER_DESTINATION = "selected_container_destination"
30 CONSUL_HOST = "consul_host"
32 CONSUL_HOSTNAME = "localhost"
35 # Lifecycle interface calls for component_connect_to
37 # NOTE: ctx.source and ctx.target are RelationshipSubjectContext
38 # Order of operation of relationships is bit confusing. These operations are
39 # implemented for `target_interfaces`. By observation, the target node processed,
40 # then the source is created, the relationship is run then the source is started.
41 # http://getcloudify.org/guide/3.1/dsl-spec-relationships.html#relationship-interfaces
44 def add_relationship(**kwargs):
45 """Adds target to the source relationship list"""
47 conn = dis.create_kv_conn(CONSUL_HOSTNAME)
49 source_name = ctx.source.instance.runtime_properties[SERVICE_COMPONENT_NAME]
50 # The use case for using the target name override is for the platform
51 # blueprint where the cdap broker needs to connect to a cdap cluster but
52 # the cdap cluster does not not use the component plugins so the name is
54 # REVIEW: Re-review this
55 target_name = kwargs["target_name_override"] \
56 if "target_name_override" in kwargs \
57 else ctx.target.instance.runtime_properties[SERVICE_COMPONENT_NAME]
59 dis.store_relationship(conn, source_name, target_name)
60 ctx.logger.info("Created relationship: {0} to {1}".format(source_name,
62 except Exception as e:
63 ctx.logger.error("Unexpected error while adding relationship: {0}"
65 raise NonRecoverableError(e)
68 def remove_relationship(**kwargs):
69 """Removes target from the source relationship list"""
71 conn = dis.create_kv_conn(CONSUL_HOSTNAME)
73 source_name = ctx.source.instance.runtime_properties[SERVICE_COMPONENT_NAME]
74 dis.delete_relationship(conn, source_name)
75 ctx.logger.info("Removed relationship: {0}".format(source_name))
76 except Exception as e:
77 ctx.logger.error("Unexpected error while removing relationship: {0}"
79 raise NonRecoverableError(e)
82 # Lifecycle interface calls for component_contained_in
85 def forward_destination_info(**kwargs):
87 selected_target = ctx.target.instance.runtime_properties[SERVICE_COMPONENT_NAME]
88 ctx.source.instance.runtime_properties[SELECTED_CONTAINER_DESTINATION] = selected_target
89 ctx.logger.info("Forwarding selected target: {0}".format(ctx.source.instance.id))
90 except Exception as e:
91 ctx.logger.error("Unexpected error while forwarding selected target: {0}"
93 raise NonRecoverableError(e)
96 def registered_to(**kwargs):
98 Intended to be used in platform blueprints, but possible to be reused elsewhere
100 ctx.logger.info(str(kwargs))
101 address = kwargs["address_to_register"]
102 name = kwargs["name_to_register"]
103 port = kwargs["port_to_register"]
105 (consul_host, consul_port) = (CONSUL_HOSTNAME, 8500)
106 #Storing in source because that's who is getting registered
107 ctx.source.instance.runtime_properties[CONSUL_HOST] = "http://{0}:{1}".format(consul_host, consul_port)
108 ctx.source.instance.runtime_properties["name_to_register"] = name #careful! delete does not have access to inputs
111 response = requests.put(url = "{0}/v1/agent/service/register".format(ctx.source.instance.runtime_properties[CONSUL_HOST]),
117 headers={'Content-Type': 'application/json'})
118 response.raise_for_status() #bomb if not 2xx
119 except Exception as e:
120 ctx.logger.error("Error while registering: {0}".format(str(e)))
121 raise NonRecoverableError(e)
124 def registered_to_delete(**kwargs):
126 The deletion/opposite of registered_to
128 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"]),
129 headers={'Content-Type': 'Content-Type: application/json'})
130 #this is on delete so do not do any checking