#系统环境:Centos6. 5  X86_64
#python版本: 2.6 . 6
 
 
#安装salt服务和依赖:
cat /etc/redhat-release       
cd /etc/yum.repos.d/ && wget http: //dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release- 6 - 8 .noarch.rpm
yum -y install kernel-firmware kernel-headers perf e2fsprogs
rpm -ivh libyaml- 0.1 . 3 - 1.4 .el6.x86_64.rpm 
rpm -ivh PyYAML- 3.10 - 3.1 .el6.x86_64.rpm 
yum -y install salt-master salt-api 
 
 
#安装pip:
wget https: //pypi.python.org/packages/source/p/pip/pip-1.5.6.tar.gz#md5=01026f87978932060cc86c1dc527903e --no-check-certificate
tar xvfz pip- 1.5 . 6 .tar.gz
cd pip- 1.5 . 6
python setup.py build && python setup.py install && pip freeze
 
 
#使用pip安装cherrypy:
pip install cherrypy== 3.2 . 3
 
 
#配置openssl证书:
cd /etc/pki/tls/certs
[root@localhost certs]# make testcert
umask  77  ; \
         /usr/bin/openssl genrsa -aes128  2048  > /etc/pki/tls/ private /localhost.key
Generating RSA  private  key,  2048  bit long modulus
......................................+++
.....................+++
is  65537  ( 0x10001 )
Enter pass phrase:
Verifying - Enter pass phrase:
umask  77  ; \
         /usr/bin/openssl req -utf8 - new  -key /etc/pki/tls/ private /localhost.key -x509 -days  365  -out /etc/pki/tls/certs/localhost.crt -set_serial  0
