コード例 #1
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def delete_expired_files(self):
     """delete expired toml/tmpl files in remote confd client
     """
     cfg_names = [x['name'] for x in self._files]
     for host in self._hosts:
         aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
         # 1. delete expired toml file
         tomls = self.get_tomls(host=host)
         for x in tomls:
             config = x.split(self._file_pre)[1].split('toml')[0].strip('.')
             if config not in cfg_names:
                 state, state_sum, results = ansible_safe_run(
                     aapi=aapi,
                     module='file',
                     args=dict(path=os.path.join(self._r_toml, x),
                               state='absent'))
                 msg = 'Toml File Deleted: %s' % state_sum
                 app.logger.debug(logmsg(msg))
                 msg = 'Toml File Deleted: %s' % results
                 app.logger.info(logmsg(msg))
         # 2. delete expired tmpl file
         tmpls = self.get_tmpls(host=host)
         for x in tmpls:
             config = x.split('.tmpl')[0]
             if config not in cfg_names:
                 state, state_sum, results = ansible_safe_run(
                     aapi=aapi,
                     module='file',
                     args=dict(path=os.path.join(self._r_tmpl,
                                                 self._folder_pre, x),
                               state='absent'))
                 msg = 'Tmpl File Deleted: %s' % state_sum
                 app.logger.debug(logmsg(msg))
                 msg = 'Tmpl File Deleted: %s' % results
                 app.logger.info(logmsg(msg))
コード例 #2
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def confd_cmd(self, action):
     """ confd client startup cmd """
     aapi = Ansible2API(hosts=self._hosts, **self._ansible_kwargs)
     state, state_sum, results = ansible_safe_run(
         aapi=aapi, module='shell', args=self._confd_startup_cmd[action])
     msg = 'Confd %s: %s' % (action.upper(), state_sum)
     app.logger.debug(logmsg(msg))
     msg = 'Confd %s: %s' % (action.upper(), results)
     app.logger.info(logmsg(msg))
コード例 #3
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def get_tmpl_content(self, cfg_name, host):
     """get template file content from remote confd client
     """
     aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
     state, state_sum, results = ansible_safe_run(
         aapi=aapi,
         module='shell',
         args='cat %s.tmpl' % os.path.join(self._folder_pre, cfg_name))
     msg = 'Tmpl File Get: %s' % state_sum
     app.logger.debug(logmsg(msg))
     msg = 'Tmpl File Get: %s' % results
     app.logger.info(logmsg(msg))
     return '%s\r\n' % results[host]['stdout']
コード例 #4
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def get_tmpls(self, host):
     """get template files from remote confd client
     """
     aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
     state, state_sum, results = ansible_safe_run(
         aapi=aapi,
         module='shell',
         args='ls %s | awk 1' %
         os.path.join(self._r_tmpl, self._folder_pre))
     msg = 'Tmpl File Check: %s' % state_sum
     app.logger.debug(logmsg(msg))
     msg = 'Tmpl File Check: %s' % results
     app.logger.info(logmsg(msg))
     return results[host]['stdout_lines']
コード例 #5
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def get_tomls(self, host):
     """get toml files from remote confd client
     """
     aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
     state, state_sum, results = ansible_safe_run(
         aapi=aapi,
         module='shell',
         args='ls %s | grep "^%s\..*\.toml$" | awk 1' %
         (self._r_toml, self._file_pre))
     msg = 'Toml File Check: %s' % state_sum
     app.logger.debug(logmsg(msg))
     msg = 'Toml File Check: %s' % results
     app.logger.info(logmsg(msg))
     return results[host]['stdout_lines']
コード例 #6
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def get_toml_content(self, cfg_name, host):
     """get toml file content from remote confd client
     """
     aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
     state, state_sum, results = ansible_safe_run(
         aapi=aapi,
         module='shell',
         args='cat %s.%s.toml' % (self._file_pre, cfg_name))
     msg = 'Toml File Get: %s' % state_sum
     app.logger.debug(logmsg(msg))
     msg = 'Toml File Get: %s' % results
     app.logger.info(logmsg(msg))
     results = results[host]['stdout_lines'][1:]
     ret = dict()
     for x in results:
         key, value = x.split(' = ')
         ret[key] = value.strip('\"')
     return ret
