zoukankan      html  css  js  c++  java
  • saltstack主机管理项目【day39】:主机管理项目开发

    项目目标

    salt  state.apply   -h "ubuntu,centos"
    			     -g "ubuntu,centos"
    			     -f "ubuntu,centos"

    文件目录规划

    配置文件详解

    步骤一:创建一个salt 

    salt配置文件

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:Alex Li
    
    
    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)

    步骤二:utils命令分发器分发器通过action_list.py把不同的命令分给不同的模块

    #!/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")

    actions_list文件内容

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:Alex Li
    from Arya.plugins import cmd,state
    actions = {
        'cmd': cmd.CMD,
        'state':state.State
    }

    步骤三:state模块

    模块功能说明

    1. state模块加载yaml file 文件
    2. 根据字符串把所有的模块加载出来 
    3. 不同的操作系统语法不同,所以就有通用模块和特殊模块
    4. 解析还未做做
    5. 每个参数当做一个函数处理(等待商确)
    6. 通用类的好处 写一个通用的类 类的继承
    7. 体会到用继承类的好处

    具体配置文件

    state

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:Alex Li
    from Arya.backends.base_module import BaseSaltModule
    import os
    
    class State(BaseSaltModule):
    
        def load_state_files(self,state_filename):   #加载yumfeile
            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.")

    cmd

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

    file

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

    group

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:Alex Li
    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:Alex Li
    from Arya.backends.base_module import BaseSaltModule
    
    
    class Pkg(BaseSaltModule):
    
        pass 

    service

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

      

    user

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:Alex Li
    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 ')

    models

    from django.db import models
    
    # Create your models here.
    
    class Host(models.Model):         #主机管理
        hostname = models.CharField(max_length=128,unique=True)     #saltsack用hostname区别主机
        key = models.TextField()                #客户端主动找服务器,我想被你管理存放key文件
        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

    base_models

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:Alex Li
    
    
    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 ))
    

      

  • 相关阅读:
    jquery 实现 html5 placeholder 兼容password密码框
    php返回json的结果
    使用PHP读取远程文件
    Sharepoint 自定义字段
    Sharepoint 中新增 aspx页面,并在页面中新增web part
    【转】Sharepoint 2010 配置我的站点及BLOG
    JS 实现 Div 向上浮动
    UserProfile同步配置
    【转】Import User Profile Photos from Active Directory into SharePoint 2010
    Sharepoint 2010 SP1升级后 FIMSynchronizationService 服务无法开启
  • 原文地址:https://www.cnblogs.com/luoahong/p/7219480.html
Copyright © 2011-2022 走看看