![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 if __name__ =='__main__': 2 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Stark.settings") 3 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 4 sys.path.append(BASE_DIR) 5 from Arya.backends.utils import ArgvManagement 6 obj = ArgvManagement(sys.argv)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 import sys 2 import django 3 django.setup() 4 from Stark import settings 5 from Arya import action_list 6 from Arya import models 7 8 9 class ArgvManagement(object): 10 """ 11 接受用户从命令行输入的指令,并分配到相应的模块 12 """ 13 def __init__(self,argvs): 14 self.argvs = argvs 15 self.argv_parse() 16 17 def help_msg(self): 18 print("Available modules:") 19 for registered_module in action_list.actions: 20 print(" %s" % registered_module) 21 exit() 22 23 def argv_parse(self): 24 if len(self.argvs) < 2: 25 self.help_msg() 26 module_name = self.argvs[1] 27 if "." in module_name: 28 mod_name,mod_method = module_name.split('.') 29 module_instance = action_list.actions.get(mod_name) 30 if module_instance: 31 module_obj = module_instance(self.argvs,models,settings) 32 module_obj.process() #解析任务,发送到队列,取任务结果 33 if hasattr(module_obj,mod_method): 34 module_method_obj = getattr(module_obj,mod_method) 35 module_method_obj()#调用指定的指令 36 else: 37 exit("module [%s] doesn't have [%s] method" % (mod_name,mod_method)) 38 else: 39 exit('invalid module name argument')
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 class BaseSaltModule(object): 2 3 def __init__(self,sys_argvs,db_models,settings): 4 self.sys_argvs = sys_argvs 5 self.db_models = db_models 6 self.setting =settings 7 8 def process(self): 9 self.fetch_hosts() 10 self.config_data_dic = self.get_selected_os_types() 11 12 def get_selected_os_types(self): 13 data = {} 14 for host in self.host_list: 15 data[host.os_type] = [] 16 print('-->data',data) 17 return data 18 19 def fetch_hosts(self): 20 print("there fetching host") 21 if '-h' in self.sys_argvs or '-g' in self.sys_argvs: 22 host_list = [] 23 if '-h' in self.sys_argvs: 24 host_str_index = self.sys_argvs.index('-h')+1 25 if len(self.sys_argvs) <= host_str_index: 26 exit('host argument must be provide after -h') 27 else: 28 host_str = self.sys_argvs[host_str_index] 29 host_str_list = host_str.split(',') 30 host_list += self.db_models.Host.objects.filter(hostname__in = host_str_list ) 31 if '-g' in self.sys_argvs: 32 group_str_index = self.sys_argvs.index('-g')+1 33 if len(self.sys_argvs) <= group_str_index: 34 exit('group argument must be provide after -g') 35 else: 36 group_str = self.sys_argvs[group_str_index] 37 group_str_list = group_str.split(',') 38 group_list = self.db_models.HostGroup.objects.filter(name__in = group_str_list ) 39 for group in group_list: 40 host_list +=group.host.select_related() 41 self.host_list = set(host_list) 42 return True 43 else: 44 print('host [-h] argument or [-g] argument must be provided') 45 46 def syntax_parser(self, section_name, mod_name, mod_data): 47 print("-going to parser state data:", section_name, mod_name) 48 for state_item in mod_data: 49 print("\t", state_item) 50 for key, val in state_item.items(): 51 if hasattr(self, key): 52 state_func = getattr(self, key) 53 state_func(val) 54 else: 55 exit("Error:module [%s] has no argument [%s]" % (mod_name, key)) 56 57 def require(self,*args,**kwargs): 58 pass
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 import os 2 from Arya.backends.base_module import BaseSaltModule 3 4 5 class State(BaseSaltModule): 6 7 def load_state_files(self, state_filename): 8 from yaml import load, dump 9 try: 10 from yaml import CLoader as Loader, CDumper as Dumper 11 except ImportError: 12 from yaml import Loader, Dumper 13 state_file_path = "%s/%s" % (self.setting.SALT_CONFIG_FILES_DIR, state_filename) 14 if os.path.isfile(state_file_path): 15 with open(state_file_path) as f: 16 data = load(f.read(), Loader=Loader) 17 return data 18 else: 19 exit("%s is not a valid yaml config file" % state_filename) 20 21 22 def apply(self): 23 """ 24 1、下载配置文件 25 2、解析 26 3、创建一个任务,并发送到队列 27 4、收集任务结果 28 :return: 29 """ 30 if '-f' in self.sys_argvs: 31 yaml_file_index = self.sys_argvs.index('-f') + 1 32 try: 33 yaml_filename = self.sys_argvs[yaml_file_index] 34 state_data = self.load_state_files(yaml_filename) 35 for os_type, os_type_data in self.config_data_dic.items(): # 按照不同的操作系统单独生成一份配置文件 36 for section_name, section_data in state_data.items(): 37 print('Section:', section_name) 38 for mod_name, mod_data in section_data.items(): 39 base_mod_name = mod_name.split(".")[0] 40 plugin_file_path = "%s/%s.py" % (self.setting.SALT_PLUGINS_DIR, base_mod_name) 41 if os.path.isfile(plugin_file_path): 42 module_plugin = __import__('plugins.%s' % base_mod_name) 43 special_os_module_name = "%s%s" % (os_type.capitalize(), base_mod_name.capitalize()) 44 getattr(module_plugin, base_mod_name) 45 module_file = getattr(module_plugin, base_mod_name) 46 if hasattr(module_file, special_os_module_name): # 判断有没有根据操作系统的类型进行特殊解析 的类,在这个文件里 47 module_instance = getattr(module_file, special_os_module_name) 48 else: 49 module_instance = getattr(module_file, base_mod_name.capitalize()) 50 module_obj = module_instance(self.sys_argvs, self.db_models, self.setting) 51 module_obj.syntax_parser(section_name, mod_name, mod_data) 52 else: 53 exit("module [%s] is not exist" % base_mod_name) 54 print(" ",mod_name) 55 for state_item in mod_data: 56 print("\t",state_item) 57 # base_mod_name = mod_name.split(".")[0] 58 # plugin_file_path = "%s/%s.py" % (self.setting.SALT_PLUGINS_DIR, base_mod_name) 59 # if os.path.isfile(plugin_file_path): 60 # # 导入 模块 61 # 62 # module_plugin = __import__('plugins.%s' % base_mod_name) 63 # special_os_module_name = "%s%s" % (os_type.capitalize(), base_mod_name.capitalize()) 64 # # print('dir module plugin:',module_plugin,base_mod_name) 65 # # getattr(module_plugin,base_mod_name) 66 # module_file = getattr(module_plugin, base_mod_name) # 这里才是真正导入模块 67 # if hasattr(module_file, special_os_module_name): # 判断有没有根据操作系统的类型进行特殊解析 的类,在这个文件里 68 # module_instance = getattr(module_file, special_os_module_name) 69 # else: 70 # module_instance = getattr(module_file, base_mod_name.capitalize()) 71 # 72 # # 开始调用 此module 进行配置解析 73 # module_obj = module_instance(self.sys_argvs, self.db_models, self.settings) 74 # module_obj.syntax_parser(section_name, mod_name, mod_data) 75 # else: 76 # exit("module [%s] is not exist" % base_mod_name) 77 # # print(" ",mod_name) 78 # # for state_item in mod_data: 79 # # print("\t",state_item) 80 81 except IndexError as e: 82 exit("state file must be provided after -f") 83 84 else: 85 exit("statefile must be specified.")
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 from Arya.backends.base_module import BaseSaltModule 2 3 class User(BaseSaltModule): 4 5 def uid(self,*args): 6 pass 7 8 def gid(self,*args): 9 pass 10 11 def shell(self,*args): 12 pass 13 14 def home(self,*args): 15 pass 16 17 class UbuntuUser(User): 18 def home(self,*args): 19 print('in ubuntu ')
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 from Arya.plugins import cmd,state 2 3 actions = { 4 'cmd': cmd.CMD, 5 'state':state.State 6 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 from django.db import models 2 3 # Create your models here. 4 5 6 class Host(models.Model): 7 8 hostname = models.CharField(max_length=32) 9 key = models.TextField() 10 11 status_choices = ((0,'Waiting'), 12 (1,'Accepted'), 13 (2,'Rejected')) 14 status = models.SmallIntegerField(choices=status_choices,default=0) 15 os_type_choices = ( 16 ('redhat', 'Redhat\CentOS'), 17 ('ubuntu', 'Ubuntu'), 18 ('suse', 'Suse'), 19 ('windows', 'Windows'), 20 ) 21 os_type = models.CharField(choices=os_type_choices, max_length=64, default='redhat') 22 23 def __str__(self): 24 return self.hostname 25 26 class HostGroup(models.Model): 27 name = models.CharField(max_length=64,unique=True) 28 host = models.ManyToManyField(Host,blank=True) 29 30 def __str__(self): 31 return self.name
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 apache: 2 #pkg.installed: [] 3 #service.running: 4 # - reload: True 5 # - watch: 6 # - file: /etc/httpd/conf/httpd.conf 7 user.present: 8 - uid: 87 9 #- username: alex 10 - gid: 87 11 - home: /var/www/html 12 - shell: /bin/nologin 13 - require: 14 - group: apache 15 group.present: 16 - gid: 87 17 - require: 18 - pkg: apache 19 20 #/etc/httpd/conf/httpd.conf: 21 # file.managed: 22 # - source: salt://apache/httpd.conf 23 # - user: root 24 # - group: root 25 # - mode: 644
setting.py中的配置
SALT_CONFIG_FILES_DIR = "%s/Arya/salt_configs" % BASE_DIR
SALT_PLUGINS_DIR = "%s/Arya/plugins" % BASE_DIR
命令行输入调试命令:
python salt.py state.apply -h "windows,redhat" -g "group2" -f test.yml