b9b32bf2ff9400beb4587d8713a84ec86a4ddb5f
[dcaegen2/platform/plugins.git] / k8s / k8splugin / decorators.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 copy
22
23 from cloudify import ctx
24 from cloudify.exceptions import NonRecoverableError, RecoverableError
25
26 from k8splugin import discovery as dis
27 from k8splugin import utils
28 from k8splugin.exceptions import (DockerPluginDependencyNotReadyError,
29                                   DockerPluginDeploymentError)
30
31
32 def monkeypatch_loggers(task_func):
33     """Sets up the dependent loggers"""
34
35     def wrapper(**kwargs):
36         # Ouch! Monkeypatch loggers
37         dis.logger = ctx.logger
38
39         return task_func(**kwargs)
40
41     return wrapper
42
43
44 def wrap_error_handling_start(task_start_func):
45     """Wrap error handling for the start operations"""
46
47     def wrapper(**kwargs):
48         try:
49             return task_start_func(**kwargs)
50         except DockerPluginDependencyNotReadyError as e:
51             # You are here because things we need like a working docker host is not
52             # available yet so let Cloudify try again later.
53             raise RecoverableError(e)
54         except DockerPluginDeploymentError as e:
55             # Container failed to come up in the allotted time. This is deemed
56             # non-recoverable.
57             raise NonRecoverableError(e)
58         except Exception as e:
59             ctx.logger.error("Unexpected error while starting container: {0}"
60                     .format(str(e)))
61             raise NonRecoverableError(e)
62
63     return wrapper
64
65
66 def _wrapper_merge_inputs(task_func, properties, **kwargs):
67     """Merge Cloudify properties with input kwargs before calling task func"""
68     inputs = copy.deepcopy(properties)
69     # Recursively update
70     utils.update_dict(inputs, kwargs)
71
72     # Apparently kwargs contains "ctx" which is cloudify.context.CloudifyContext
73     # This has to be removed and not copied into runtime_properties else you get
74     # JSON serialization errors.
75     if "ctx" in inputs:
76         del inputs["ctx"]
77
78     return task_func(**inputs)
79
80 def merge_inputs_for_create(task_create_func):
81     """Merge all inputs for start operation into one dict"""
82
83     # Needed to wrap the wrapper because I was seeing issues with
84     # "RuntimeError: No context set in current execution thread"
85     def wrapper(**kwargs):
86         # NOTE: ctx.node.properties is an ImmutableProperties instance which is
87         # why it is passed into a mutable dict so that it can be deep copied
88         return _wrapper_merge_inputs(task_create_func,
89                 dict(ctx.node.properties), **kwargs)
90
91     return wrapper
92
93 def merge_inputs_for_start(task_start_func):
94     """Merge all inputs for start operation into one dict"""
95
96     # Needed to wrap the wrapper because I was seeing issues with
97     # "RuntimeError: No context set in current execution thread"
98     def wrapper(**kwargs):
99         return _wrapper_merge_inputs(task_start_func,
100                 ctx.instance.runtime_properties, **kwargs)
101
102     return wrapper
103
104 def wrap_error_handling_update(update_func):
105     """ Wrap error handling for update operations (scale and upgrade) """
106
107     def wrapper(**kwargs):
108         try:
109             return update_func(**kwargs)
110         except DockerPluginDeploymentError:
111             raise NonRecoverableError ("Update operation did not complete successfully in the alloted time")
112         except Exception as e:
113             ctx.logger.error ("Unexpected error during update operation: {0}".format(str(e)))
114             raise NonRecoverableError(e)
115
116     return wrapper