ansible的restful api接口
先阅读以下链接
https://iswbm.com/192.html
1.python有一个ansible-api的包,可以提供restful api接口,通过如下命令可以查询
pip search ansible-api
#注意pip search可能在某些版本不能使用了,需要安装新的命令#pip install pip_search
#pip_search ansible-api
2.ansible-api依赖python>=3.7
安装参考:https://www.cnblogs.com/pipiisacat/p/16247355.html
注意openssl需要先升级到新版本(可以先尝试yum命令升级),然后再编译安装python,参考:https://blog.csdn.net/bo_self_effacing/article/details/123628224。
安装过程中如果有依赖包找不到的情况,需要先安装依赖包,再重新编译安装。
3.安装ansible-api
安装参考:https://github.com/lfbear/ansible-api/blob/master/README.md
4.启动ansible-api的时候会有报错,不知道是不是和python的版本有关系
#报错1,参考https://blog.csdn.net/Moelimoe/article/details/127913089 Sanic app name 'ansible-api' not found. App instantiation must occur outside if __name__ == '__main__' block or by using an AppLoader. See https://sanic.dev/en/guide/deployment/app-loader.html for more details. Traceback (most recent call last): File "/usr/local/python3.8/lib/python3.8/site-packages/sanic/app.py", line 1499, in get_app return cls._app_registry[name] KeyError: 'ansible-api' #报错2 Traceback (most recent call last): File "./ansible-api", line 53, in <module> register_route() File "./ansible-api", line 51, in register_route Tool.LOGGER.debug("Config at start: %s" % json.dumps(config)) AttributeError: 'NoneType' object has no attribute 'debug'
这些报错基本就是初始化的顺序不对,修改ansible-api文件如下即可
#!/usr/local/python3.8/bin/python3.8 # coding: utf-8 # A restful HTTP API for ansible # Base on ansible-runner and sanic # Github <https://github.com/lfbear/ansible-api> # Author: lfbear from __future__ import (absolute_import, division, print_function) __metaclass__ = type import sys import os import getopt from ansible_api.tool import Tool from ansible_api.config import Config from ansible_api.server import Server from ansible_api import __version__ import json from sanic import Sanic from sanic.response import text from ansible_api import controller app = Sanic('ansible-api') def init_log(): try: opts, args = getopt.getopt(sys.argv[1:], 'c:dV') except getopt.GetoptError: print( '%s -c [Configfile, Optional] -d [Daemon Mode, Optional]' % sys.argv[0]) sys.exit(1) daemon_mode = False for opt in opts: if opt[0] == '-V': print("Ansible API - Version %s" % __version__) exit(0) if opt[0] == '-c' and os.path.isfile(opt[1]): Config.cfg_path = opt[1] print('Info: Load config file from %s' % Config.cfg_path) if opt[0] == '-d': daemon_mode = True print('\033[1;32mAnsible API is running at', end=' ') if daemon_mode: log_path = Config.get('log_path') print('Daemon Mode') else: log_path = None print('Debug Mode') print('\033[0m') Tool.init_logger(log_path) return daemon_mode; def register_route(): app.add_route(controller.Main.as_view(), '/') app.add_route(controller.NonBlockTest.as_view(), '/test') app.add_route(controller.Command.as_view(), '/command') app.add_route(controller.Playbook.as_view(), '/playbook') app.add_route(controller.FileList.as_view(), '/filelist') app.add_route(controller.FileReadWrite.as_view(), '/fileitem') app.add_route(controller.FileExist.as_view(), '/filexist') app.add_route(controller.ParseVarsFromFile.as_view(), '/parsevars') app.add_websocket_route(controller.Message.websocket, '/message', subprotocols=Config.get('ws_sub')) app.config.update(dict(RESPONSE_TIMEOUT=Config.get('timeout'))) # timeout for waiting response @app.middleware('request') async def ip_ban(request): if len(Config.get('allow_ip')) and request.ip not in Config.get('allow_ip'): return text('Your IP (%s) is not allowed!' % request.ip, status=403) # print config contents config = Config().__dict__ config['sign_key'] = len(config['sign_key']) * '*' # mask signature key Tool.LOGGER.debug("Config at start: %s" % json.dumps(config)) daemon_mode=init_log(); register_route() if __name__ == "__main__": #try: # opts, args = getopt.getopt(sys.argv[1:], 'c:dV') #except getopt.GetoptError: # print( # '%s -c [Configfile, Optional] -d [Daemon Mode, Optional]' % sys.argv[0]) # sys.exit(1) #daemon_mode = False #for opt in opts: # if opt[0] == '-V': # print("Ansible API - Version %s" % __version__) # exit(0) # if opt[0] == '-c' and os.path.isfile(opt[1]): # Config.cfg_path = opt[1] # print('Info: Load config file from %s' % Config.cfg_path) # if opt[0] == '-d': # daemon_mode = True #print('\033[1;32mAnsible API is running at', end=' ') #if daemon_mode: # log_path = Config.get('log_path') # print('Daemon Mode') #else: # log_path = None # print('Debug Mode') #print('\033[0m') #Tool.init_logger(log_path) Tool.LOGGER.info( ' '.join(['Ansible API', 'Start...', '(', 'PID =', str(os.getpid()), ')'])) try: #Server(daemon_mode) app.run(host=Config.get('host'), port=Config.get('port'), workers=Config.get('workers'), debug=not daemon_mode) except Exception as e: Tool.LOGGER.exception(e)
5.api.cfg文件
# ============================================== # Config file for Ansible-Api # # A restful HTTP API for ansible # I am not a part of ansible official code # # https://github.com/lfbear/ansible-api # ============================================== ## # Base configuration part # [default] #listen host host = 127.0.0.1 #注意这个地址,改为0.0.0.0可以所有主机访问 #listen port port = 8765 #signature string for api call sign_key = YOUR_SIGNATURE_KEY_HERE #注意这个key,请求时的签名需要用到 #signature encryption method, md5 or sha256. sha256 suggested sign_mode = sha256 #两种不同的签名方式 #log path if using daemon mode log_path = /var/log/ansible-api.log #worker number (default: 1) workers = 1 #response of a task will be timeout (sec, default: 3600 [1 hour], task will NOT break off after timeout) timeout = 3600 #websocket subprotocols ws_sub = #ip white list (multiple separated by space, leave a blank for all allowed) allow_ip = ## # the path part for playbooks and scripts # [directory] #your playbook path (file *.yml in this dir will be worked) playbook = #your script path (file *.sh in this dir will be worked) script =
6.启动后就可以通过restful api接口去操作ansible了
7.加密方式
加密的原文拼接方式请参考:https://github.com/lfbear/ansible-api/wiki/http-api-usage
简单的字符串拼接就行
md5:
echo -n 'xxxxxxxxxxxxxxxx'|md5sum |cut -d ' ' -f1
sha256:
echo -n 'xxxxxxxxxxxxxxx'|sha256sum |cut -d ' ' -f1