コード例 #7
0
 def setUp(self):
     ''' create ansible api object and mock attr '''
     self._hosts = ['127.0.0.1', '10.0.0.1']
     self._args = 'cat helloworld.txt'
     self._state = 0
     self._stat = {
         'unreachable': 0,
         'skipped': 0,
         'ok': 1,
         'changed': 1,
         'failures': 0
     }
     self._hostvars = {
         self._hosts[0]: {
             'out': {
                 u'changed': True,
                 u'end': u'2018-01-01 10:57:08.144560',
                 u'stdout': u'Hello World!',
                 u'cmd': self._args,
                 u'rc': 0,
                 u'start': u'2018-01-01 10:57:08.137068',
                 u'stderr': u'',
                 u'delta': u'0:00:00.007492',
                 'stdout_lines': [u'Hello World!'],
                 u'warnings': []
             }
         },
         self._hosts[1]: {
             'out': {
                 u'changed': True,
                 u'end': u'2018-01-01 10:57:08.144560',
                 u'stdout': u'Hello Leann!',
                 u'cmd': self._args,
                 u'rc': 0,
                 u'start': u'2018-01-01 10:57:08.137068',
                 u'stderr': u'',
                 u'delta': u'0:00:00.007492',
                 'stdout_lines': [u'Hello Leann!'],
                 u'warnings': []
             }
         }
     }
     TaskQueueManager.hostvars = self._hostvars
     self.aapi = Ansible2API(hosts=self._hosts)
コード例 #8
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def delete_files(self):
     """
         delete old toml/tmpl files in remote confd client
         ps: make sure that all these files have been backup already
     """
     for host in self._hosts:
         aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
         # 1. delete toml
         tomls = self.get_tomls(host=host)
         for x in tomls:
             state, state_sum, results = ansible_safe_run(
                 aapi=aapi,
                 module='file',
                 args=dict(path=os.path.join(self._r_toml, x),
                           state='absent'))
             msg = 'Toml File Deleted: %s' % state_sum
             app.logger.debug(logmsg(msg))
             msg = 'Toml File Deleted: %s' % results
             app.logger.info(logmsg(msg))
         # 2. delete tmpl
         state, state_sum, results = ansible_safe_run(
             aapi=aapi,
             module='file',
             args=dict(path='%s/' %
                       os.path.join(self._r_tmpl, self._folder_pre),
                       state='absent'))
         msg = 'Tmpl File Deleted: %s' % state_sum
         app.logger.debug(logmsg(msg))
         msg = 'Tmpl File Deleted: %s' % results
         app.logger.info(logmsg(msg))
         # 3. delete conf
         for x in self._files:
             state, state_sum, results = ansible_safe_run(
                 aapi=aapi,
                 module='file',
                 args=dict(path=os.path.join(x['dir'], x['name']),
                           state='absent'))
             msg = 'Conf File Deleted: %s' % state_sum
             app.logger.debug(logmsg(msg))
             msg = 'Conf File Deleted: %s' % results
             app.logger.info(logmsg(msg))
コード例 #9
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def get_uids(self, name, group):
     """fetch owner's uid and gid via name
     """
     aapi = Ansible2API(hosts=self._hosts, **self._ansible_kwargs)
     state, state_sum, results = ansible_safe_run(
         aapi=aapi,
         module='shell',
         args="cat /etc/passwd | grep ^%s: | awk -F ':' '{print $3}';"
         "cat /etc/passwd | grep ^%s: | awk -F ':' '{print $3}';" %
         (name, group))
     msg = 'Uid and Gid Get: %s' % state_sum
     app.logger.debug(logmsg(msg))
     msg = 'Uid and Gid Get: %s' % results
     app.logger.info(logmsg(msg))
     ret = {}
     for k, v in results.items():
         if len(v['stdout_lines']) == 2:
             ret[k] = dict(uid=v['stdout_lines'][0],
                           gid=v['stdout_lines'][1])
         else:
             raise Exception('{0}: No such user or group ({1}, {2})'.format(
                 k, name, group))
     return ret
