blob: 0813b5b994e3691dc5aad0ed1213ebd27560c1b1 [file] [log] [blame]
Hanna Arhipova94a8abe2019-08-22 14:11:46 +03001# Copyright 2016 Mirantis, Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# 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, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
Hanna Arhipova94a8abe2019-08-22 14:11:46 +030014from tcp_tests import logger
15from tcp_tests.managers.execute_commands import ExecuteCommandsMixin
16
17LOG = logger.logger
18
19
20class ReclassManager(ExecuteCommandsMixin):
21 """docstring for ReclassManager"""
22
23 __config = None
24 __underlay = None
25 reclass_tools_cmd = ". venv-reclass-tools/bin/activate; reclass-tools "
Hanna Arhipovab2522692020-09-23 15:25:11 +030026 tgt = "cfg01" # place where the reclass-tools installed
Hanna Arhipova94a8abe2019-08-22 14:11:46 +030027
28 def __init__(self, config, underlay):
29 self.__config = config
30 self.__underlay = underlay
31
32 reclass_node = [node_name
33 for node_name in self.__underlay.node_names()
34 if self.tgt in node_name]
35 self.ssh = self.__underlay.remote(node_name=reclass_node[0])
36
37 super(ReclassManager, self).__init__(config=config, underlay=underlay)
38
39 def check_existence(self, key):
Hanna Arhipova54fec802020-10-30 12:45:46 +020040 """
41 Returns True if reclass contains that key.
42 :param key: string
43 :return: boolean
44 """
Hanna Arhipova94a8abe2019-08-22 14:11:46 +030045 if key in self.ssh.check_call(
Hanna Arhipovab2522692020-09-23 15:25:11 +030046 "{reclass_tools} get-key {key} /srv/salt/reclass/classes".
47 format(reclass_tools=self.reclass_tools_cmd,
48 key=key)):
Hanna Arhipova94a8abe2019-08-22 14:11:46 +030049 LOG.warning("({}) key already exists in reclass".format(key))
50 return True
51 return False
52
53 def add_key(self, key, value, short_path):
54 """
55 Shows alert if key exists
56
57 :param key: string, parameters which will be added or updated
58 :param value: value of key
59 :param short_path: path to reclass yaml file.
60 It takes into account default path where the reclass locates.
61 May look like cluster/*/cicd/control/leader.yml
62 :return: None
63 """
Hanna Arhipova54fec802020-10-30 12:45:46 +020064
65 value = str(value).replace('"', "'")
66 # let's escape $ symbol for bash-like command
67 value = str(value).replace("$", r"\$")
68
69 # value can contain a space symbol. So value should be in quotes
70 cmd = "{reclass_tools} add-key {key} \"{value}\" \
Hanna Arhipova94a8abe2019-08-22 14:11:46 +030071 /srv/salt/reclass/classes/{path}".format(
72 reclass_tools=self.reclass_tools_cmd,
73 key=key,
74 value=value,
Hanna Arhipova54fec802020-10-30 12:45:46 +020075 path=short_path)
76 LOG.info("Add key to reclass: \n {cmd} ".format(cmd=cmd))
77 self.ssh.check_call(cmd)
Hanna Arhipova94a8abe2019-08-22 14:11:46 +030078
Hanna Arhipova19429962019-10-17 15:16:49 +030079 def get_key(self, key, file_name):
Dmitriy Kruglov07977de2019-09-02 13:15:18 +020080 """Find a key in a YAML
81
82 :param key: string, parameter to add
Hanna Arhipova19429962019-10-17 15:16:49 +030083 :param file_name: name of YAML file to find a key
Dmitriy Kruglov07977de2019-09-02 13:15:18 +020084 :return: str, key if found
85 """
Hanna Arhipovab2522692020-09-23 15:25:11 +030086 LOG.info("Try to get '{key}' key from '{file}' file".format(
87 file=file_name,
88 key=key
89 ))
Hanna Arhipova19429962019-10-17 15:16:49 +030090 request_key = self.ssh.check_call(
91 "{reclass_tools} get-key {key} /srv/salt/reclass/*/{file_name}".
92 format(reclass_tools=self.reclass_tools_cmd,
93 key=key,
94 file_name=file_name))['stdout']
95
96 # Reclass-tools returns result to stdout, so we get it as
97 # ['\n',
98 # '---\n',
99 # '# Found parameters._param.jenkins_pipelines_branch in \
100 # /srv/salt/reclass/classes/cluster/../infra/init.yml\n',
101 # 'release/proposed/2019.2.0\n',
102 # '...\n',
103 # '\n']
104 # So we have no chance to get value without dirty code like `stdout[3]`
105
Hanna Arhipovab2522692020-09-23 15:25:11 +0300106 LOG.info("Raw output from reclass.get_key {}".format(request_key))
Hanna Arhipova19429962019-10-17 15:16:49 +0300107 if len(request_key) < 4:
Hanna Arhipovab2522692020-09-23 15:25:11 +0300108 print("Can't find {key} in {file_name}. Got stdout {stdout}".
109 format(key=key,
110 file_name=file_name,
111 stdout=request_key))
112 return None
Hanna Arhipova19429962019-10-17 15:16:49 +0300113 value = request_key[3].strip('\n')
114 LOG.info("From reclass.get_key {}".format(value))
115 return value
Dmitriy Kruglov07977de2019-09-02 13:15:18 +0200116
Hanna Arhipova94a8abe2019-08-22 14:11:46 +0300117 def add_bool_key(self, key, value, short_path):
118 """
119 Shows alert if key exists
120
121 :param key: string, parameters which will be added or updated
122 :param value: value of key
123 :param short_path: path to reclass yaml file.
124 It takes into account default path where the reclass locates.
125 May look like cluster/*/cicd/control/leader.yml
126 :return: None
127 """
128 self.check_existence(key)
129 self.ssh.check_call(
130 "{reclass_tools} add-bool-key {key} {value} \
131 /srv/salt/reclass/classes/{path}".format(
132 reclass_tools=self.reclass_tools_cmd,
133 key=key,
134 value=value,
135 path=short_path
136 ), raise_on_err=False)
137
138 def add_class(self, value, short_path):
139 """
140 Shows warning if class exists
141 :param value: role to add to 'classes' parameter in the reclass
142 :param short_path: path to reclass yaml file.
143 It takes into account default path where the reclass locates.
144 May look like cluster/*/cicd/control/leader.yml
145 :return: None
146 """
147 if value in self.ssh.check_call(
148 "{reclass_tools} get-key classes \
149 /srv/salt/reclass/classes/{path}".format(
150 reclass_tools=self.reclass_tools_cmd,
151 value=value,
152 path=short_path
153 )):
154 LOG.warning("Class {} already exists in {}".format(
155 value,
156 short_path
157 ))
158
159 self.ssh.check_call(
160 "{reclass_tools} add-key classes {value} \
161 /srv/salt/reclass/classes/{path} --merge".format(
162 reclass_tools=self.reclass_tools_cmd,
163 value=value,
164 path=short_path
165 ))
Ekaterina Chernovaa6087342019-08-26 13:14:42 +0300166
167 def delete_key(self, key, short_path):
168 """
169 Remove key from the provided file
170
171 :param value: string, parameter which will be deleted
172 :param short_path: string,, path to reclass yaml file.
173 It takes into account default path where the reclass locates.
174 May look like cluster/*/cicd/control/leader.yml
175 :return: None
176 """
177 self.ssh.check_call(
178 "{reclass_tools} del-key {key} \
179 /srv/salt/reclass/classes/{path}".format(
180 reclass_tools=self.reclass_tools_cmd,
181 key=key,
182 path=short_path
183 ))