saltstack-api使用詳解


目錄

1.1 salt-api安裝

1.2 編寫python腳本請求salt api接口

1.1 salt-api安裝

  參考博客:https://www.jianshu.com/p/012ccdff93cc

  1、介紹

    1. saltsatck本身就提供了一套算完整的api,使用 CherryPy 來實現 restful 的 api,供外部的程序調用。

    2. salt-api需要安裝,然后進行一些配置才可以正常使用

  2、安裝salt-api,並設置開機啟動

    yum -y install salt-api pyOpenSSL

    systemctl enable salt-api

  3、配置自簽名證書

      cd /etc/pki/tls/certs/

      make testcert

Enter pass phrase:    ===>  輸入加密短語,這里我使用salt2017
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 []:

交互模式輸入密碼等
交互模式輸入密碼等

  4、解密key文件,生成無密碼的key文件

    注:過程中需要輸入key密碼,該密碼為之前生成證書時設置的密碼

    cd /etc/pki/tls/private/

    openssl rsa -in localhost.key -out localhost_nopass.key

  5、修改文件權限

    chmod 755 /etc/pki/tls/certs/localhost.crt
    chmod 755 /etc/pki/tls/private/localhost.key
    chmod 755 /etc/pki/tls/private/localhost_nopass.key

  6、添加用戶

    注:生產環境請使用密碼復雜度高的密碼,這里我使用 chnsys@2016

    useradd -M -s /sbin/nologin saltapi          # 創建用戶 saltapi

    passwd saltapi                                    # 為用戶saltapi設置密碼

  7、配置salt-api

    sed -i '/#default_include/s/#default/default/g' /etc/salt/master

  8、創建/etc/salt/master.d/目錄    

    mkdir -p /etc/salt/master.d/
    cd /etc/salt/master.d/
    touch eauth.conf
    touch api.conf

external_auth:
  pam:
    saltapi:   # 用戶
      - .*     # 該配置文件給予saltapi用戶所有模塊使用權限,出於安全考慮一般只給予特定模塊使用權限
eauth.conf
rest_cherrypy:
  port: 8001
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/private/localhost_nopass.key
api.conf

  9、啟動salt-api

    systemctl restart salt-master
    systemctl start salt-api
    ps -ef|grep salt-api
    netstat -lnput|grep 8001

  10、測試獲取token

    curl -k https://192.168.56.11:8001/login -H "Accept: application/x-yaml"  -d username='saltapi'  -d password='chnsys@2016'  -d eauth='pam'

  11、調用test.ping

    curl -k https://192.168.56.11:8001/ -H "Accept: application/x-yaml" -H "X-Auth-Token: 87cbb68e0babf3d0ad6b3741795667dbe62b3c11" -d client='local' -d tgt='*' -d fun='test.ping'

1.2 編寫python腳本請求salt api接口

  1、使用python簡單測試接口執行命令

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = 'junxi'


import requests
import json
try:
    import cookielib
except:
    import http.cookiejar as cookielib

# 使用urllib2請求https出錯,做的設置
import ssl
context = ssl._create_unverified_context()

# 使用requests請求https出現警告,做的設置
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


salt_api = "https://192.168.56.11:8001/"


class SaltApi:
    """
    定義salt api接口的類
    初始化獲得token
    """
    def __init__(self, url):
        self.url = url
        self.username = "saltapi"
        self.password = "chnsys@2016"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
            "Content-type": "application/json"
        }
        self.params = {'client': 'local', 'fun': '', 'tgt': ''}
        self.login_url = salt_api + "login"
        self.login_params = {'username': self.username, 'password': self.password, 'eauth': 'pam'}
        self.token = self.get_data(self.login_url, self.login_params)['token']
        self.headers['X-Auth-Token'] = self.token

    def get_data(self, url, params):
        send_data = json.dumps(params)
        request = requests.post(url, data=send_data, headers=self.headers, verify=False)
        response = request.json()
        result = dict(response)
        return result['return'][0]

    def salt_command(self, tgt, method, arg=None):
        """遠程執行命令,相當於salt 'client1' cmd.run 'free -m'"""
        if arg:
            params = {'client': 'local', 'fun': method, 'tgt': tgt, 'arg': arg}
        else:
            params = {'client': 'local', 'fun': method, 'tgt': tgt}
        print '命令參數: ', params
        result = self.get_data(self.url, params)
        return result

def main():
    salt = SaltApi(salt_api)
    salt_client = '*'
    salt_test = 'test.ping'
    result1 = salt.salt_command(salt_client, salt_test)
    print result1
    # 返回結果:{u'linux-node1.example.com': True, u'linux-node2.example.com': True}