Enter pass phrase  for  /etc/pki/tls/ private /localhost.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter  is  what  is  called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a  default  value,
If you enter  '.' , the field will be left blank.
-----
Country Name ( 2  letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:jiechao@gmail.com
cd ../ private /
[root@localhost  private ]# openssl rsa - in  localhost.key -out localhost_nopass.key
Enter pass phrase  for  localhost.key:
writing RSA key
[root@localhost  private ]# useradd -M -s /sbin/nologin jc
[root@localhost  private ]# passwd jc
Changing password  for  user jc.
New password: 
BAD PASSWORD: it  is  too simplistic/systematic
BAD PASSWORD:  is  too simple
Retype  new  password: 
passwd: all authentication tokens updated successfully.
 
 
#salt master配置文件:/etc/salt/master 
#取消注释
default_include: master.d/*.conf
mkdir -p /etc/salt/master.d
 
 
#saltstack服务端配置:
[root@localhost ~]# cat /etc/salt/master.d/api.conf 
rest_cherrypy:
   port:  8000
   ssl_crt: /etc/pki/tls/certs/localhost.crt
   ssl_key: /etc/pki/tls/ private /localhost_nopass.key
[root@localhost ~]# cat /etc/salt/master.d/eauth.conf 
external_auth:
   pam:
     jc:
       - .*
       '@wheel'
       '@runner'
  
#重启salt-master和salt-api服务: 
[root@localhost ~]# /etc/init.d/salt-master restart
Stopping salt-master daemon:                               [FAILED]
Starting salt-master daemon:                               [  OK  ]
[root@localhost ~]# /etc/init.d/salt-api restart
Stopping salt-api daemon:                                  [FAILED]
Starting salt-api daemon:                                  [  OK  ]
[root@localhost ~]# netstat -lntp|grep  8000
tcp         0       0  0.0 . 0.0 : 8000                 0.0 . 0.0 :*                   LISTEN       14695 /python  
 
 
#curl使用api:
[root@localhost ~]# curl -k https: //192.168.1.10:8000/login -H "Accept: application/x-yaml"  -d username='jc' -d password='123456' -d eauth='pam'
return :
- eauth: pam
   expire:  1419373087.9501131
   perms:
   - .*
   '@wheel'
   '@runner'
   start:  1419329887.9501131
   token: e214657dba43b46c482501349123jkpo
   user: jc
 
   
#saltstack安装客户端测试:
yum -y install salt-minion
#更改配置:/etc/salt/minion 
master:  192.168 . 1.10
id: localhost
/etc/init.d/salt-minion restart
 
 
 
#API测试test.ping:
[root@localhost ~]# curl -k https: //192.168.1.10:8000/ -H "Accept: application/x-yaml" -H "X-Auth-Token: e214657dba43b46c482501349123jkpo" -d client='local' -d tgt='*' -d fun='test.ping'
return :
- localhost:  true
 
 
#Api测试查看系统内存:
[root@localhost ~]# curl -k https: //192.168.1.10:8000/ -H "Accept: application/x-yaml" -H "X-Auth-Token: e214657dba43b46c482501349123jkpo" -d client='local' -d tgt='*' -d fun='cmd.run' -d arg="free -m"
return :
- localhost: '             total       used       free     shared    buffers     cached
     Mem:          13830       3375       10523           0         253         467
     -/+ buffers/cache:         655       11243
     Swap:          9000           0        9000 '
 
     
  #脚本:
[root@localhost ~]# cat saltapi.py 
#!/usr/bin/env python
import  urllib2,urllib
import  time
try :
     import  json
except ImportError:
     import  simplejson  as  json
class  SaltAPI(object):
     __token_id =  ''
     def __init__(self,url,username,password):
         self.__url = url.rstrip( '/' )
         self.__user = username
         self.__password = password
     def token_id(self):
         '' ' user login and get token id ' ''
         params = { 'eauth' 'pam' 'username' : self.__user,  'password' : self.__password}
         encode = urllib.urlencode(params)
         obj = urllib.unquote(encode)
         content = self.postRequest(obj,prefix= '/login' )
         try :
             self.__token_id = content[ 'return' ][ 0 ][ 'token' ]
         except KeyError:
             raise KeyError
     def postRequest(self,obj,prefix= '/' ):
         url = self.__url + prefix
         headers = { 'X-Auth-Token'    : self.__token_id}
         req = urllib2.Request(url, obj, headers)
         opener = urllib2.urlopen(req)
         content = json.loads(opener.read())
         return  content
     def list_all_key(self):
         params = { 'client' 'wheel' 'fun' 'key.list_all' }
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         minions = content[ 'return' ][ 0 ][ 'data' ][ 'return' ][ 'minions' ]
         minions_pre = content[ 'return' ][ 0 ][ 'data' ][ 'return' ][ 'minions_pre' ]
         return  minions,minions_pre
     def delete_key(self,node_name):
         params = { 'client' 'wheel' 'fun' 'key.delete' 'match' : node_name}
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         ret = content[ 'return' ][ 0 ][ 'data' ][ 'success' ]
         return  ret
     def accept_key(self,node_name):
         params = { 'client' 'wheel' 'fun' 'key.accept' 'match' : node_name}
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         ret = content[ 'return' ][ 0 ][ 'data' ][ 'success' ]
         return  ret
     def remote_noarg_execution(self,tgt,fun):
         '' ' Execute commands without parameters ' ''
         params = { 'client' 'local' 'tgt' : tgt,  'fun' : fun}
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         ret = content[ 'return' ][ 0 ][tgt]
         return  ret
     def remote_execution(self,tgt,fun,arg):
         '' ' Command execution with parameters ' ''        
         params = { 'client' 'local' 'tgt' : tgt,  'fun' : fun,  'arg' : arg}
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         ret = content[ 'return' ][ 0 ][tgt]
         return  ret
     def target_remote_execution(self,tgt,fun,arg):
         '' ' Use targeting for remote execution ' ''
         params = { 'client' 'local' 'tgt' : tgt,  'fun' : fun,  'arg' : arg,  'expr_form' 'nodegroup' }
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         jid = content[ 'return' ][ 0 ][ 'jid' ]
         return  jid
     def deploy(self,tgt,arg):
         '' ' Module deployment ' ''
         params = { 'client' 'local' 'tgt' : tgt,  'fun' 'state.sls' 'arg' : arg}
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         return  content
     def async_deploy(self,tgt,arg):
         '' ' Asynchronously send a command to connected minions ' ''
         params = { 'client' 'local_async' 'tgt' : tgt,  'fun' 'state.sls' 'arg' : arg}
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         jid = content[ 'return' ][ 0 ][ 'jid' ]
         return  jid
     def target_deploy(self,tgt,arg):
         '' ' Based on the node group forms deployment ' ''
         params = { 'client' 'local_async' 'tgt' : tgt,  'fun' 'state.sls' 'arg' : arg,  'expr_form' 'nodegroup' }
         obj = urllib.urlencode(params)
         self.token_id()
         content = self.postRequest(obj)
         jid = content[ 'return' ][ 0 ][ 'jid' ]
         return  jid
def main():
     sapi = SaltAPI(url= 'https://192.168.1.10:8000' ,username= 'jc' ,password= '123456' )
     print sapi.list_all_key()
#    sapi.token_id()
     #sapi.delete_key( 'test-01' )
     print sapi.accept_key( 'localhost' )
     #sapi.deploy( 'test-01' , 'nginx' )
     #print sapi.remote_noarg_execution( 'test-01' , 'grains.items' )
if  __name__ ==  '__main__' :
     main()
 
     
#执行脚本:
[root@localhost ~]# python saltapi.py 
([u 'localhost' ], [])
True

本文出自 “IMySQL” 博客,请务必保留此出处http://jiechao2012.blog.51cto.com/3251753/1594077