コード例 #10
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def check_files(self):
     ret = {}
     template_regex = r'{{getv\s+"/%s"}}'
     mode_dict = {'-': 0, 'x': 1, 'w': 2, 'r': 4}
     aapi = Ansible2API(hosts=self._hosts, **self._ansible_kwargs)
     for x in self._files:
         abs_path = os.path.join(x['dir'], x['name'])
         ret[x['name']] = {host: {} for host in self._hosts}
         # 1. check md5
         # use tmpl to generate expected configuration file content
         content = x['template']
         for k, v in x['items'].items():
             content = re.sub(pattern=template_regex % k,
                              repl=v,
                              string=content)
         # cuz ansible shell 'stdout' will ignore terminal '\r\n'
         expected_raw = content.rstrip('\r\n')
         expected_md5 = md5hex(expected_raw)
         # use ansible to fetch file content
         state, state_sum, results = ansible_safe_run(
             aapi=aapi, module='shell', args='cat {0}'.format(abs_path))
         # compare the online to the expected using md5
         for host in self._hosts:
             if results[host]['stderr']:
                 ret[x['name']][host] = dict(
                     error='{0}: No such file or directory'.format(
                         abs_path))
             else:
                 actual_raw = results[host]['stdout'].rstrip('\r\n')
                 actual_md5 = md5hex(actual_raw)
                 if actual_md5 != expected_md5:
                     ret[x['name']][host]['content'] = '{0} != {1}'.format(
                         actual_md5, expected_md5)
                     ret[x['name']][host]['content_expected'] = expected_raw
                     ret[x['name']][host]['content_actual'] = actual_raw
                 else:
                     ret[x['name']][host]['content'] = "OK"
         # 2. check mode
         state, state_sum, results = ansible_safe_run(
             aapi=aapi,
             module='shell',
             args="ls -al %s|awk '{print $1}'" % abs_path)
         for host in self._hosts:
             if 'error' in ret[x['name']][host]:
                 continue
             mode = '0{0}{1}{2}'.format(
                 sum([mode_dict[y] for y in results[host]['stdout'][1:4]]),
                 sum([mode_dict[y] for y in results[host]['stdout'][4:7]]),
                 sum([mode_dict[y] for y in results[host]['stdout'][7:]]))
             ret[x['name']][host]['mode'] = ('{0} != {1}'.format(
                 mode, x['mode']) if mode != x['mode'] else 'OK')
         # 3. check owner
         state, state_sum, results = ansible_safe_run(
             aapi=aapi,
             module='shell',
             args="ls -al %s|awk '{print $3,$4}'" % abs_path)
         for host in self._hosts:
             if 'error' in ret[x['name']][host]:
                 continue
             owner = results[host]['stdout'].split()
             ret[x['name']][host]['owner'] = (
                 '{0} != {1}'.format(tuple(owner), (x['owner']['name'],
                                                    x['owner']['group']))
                 if owner[0] != x['owner']['name']
                 and owner[1] != x['owner']['group'] else 'OK')
         # 4. check modify time
         state, state_sum, results = ansible_safe_run(
             aapi=aapi,
             module='shell',
             args="ls --full-time %s|awk '{print $6,$7,$8}'" % abs_path)
         for host in self._hosts:
             if 'error' in ret[x['name']][host]:
                 continue
             ret[x['name']][host]['last_modify_time'] = results[host][
                 'stdout']
     return ret
