コード例 #1
0
class Autopatch():
    def __init__(self, file_name):
        self.file_name = file_name
        self.ticket = Ticket()
        with open(self.file_name, 'r') as f:
            self.hostnames = f.readlines()

#return issue in Jira

    def issue_jira(self, jira_query):
        jira = Jira()
        issues = jira.get_issues(jira_query)
        return issues

#ping the host and return status

    def host_up(self, host):
        status, result = subprocess.getstatusoutput("ping -c 1 " + host)
        if status == 0:
            return True
        else:
            return False

#Ticket reader

    def ticket_reader(self, issue_keys):
        pkgs = []
        for key in issue_keys:
            jira_query = f'issuekey = {key} and status not in(Completed)'
            issues_package = self.issue_jira(jira_query)
            for issue in issues_package:
                description = issue.fields.description.split('\n')
                for line in description:
                    if 'Remote' in line:
                        pkgs.append(line.split(':')[1])
                    else:
                        continue
        return pkgs

#host package check

    def host_pkg_ckeck(self, host, pkgs):
        packages = []
        pattern = re.compile(r'([\w]+)')
        for pkg in pkgs:
            pkg2 = re.search(pattern, pkg).group(0)
            ssh_list = subprocess.Popen([
                "ssh", "-o", "StrictHostKeyChecking=no", "-o",
                " BatchMode=yes",
                "%s" % host,
                "sudo yum list  %s | grep %s" % (pkg, pkg2)
            ],
                                        shell=False,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
            result1 = ssh_list.stdout.read()
            result2 = result1.decode('utf-8')
            package = result2.split(' ')[0]
            if package not in packages:
                if '.x86_64' in package:
                    packages.append(package.replace('.x86_64', ''))
                elif '.i686' in package:
                    packages.append(package.replace('.i686', ''))
                else:
                    packages.append(package)
        return packages

#check server Status

    def check_status(self, host):
        ssh_list = subprocess.Popen([
            "ssh", "-o", "StrictHostKeyChecking=no", "-o", " BatchMode=yes",
            "%s" % host, "sudo server-enabled status | grep Status"
        ],
                                    shell=False,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
        result1 = ssh_list.stdout.read()
        result2 = result1.decode('utf-8')
        if 'enabled' in result2:
            return True
        else:
            return False

#enable host

    def do_enable(self, host):
        disable = subprocess.Popen([
            "ssh", "-o", "StrictHostKeyChecking=no", "-o", " BatchMode=yes",
            "%s" % host,
            "sudo server-enabled enable --unlock --comment 'Enabled After patching' | grep Status"
        ],
                                   shell=False,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        res = disable.stdout.read()
        result = res.decode('utf-8')
        if 'enable' in result:
            return True
        else:
            return False

#Disable host

    def do_disable(self, host):
        disable = subprocess.Popen([
            "ssh", "-o", "StrictHostKeyChecking=no", "-o", " BatchMode=yes",
            "%s" % host,
            "sudo server-enabled disable --lock --comment 'Disabled for patching' | grep Status"
        ],
                                   shell=False,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        res = disable.stdout.read()
        result = res.decode('utf-8')
        if 'disable' in result:
            return True
        else:
            return False

# Create a list of hosts with data

    def host_data(self):
        hosts = {}
        for host in self.hostnames:
            issue_keys = self.ticket.host_finder(host.strip())
            status = self.host_up(host.strip())
            if issue_keys:
                pkgs = self.ticket_reader(issue_keys)
                if status:
                    packages = self.host_pkg_ckeck(host.strip(), pkgs)
                    enable = self.check_status(host.strip())
                    hosts.update({
                        host.strip(): {
                            'issue': issue_keys,
                            'status': status,
                            'pkgs': packages,
                            'enabled': enable
                        }
                    })
                else:
                    hosts.update({
                        host.strip(): {
                            'issue': issue_keys,
                            'status': False,
                            'pkgs': None,
                            'enabled': False
                        }
                    })
            else:
                if status:
                    hosts.update({
                        host.strip(): {
                            'issue': None,
                            'status': status,
                            'pkgs': None,
                            'enabled': False
                        }
                    })
                else:
                    hosts.update({
                        host.strip(): {
                            'issue': None,
                            'status': False,
                            'pkgs': None,
                            'enabled': False
                        }
                    })
        return hosts
# ###########Package update section

    def yum_clean(self, host):
        print("yum clean")
        kernel_cleaner = subprocess.Popen([
            "ssh", "-o", "StrictHostKeyChecking=no", "-o", " BatchMode=yes",
            "%s" % host, "sudo yum clean all"
        ],
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE)
        result1 = kernel_cleaner.stdout.read()
        result2 = result1.decode('utf-8')
        print(result2)

    def kernel_update(self, host):
        print("kernel_cleaner")
        kernel_cleaner = subprocess.Popen([
            "ssh", "-o", "StrictHostKeyChecking=no", "-o", " BatchMode=yes",
            "%s" % host, "sudo /box/bin/kernel_cleaner"
        ],
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE)
        result1 = kernel_cleaner.stdout.read()
        result2 = result1.decode('utf-8')
        print(result2)
        self.yum_clean(host)
        kernel_install = subprocess.Popen([
            "ssh", "-o", "StrictHostKeyChecking=no", "-o", " BatchMode=yes",
            "%s" % host, "sudo yum install", "kernel", "kernel-headers", "-y"
        ],
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE)

        result1 = kernel_install.stdout.read()
        result2 = result1.decode('utf-8')
        print(result2)
        kernel_update_package = subprocess.Popen([
            "ssh", "-o", "StrictHostKeyChecking=no", "-o", " BatchMode=yes",
            "%s" % host, "sudo yum update", "perf", "python-perf",
            "microcode_ctl ", "kernel-devel", "-y"
        ],
                                                 stdout=subprocess.PIPE,
                                                 stderr=subprocess.PIPE)
        result1 = kernel_update_package.stdout.read()
        result2 = result1.decode('utf-8')
        print(result2)
#
#
#
#

    def package_update(self, host, pkgs):
        for pkg in pkgs:

            package_update = subprocess.Popen([
                "ssh", "-o", "StrictHostKeyChecking=no", "-o",
                " BatchMode=yes",
                "%s" % host, "sudo yum update -y",
                "%s" % pkg
            ],
                                              stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE)
            result1 = package_update.stdout.read()
            result2 = result1.decode('utf-8')
            print(result2)

    def reboot(self, host):
        reboot = subprocess.Popen([
            "ssh", "-o", "StrictHostKeyChecking=no", "-o", " BatchMode=yes",
            "%s" % host, "sudo reboot now"
        ],
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE)
        result1 = package_update.stdout.read()
        result2 = result1.decode('utf-8')
        print(result2)


###########End od section

#Patching Method

    def patch(self):
        down = []
        disabled_hosts = []
        data = self.host_data()
        for key in data.keys():
            if data[key]['status']:
                while data[key]['enabled']:
                    if self.do_disable(key):
                        data[key]['enabled'] = False
                        disabled_hosts.append(key)
                if len(data[key]['pkgs']) >= 1:
                    if 'kernel' in data[key]['pkgs']:
                        data[key]['pkgs'].remove('kernel')
                        data[key]['pkgs'].remove('kernel-headers')
                        data[key]['pkgs'].remove('kernel-firmware.noarch')
                        if 'perf.x86_64' in data[key]['pkgs']:
                            data[key]['pkgs'].remove('perf')
                        if 'python-perf.x86_64' in data[key]['pkgs']:
                            data[key]['pkgs'].remove('python-perf')
                        if 'kernel-devel.x86_64' in data[key]['pkgs']:
                            data[key]['pkgs'].remove('kernel-devel')
                        if 'microcode_ctl.x86_64' in data[key]['pkgs']:
                            data[key]['pkgs'].remove('microcode_ctl')
                        self.kernel_update(key)
                        if len(data[key]['pkgs']) >= 1:
                            self.package_update(key, data[key]['pkgs'])