zoukankan      html  css  js  c++  java
  • saltstack主机管理项目:今日总结(六)

    一、总目录

    二、具体代码

    salt

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    
    
    import os,sys
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Stark.settings")
        BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        #print(BASE_DIR)
        sys.path.append(BASE_DIR)
        from Arya.action_list import actions
        from Arya.backends.utils import ArgvManagement
        obj = ArgvManagement(sys.argv)

    models

    from django.db import models
    # Create your models here.
    class Host(models.Model):
        hostname = models.CharField(max_length=128,unique=True)
        key = models.TextField()
        status_choices = ((0,'Waiting Approval'),
                          (1,'Accepted'),
                          (2,'Rejected'))
    
    
        os_type_choices =(
            ('redhat','RedhatCentOS'),
            ('ubuntu','Ubuntu'),
            ('suse','Suse'),
            ('windows','Windows'),
        )
    
        os_type = models.CharField(choices=os_type_choices,max_length=64,default='redhat')
        status = models.SmallIntegerField(choices=status_choices,default=0)
    
        def __str__(self):
            return self.hostname
    class HostGroup(models.Model):
        name =  models.CharField(max_length=64,unique=True)
        hosts = models.ManyToManyField(Host,blank=True)
    
        def __str__(self):
            return self.name

    admin

    from django.contrib import admin
    
    # Register your models here.
    from Arya import models
    admin.site.register(models.Host)
    admin.site.register(models.HostGroup)

    base_module

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    
    
    class BaseSaltModule(object):
        def __init__(self,sys_argvs,db_models,settings):
            self.db_models = db_models
            self.settings = settings
            self.sys_argvs = sys_argvs
    
        def get_selected_os_types(self):
            data = {}
            for host in self.host_list:
                data[host.os_type] = []
            print('--->data',data)
            return data
        def process(self):
            self.fetch_hosts()
            self.config_data_dic = self.get_selected_os_types()
        def require(self,*args,**kwargs):
            pass
        def fetch_hosts(self):
            print('--fetching hosts---')
    
            if '-h' in self.sys_argvs or '-g' in self.sys_argvs:
                host_list = []
                if '-h' in self.sys_argvs:
                    host_str_index = self.sys_argvs.index('-h') +1
                    if len(self.sys_argvs) <= host_str_index:
                        exit("host argument must be provided after -h")
                    else: #get the host str
                        host_str = self.sys_argvs[host_str_index]
                        host_str_list = host_str.split(',')
                        host_list += self.db_models.Host.objects.filter(hostname__in=host_str_list)
                if '-g' in self.sys_argvs:
                    group_str_index = self.sys_argvs.index('-g') +1
                    if len(self.sys_argvs) <= group_str_index:
                        exit("group argument must be provided after -g")
                    else: #get the group str
                        group_str = self.sys_argvs[group_str_index]
                        group_str_list = group_str.split(',')
                        group_list = self.db_models.HostGroup.objects.filter(name__in=group_str_list)
                        for group in group_list:
                            host_list += group.hosts.select_related()
                self.host_list = set(host_list)
                return True
                print('----host list:', host_list)
            else:
                exit("host [-h] or group[-g] argument must be provided")
    
    
        def syntax_parser(self,section_name,mod_name,mod_data):
            print("-going to parser state data:",section_name,mod_name)
            for state_item in mod_data:
                print("	",state_item)
                for key,val in state_item.items():
                    if hasattr(self,key):
                        state_func = getattr(self,key)
                        state_func(val)
                    else:
                        exit("Error:module [%s] has no argument [%s]" %( mod_name,key ))

    utils

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:Alex Li
    import sys
    
    from Arya import action_list
    import django
    django.setup()
    
    from Stark import settings
    from Arya import models
    class ArgvManagement(object):
        '''
        接收用户指令并分配到相应模块
        '''
        def __init__(self,argvs):
            self.argvs = argvs
            self.argv_parse()
    
        def help_msg(self):
            print("Available modules:")
            for registered_module in action_list.actions:
                print("  %s" % registered_module)
            exit()
        def argv_parse(self):
            #print(self.argvs)
            if len(self.argvs) <2:
                self.help_msg()
            module_name = self.argvs[1]
            if '.' in module_name:
                mod_name,mod_method = module_name.split('.')
                module_instance  = action_list.actions.get(mod_name)
                if module_instance:#matched
                    module_obj = module_instance(self.argvs,models,settings)
                    module_obj.process() #提取 主机
                    if hasattr(module_obj,mod_method):
                        module_method_obj = getattr(module_obj,mod_method)#解析任务,发送到队列,取任务结果
                        module_method_obj() #调用指定的指令
                    else:
                        exit("module [%s] doesn't have [%s] method" % (mod_name,mod_method))
            else:
                exit("invalid module name argument")

    cmd

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    
    from Arya.backends.base_module import BaseSaltModule
    class CMD(BaseSaltModule):
        print('in cmd module ')

    file

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    from Arya.backends.base_module import BaseSaltModule
    class File(BaseSaltModule):
        pass

    group

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    from Arya.backends.base_module import BaseSaltModule
    class Group(BaseSaltModule):
    
        def gid(self,*args,**kwargs):
            pass

    pkg

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    from Arya.backends.base_module import BaseSaltModule
    class Pkg(BaseSaltModule):
    
        pass

    service

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    from Arya.backends.base_module import BaseSaltModule
    class Service(BaseSaltModule):
        pass

    state

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    from Arya.backends.base_module import BaseSaltModule
    import os
    
    class State(BaseSaltModule):
    
        def load_state_files(self,state_filename):
            from yaml import load, dump
            try:
                from yaml import CLoader as Loader, CDumper as Dumper
            except ImportError:
                from yaml import Loader, Dumper
            state_file_path = "%s/%s" %(self.settings.SALT_CONFIG_FILES_DIR,state_filename)
            if os.path.isfile(state_file_path):
                with open(state_file_path) as f:
                    data = load(f.read(), Loader=Loader)
                    return data
            else:
                exit("%s is not a valid yaml config file" % state_filename)
    
        def apply(self):
            '''
            1. load the configurations file
            2. parse it
            3. create a task and sent it to the MQ
            4. collect the result with task-callback id
            :return:
            '''
    
    
            if '-f' in self.sys_argvs:
                yaml_file_index = self.sys_argvs.index('-f') + 1
                try:
                    yaml_filename = self.sys_argvs[yaml_file_index]
                    state_data = self.load_state_files(yaml_filename)
                    #print('state data:',state_data)
    
                    for os_type,os_type_data in self.config_data_dic.items(): #按照不同的操作系统单独生成一份配置文件
                        for section_name,section_data in state_data.items():
                            print('Section:',section_name)
    
                            for mod_name,mod_data in section_data.items():
                                base_mod_name = mod_name.split(".")[0]
                                plugin_file_path = "%s/%s.py" % (self.settings.SALT_PLUGINS_DIR,base_mod_name)
                                if os.path.isfile(plugin_file_path):
                                    #导入 模块
    
                                    module_plugin = __import__('plugins.%s' %base_mod_name)
                                    special_os_module_name = "%s%s" %(os_type.capitalize(),base_mod_name.capitalize())
                                    #print('dir module plugin:',module_plugin,base_mod_name)
                                    #getattr(module_plugin,base_mod_name)
                                    module_file= getattr(module_plugin, base_mod_name) # 这里才是真正导入模块
                                    if hasattr(module_file, special_os_module_name): #判断有没有根据操作系统的类型进行特殊解析 的类,在这个文件里
                                        module_instance = getattr(module_file, special_os_module_name)
                                    else:
                                        module_instance = getattr(module_file, base_mod_name.capitalize())
    
                                    #开始调用 此module 进行配置解析
                                    module_obj = module_instance(self.sys_argvs,self.db_models,self.settings)
                                    module_obj.syntax_parser(section_name,mod_name,mod_data )
                                else:
                                    exit("module [%s] is not exist" % base_mod_name)
                                #print("  ",mod_name)
                                #for state_item in mod_data:
                                #    print("	",state_item)
    
                except IndexError as e:
                    exit("state file must be provided after -f")
    
            else:
                exit("statefile must be specified.")

    user

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:luoahong
    from Arya.backends.base_module import BaseSaltModule
    
    
    class User(BaseSaltModule):
        def uid(self,*args,**kwargs):
            pass
        def gid(self,*args,**kwargs):
            pass
        def shell(self,*args,**kwargs):
            pass
        def home(self,*args,**kwargs):
            pass
    
    class UbuntuUser(User):
        def home(self,*args,**kwargs):
            print('in ubnutn home ')

    三、调用逻辑图

    四、流程解析

    1、salt开始
    2、utils命令分发器

    把不同的命令分发到不同的模块
    怎么样才能把不同的命令分发给不同的模块
    通过actions_list对应着不同的模块

    3、actions
    4、 'state':state.State对应着 state模块


    1、加载load_state_files
    2、解析
    3、创建一个任务扔到MO

      1. 根据字符串把plugins里面的组件一个个的加载出来
      2. 不同的操作系统的语法是不一样
      3. 如果没有进行特殊处理,就调通用模块
      4. 如果有特殊处理,就用相同的模块处理
      5. 通用类的好处
  • 相关阅读:
    [LeetCode 1029] Two City Scheduling
    POJ 2342 Anniversary party (树形DP入门)
    Nowcoder 106 C.Professional Manager(统计并查集的个数)
    2018 GDCPC 省赛总结
    CF 977 F. Consecutive Subsequence
    Uva 12325 Zombie's Treasure Chest (贪心,分类讨论)
    Poj 2337 Catenyms(有向图DFS求欧拉通路)
    POJ 1236 Network of Schools (强连通分量缩点求度数)
    POJ 1144 Network (求割点)
    POJ 3310 Caterpillar(图的度的判定)
  • 原文地址:https://www.cnblogs.com/luoahong/p/9427613.html
Copyright © 2011-2022 走看看