コード例 #11
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def push_files(self, rollback=False):
     """ update toml/tmpl/(conf) files to remote/local confd client """
     for host in self._hosts:
         aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
         toml_folder = '%s/' % (os.path.join(self._l_toml_bak, host)
                                if rollback else os.path.join(
                                    self._l_toml, host))
         tmpl_folder = '{}/'.format(
             os.path.join(self._l_tmpl_bak, host) if rollback else self.
             _l_tmpl)
         if rollback:
             conf_folder = '%s/' % os.path.join(self._l_conf_bak, host)
             # clear folders
             remove_folder(toml_folder)
             remove_folder(tmpl_folder)
             remove_folder(conf_folder)
             get_folder(toml_folder)
             get_folder(tmpl_folder)
             get_folder(conf_folder)
             # download latest tomls/tmpls from minio
             toml_pre = '%s/' % os.path.join('toml', self._folder_pre, host)
             objs = self.minio.list_objects(bucket_name=self._minio_bucket,
                                            prefix=toml_pre,
                                            recursive=False)
             for x in objs:
                 object_name = x.object_name.encode('utf-8')
                 self.minio.fget_object(bucket_name=self._minio_bucket,
                                        object_name=object_name,
                                        file_path=os.path.join(
                                            toml_folder,
                                            os.path.basename(object_name)))
             tmpl_pre = '%s/' % os.path.join('tmpl', self._folder_pre, host)
             objs = self.minio.list_objects(bucket_name=self._minio_bucket,
                                            prefix=tmpl_pre,
                                            recursive=False)
             for x in objs:
                 object_name = x.object_name.encode('utf-8')
                 self.minio.fget_object(bucket_name=self._minio_bucket,
                                        object_name=object_name,
                                        file_path=os.path.join(
                                            tmpl_folder,
                                            os.path.basename(object_name)))
             conf_pre = '%s/' % os.path.join('conf', self._folder_pre, host)
             objs = self.minio.list_objects(bucket_name=self._minio_bucket,
                                            prefix=conf_pre,
                                            recursive=False)
             for x in objs:
                 object_name = x.object_name.encode('utf-8')
                 self.minio.fget_object(bucket_name=self._minio_bucket,
                                        object_name=object_name,
                                        file_path=os.path.join(
                                            conf_folder,
                                            os.path.basename(object_name)))
             # push conf files to remote/local confd client
             for x in os.listdir(conf_folder):
                 config = x.split(self._broken_word_2)
                 file_path = config[1].replace(self._broken_word_1, '/')
                 info = config[0].split('@@')
                 state, state_sum, results = ansible_safe_run(
                     aapi=aapi,
                     module='copy',
                     args=dict(mode=info[0],
                               src=os.path.join(conf_folder, x),
                               dest=file_path,
                               group=info[2],
                               owner=info[1]))
                 msg = 'Conf File Updated: %s' % state_sum
                 app.logger.debug(logmsg(msg))
                 msg = 'Conf File Updated: %s' % results
                 app.logger.info(logmsg(msg))
         # 1. push toml files to remote/local confd client
         state, state_sum, results = ansible_safe_run(
             aapi=aapi,
             module='copy',
             args=dict(mode=self._confd_file_mode,
                       src=toml_folder,
                       dest=self._r_toml,
                       group=self._confd_owner[1],
                       owner=self._confd_owner[0]))
         msg = 'Toml File Updated: %s' % state_sum
         app.logger.debug(logmsg(msg))
         msg = 'Toml File Updated: %s' % results
         app.logger.info(logmsg(msg))
         # 2. push tmpl files to remote/local confd client
         r_tmpl_folder = os.path.join(self._r_tmpl, self._folder_pre)
         state, state_sum, results = ansible_safe_run(
             aapi=aapi,
             module='copy',
             args=dict(mode=self._confd_file_mode,
                       src=tmpl_folder,
                       dest=r_tmpl_folder,
                       group=self._confd_owner[1],
                       owner=self._confd_owner[0]))
         msg = 'Tmpl File Updated: %s' % state_sum
         app.logger.debug(logmsg(msg))
         msg = 'Tmpl File Updated: %s' % results
         app.logger.info(logmsg(msg))