if __name__ == '__main__':
    main()

使用python簡單測試接口執行命令
使用python簡單測試接口執行命令

  2、使用requests模塊獲取基本信息

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import requests
import json
import logging
logging.captureWarnings(True)  # 屏蔽由於訪問https時沒有證書警告問題

SALT_BASE_URL = 'https://192.168.56.11:8001/'
SALT_USER = 'saltapi'
SALT_PWD = 'chnsys@2016'


class SaltAPI(object):
    __token_id = ''

    def __init__(self):
        self.__url = SALT_BASE_URL
        self.__user = SALT_USER
        self.__password = SALT_PWD

    def token_id(self):
        """
            用戶登陸和獲取token
        :return:
        """
        params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
        content = self.postRequest(self.__url + '/login', data=params)
        try:
            self.__token_id = content[0]['token']
        except Exception as e:
            print '**** Failed to get token, {} ****'.format(str(e))

    def postRequest(self, url, data=None):
        headers = {"X-Auth-Token": self.__token_id}
        ret = requests.post(url=url, data=data, json='json', headers=headers, verify=False)
        if ret.status_code == 200:
            return ret.json()['return']
        return ret.text

    def remote_execution_module(self, tgt, fun, arg):
        """
            遠程執行模塊,有參數
        :param tgt: minion list
        :param fun: 模塊
        :param arg: 參數
        :return: dict, {'minion1': 'ret', 'minion2': 'ret'}
        """
        params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
        self.token_id()
        return self.postRequest(self.__url, params)

    def salt_alive(self, tgt):
        '''
        salt主機存活檢測
        '''
        params = {'client': 'local', 'tgt': tgt, 'fun': 'test.ping'}
        self.token_id()
        return self.postRequest(self.__url, params)


if __name__ == '__main__':
    salt = SaltAPI()
    minions_list = [
        'cloud:type',
        'cluster:domain',
        'cluster:name',
        'cpu_model',
        'fqdn_ip4',
        'hospital:type',
        'kernelrelease',
        'nodename',
        'os',
        'osmajorrelease',
        'osrelease',
        'saltversion',
        'serialnumber',
        'virtual',
        'num_cpus',
        'mem_total',
        'cloud:region',
        'ipv4',
    ]
    ret = salt.remote_execution_module('*', 'grains.item', minions_list)
    print json.dumps(ret, ensure_ascii=False)


'''
[{
    "linux-node1.example.com": {
        "osrelease": "7.6.1810",
        "fqdn_ip4": ["192.168.56.11"],
        "serialnumber": "VMware-56 4d 26 83 60 7c bb 5a-14 17 6a ab c2 45 f2 7a",
        "nodename": "linux-node1.example.com",
        "kernelrelease": "3.10.0-957.1.3.el7.x86_64",
        "cloud:type": "",
        "num_cpus": 1,
        "saltversion": "2018.3.3",
        "cpu_model": "Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz",
        "virtual": "VMware",
        "cluster:domain": "",
        "cluster:name": "",
        "osmajorrelease": 7,
        "hospital:type": "",
        "cloud:region": "",
        "os": "CentOS",
        "ipv4": ["127.0.0.1", "192.168.56.11"],
        "mem_total": 1819
    },
    "linux-node2.example.com": {
        "osrelease": "7.6.1810",
        "fqdn_ip4": ["192.168.56.12"],
        "serialnumber": "VMware-56 4d 09 af 9d 33 70 99-e9 7b 6d b2 5a 3b 7f 22",
        "nodename": "linux-node2.example.com",
        "kernelrelease": "3.10.0-957.1.3.el7.x86_64",
        "cloud:type": "",
        "num_cpus": 1,
        "saltversion": "2018.3.3",
        "cpu_model": "Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz",
        "virtual": "VMware",
        "cluster:domain": "",
        "cluster:name": "",
        "osmajorrelease": 7,
        "hospital:type": "",
        "cloud:region": "",
        "os": "CentOS",
        "ipv4": ["127.0.0.1", "192.168.56.12"],
        "mem_total": 1819
    }
}]
'''

使用requests模塊獲取基本信息
使用requests模塊獲取基本信息

  3、解決訪問無證書https報錯:requests.exceptions.SSLError: HTTPSConnectionPool

    參考博客:https://blog.csdn.net/qq_31077649/article/details/79013199

    1)安裝相關模塊:

      pip install cryptography
      pip install pyOpenSSL
      pip install certifi

    2)關閉證書驗證(verify=False)

      ret = requests.post(url=url, data=data, json='json', headers=headers, verify=False)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM