saltstack api部署,使用.
#这几天一直在研究saltstack api,自己也走了很多坑,把部署,使用的过程记录下来分享给大家,欢迎大家一起交流,探讨。
#系统环境: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
# make testcert
umask 77 ; \
/usr/bin/openssl genrsa -aes128 2048 > /etc/pki/tls/private/localhost.key
Generating RSA private key, 2048 bit long modulus
......................................+++
.....................+++
e 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) :CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) :beijing
Organization Name (eg, company) :
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:jiechao@gmail.com
cd ../private/
# openssl rsa -in localhost.key -out localhost_nopass.key
Enter pass phrase for localhost.key:
writing RSA key
# useradd -M -s /sbin/nologin jc
# 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服务端配置:
# 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
# cat /etc/salt/master.d/eauth.conf
external_auth:
pam:
jc:
- .*
- '@wheel'
- '@runner'
#重启salt-master和salt-api服务:
# /etc/init.d/salt-master restart
Stopping salt-master daemon:
Starting salt-master daemon:
# /etc/init.d/salt-api restart
Stopping salt-api daemon:
Starting salt-api daemon:
# netstat -lntp|grep 8000
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 14695/python
#curl使用api:
# 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:
# 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测试查看系统内存:
# 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'
#脚本:
# 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']['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']['data']['return']['minions']
minions_pre = content['return']['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']['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']['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']
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']
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']['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']['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']['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()
#执行脚本:
# python saltapi.py
(, [])
True
页:
[1]