コード例 #12
0
ファイル: tool.py プロジェクト: leannmak/sakura
 def backup_files(self):
     """backup old toml/tmpl/cfg files from remote confd client to server
     """
     for host in self._hosts:
         # local filesystem
         toml_bak = os.path.join(self._l_toml_bak, host)
         tmpl_bak = os.path.join(self._l_tmpl_bak, host)
         conf_bak = os.path.join(self._l_conf_bak, host)
         remove_folder(toml_bak)
         remove_folder(tmpl_bak)
         remove_folder(conf_bak)
         get_folder(toml_bak)
         get_folder(tmpl_bak)
         get_folder(conf_bak)
         # minio server
         toml_pre = '%s/' % os.path.join('toml', self._folder_pre, host)
         tmpl_pre = '%s/' % os.path.join('tmpl', self._folder_pre, host)
         conf_pre = '%s/' % os.path.join('conf', self._folder_pre, host)
         objs = self.minio.list_objects(bucket_name=self._minio_bucket,
                                        prefix=toml_pre,
                                        recursive=False)
         for x in objs:
             self.minio.remove_object(
                 bucket_name=self._minio_bucket,
                 object_name=x.object_name.encode('utf-8'))
         objs = self.minio.list_objects(bucket_name=self._minio_bucket,
                                        prefix=tmpl_pre,
                                        recursive=False)
         for x in objs:
             self.minio.remove_object(
                 bucket_name=self._minio_bucket,
                 object_name=x.object_name.encode('utf-8'))
         objs = self.minio.list_objects(bucket_name=self._minio_bucket,
                                        prefix=conf_pre,
                                        recursive=False)
         for x in objs:
             self.minio.remove_object(
                 bucket_name=self._minio_bucket,
                 object_name=x.object_name.encode('utf-8'))
         aapi = Ansible2API(hosts=[host], **self._ansible_kwargs)
         # 1. backup toml to minio server
         tomls = self.get_tomls(host=host)
         for x in tomls:
             state, state_sum, results = ansible_safe_run(
                 aapi=aapi,
                 module='fetch',
                 args=dict(dest='%s/' % toml_bak,
                           src=os.path.join(self._r_toml, x),
                           flat='yes'))
             msg = 'Toml File Backup: %s' % state_sum
             app.logger.debug(logmsg(msg))
             msg = 'Toml File Backup: %s' % results
             app.logger.info(logmsg(msg))
             self.minio.fput_object(bucket_name=self._minio_bucket,
                                    object_name=os.path.join(toml_pre, x),
                                    file_path=os.path.join(toml_bak, x))
         # 2. backup tmpl to minio server
         tmpls = self.get_tmpls(host=host)
         for x in tmpls:
             state, state_sum, results = ansible_safe_run(
                 aapi=aapi,
                 module='fetch',
                 args=dict(dest='%s/' % tmpl_bak,
                           src=os.path.join(self._r_tmpl, self._folder_pre,
                                            x),
                           flat='yes'))
             msg = 'Tmpl File Backup: %s' % state_sum
             app.logger.debug(logmsg(msg))
             msg = 'Tmpl File Backup: %s' % results
             app.logger.info(logmsg(msg))
             self.minio.fput_object(bucket_name=self._minio_bucket,
                                    object_name=os.path.join(tmpl_pre, x),
                                    file_path=os.path.join(tmpl_bak, x))
         # 3. backup conf to minio server
         # files should include (name, dir, mode, owner)
         for x in self._files:
             src = os.path.join(x['dir'], x['name'])
             file_name = '%s%s%s' % ('@@'.join([
                 x['mode'], x['owner']['name'], x['owner']['group']
             ]), self._broken_word_2, src.replace('/', self._broken_word_1))
             state, state_sum, results = ansible_safe_run(
                 aapi=aapi,
                 module='fetch',
                 args=dict(dest=os.path.join(conf_bak, file_name),
                           src=src,
                           flat='yes'))
             msg = 'Conf File Backup: %s' % state_sum
             app.logger.debug(logmsg(msg))
             msg = 'Conf File Backup: %s' % results
             app.logger.info(logmsg(msg))
             file_path = os.path.join(conf_bak, file_name)
             if os.path.isfile(file_path):
                 self.minio.fput_object(bucket_name=self._minio_bucket,
                                        object_name=os.path.join(
                                            conf_pre, file_name),
                                        file_path=file_path)
         # 4. check if toml/tmpl/conf have been backuped to minio server
         objs = [
             os.path.basename(x.object_name.encode('utf-8')) for x in
             self.minio.list_objects(bucket_name=self._minio_bucket,
                                     prefix=toml_pre,
                                     recursive=False)
         ]
         for x in tomls:
             if x not in objs:
                 raise Exception('Toml Backup Failed: %s.' % x)
         objs = [
             os.path.basename(x.object_name.encode('utf-8')) for x in
             self.minio.list_objects(bucket_name=self._minio_bucket,
                                     prefix=tmpl_pre,
                                     recursive=False)
         ]
         for x in tmpls:
             if x not in objs:
                 raise Exception('Tmpl Backup Failed: %s.' % x)