Skip to content

Commit a62ced2

Browse files
authored
Merge pull request #165 from cloudify-incubator/RND-704-generic-deprecation-warning
add support for deprecation decorator
2 parents 10f3bb9 + bab4917 commit a62ced2

File tree

6 files changed

+199
-2
lines changed

6 files changed

+199
-2
lines changed

CHANGELOG.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
releases:
2+
v0.0.122: add deprecation_warning decorator.
23
v0.0.121: obfuscation_keywords kw arg in obfuscate_passwords.
34
v0.0.120: Upgrade Kubernetes 26.1.0.
45
v0.0.119: fix issue in plugin properties after 7.0.0 GA.

cloudify_common_sdk/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = '0.0.121'
1+
version = '0.0.122'

cloudify_common_sdk/deprecation.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Copyright (c) 2018 - 2023 Cloudify Platform Ltd. All rights reserved
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from functools import wraps
16+
17+
from cloudify import ctx
18+
from cfy_lint.yamllint_ext.rules.constants import (
19+
deprecated_node_types,
20+
deprecated_relationship_types
21+
)
22+
try:
23+
from cloudify.constants import RELATIONSHIP_INSTANCE, NODE_INSTANCE
24+
except ImportError:
25+
NODE_INSTANCE = 'node-instance'
26+
RELATIONSHIP_INSTANCE = 'relationship-instance'
27+
28+
29+
def deprecation_warning(func):
30+
@wraps(func)
31+
def inner(*args, **kwargs):
32+
check_deprecated_node_type()
33+
check_deprecated_relationship()
34+
return func(*args, **kwargs)
35+
return inner
36+
37+
38+
def check_deprecated_relationship():
39+
if ctx.type == RELATIONSHIP_INSTANCE:
40+
for rel in ctx.source.instance.relationships:
41+
if rel.target.node.id == ctx.target.node.id:
42+
new_rel_type = deprecated_relationship_types.get(rel.type)
43+
if new_rel_type:
44+
log_deprecation(rel.type, new_rel_type, 'relationship')
45+
source_node_type = deprecated_node_types.get(
46+
ctx.source.node.type)
47+
target_node_type = deprecated_node_types.get(
48+
ctx.target.node.type)
49+
if source_node_type:
50+
log_deprecation(
51+
ctx.source.node.type,
52+
source_node_type,
53+
'source node')
54+
if target_node_type:
55+
log_deprecation(
56+
ctx.target.node.type,
57+
target_node_type,
58+
'target node')
59+
else:
60+
for rel in ctx.instance.relationships:
61+
new_rel_type = deprecated_relationship_types.get(rel.type)
62+
if new_rel_type:
63+
log_deprecation(
64+
rel.type,
65+
new_rel_type,
66+
'relationship'
67+
)
68+
69+
70+
def check_deprecated_node_type():
71+
if ctx.type != NODE_INSTANCE:
72+
return
73+
new_node_type = deprecated_node_types.get(ctx.node.type)
74+
if new_node_type:
75+
log_deprecation(ctx.node.type, new_node_type)
76+
77+
78+
def log_deprecation(old_type, new_type, rel_or_node=None):
79+
rel_or_node = rel_or_node or 'node'
80+
ctx.logger.error(
81+
'The {rel_or_node} type {old_type} is deprecated, '
82+
'please update your blueprint to use {new_type}'.format(
83+
rel_or_node=rel_or_node,
84+
old_type=old_type,
85+
new_type=new_type,
86+
)
87+
)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Copyright (c) 2018 - 2023 Cloudify Platform Ltd. All rights reserved
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import mock
16+
import unittest
17+
from cloudify_common_sdk.deprecation import (
18+
log_deprecation,
19+
deprecation_warning,
20+
check_deprecated_node_type,
21+
check_deprecated_relationship,
22+
)
23+
24+
25+
@mock.patch('cloudify.state.current_ctx.get_ctx')
26+
class TestDeprecation(unittest.TestCase):
27+
28+
def test_log_deprecation(self, mock_get_ctx, *_):
29+
expected = 'The baz type foo is deprecated, ' \
30+
'please update your blueprint to use bar'
31+
mock_ctx = mock.Mock()
32+
mock_ctx.logger = mock.Mock()
33+
mock_get_ctx.return_value = mock_ctx
34+
log_deprecation(
35+
'foo', 'bar', 'baz')
36+
mock_ctx.logger.error.assert_called_with(expected)
37+
38+
@mock.patch('cloudify_common_sdk.deprecation.deprecated_node_types')
39+
@mock.patch('cloudify_common_sdk.deprecation.log_deprecation')
40+
def test_check_deprecated_node_type(
41+
self, mock_log, mock_deprecated, mock_get_ctx, *__):
42+
mock_deprecated.get.return_value = 'bar'
43+
44+
mock_ctx = mock.Mock()
45+
mock_ctx.type = 'node-instance'
46+
mock_ctx.logger = mock.Mock()
47+
48+
mock_ctx.node = mock.Mock(type='foo')
49+
mock_get_ctx.return_value = mock_ctx
50+
check_deprecated_node_type()
51+
mock_log.assert_called_with('foo', 'bar')
52+
53+
@mock.patch(
54+
'cloudify_common_sdk.deprecation.deprecated_relationship_types')
55+
@mock.patch('cloudify_common_sdk.deprecation.log_deprecation')
56+
def test_check_deprecated_relationship(
57+
self, mock_log, mock_deprecated, mock_get_ctx, *__):
58+
mock_deprecated.get.return_value = 'bar'
59+
60+
mock_node_ctx = mock.Mock(type='foo', id='qux')
61+
62+
mock_rel = mock.Mock()
63+
mock_rel.type = 'foo'
64+
mock_rel.target = mock.Mock(node=mock_node_ctx)
65+
mock_instance_ctx = mock.Mock(relationships=[mock_rel])
66+
67+
mock_source = mock.Mock()
68+
mock_source.instance = mock_instance_ctx
69+
mock_target = mock.Mock(node=mock_node_ctx)
70+
71+
mock_ctx = mock.Mock()
72+
mock_ctx.type = 'relationship-instance'
73+
mock_ctx.logger = mock.Mock()
74+
75+
mock_ctx.target = mock_target
76+
mock_ctx.source = mock_source
77+
78+
mock_get_ctx.return_value = mock_ctx
79+
check_deprecated_relationship()
80+
mock_log.assert_called_with('foo', 'bar', 'relationship')
81+
82+
@mock.patch(
83+
'cloudify_common_sdk.deprecation.check_deprecated_node_type')
84+
@mock.patch(
85+
'cloudify_common_sdk.deprecation.check_deprecated_relationship')
86+
def test_decorator(self, mock_a, mock_b, *_):
87+
88+
@deprecation_warning
89+
def foo(*args, **kwargs):
90+
for v in args:
91+
v('foo')
92+
for k, v in kwargs.items():
93+
v(k)
94+
95+
args = [mock.Mock(), mock.Mock()]
96+
kwargs = {
97+
'a': mock.Mock(),
98+
'b': mock.Mock()
99+
}
100+
101+
foo(*args, **kwargs)
102+
for v in args:
103+
v.assert_called_with('foo')
104+
for k, v in kwargs.items():
105+
v.assert_called_with(k)
106+
mock_a.assert_called_once()
107+
mock_b.assert_called_once()

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def get_version():
5858
'xmltodict', # rest
5959
"gitdb>=0.6.4", # shared download resource
6060
"GitPython", # shared download resource
61+
"cfy-lint>=0.0.31",
6162
'psutil',
6263
'packaging',
6364
'kubernetes==v26.1.0',

tox.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ whitelist_externals = bash
1919
commands =
2020
pytest -vv -s cloudify_kubernetes_sdk/tests/
2121
pytest -vv -s cloudify_common_sdk/tests/test_cli_tool_base.py
22-
nosetests -v -s --ignore-files="test_cli_tool_base\.py" --cover-html \
22+
pytest -vv -s cloudify_common_sdk/tests/test_deprecation.py
23+
nosetests -v -s --ignore-files="test_cli_tool_base\.py" --ignore-files="test_deprecation\.py" --cover-html \
2324
--with-coverage \
2425
--cover-package=cloudify_common_sdk \
2526
--cover-package=cloudify_rest_sdk \

0 commit comments

Comments
 (0)