根据业务需要,需要自己写一些定制化ansible模块,网上这方面的资料挺少的。下面是一个操作rancher的模块
ANSIBLE_METADATA={
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = '''
---
module: rancher
short_description: .
version_added: "2.4"
description:
- ""
options:
type:
description:
- project workspace
required: true
json:
description:
- The variable WORKSPACE passed by Jenkins
required: true
author:
- Shuaibo (@shuaibo)
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.errors import AnsibleRuntimeError
import os, requests, json, time
result = dict(
changed=False,
version='',
log=""
)
# 操作service函数
def service_opt(spacename, serivce, operation, json_data):
global result
base_url = "{0}{1}/workloads".format(os.getenv("RANCHER_URL", ""), os.getenv("RANCHER_PROJECT_ID", ""))
headers = {
'accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + os.getenv("RANCHER_TOKEN", "")
}
url = base_url + '/deployment:' + spacename + ':' + serivce
status_url = '{0}{1}/pods?sort=state&workloadId=deployment:'
if operation == 'delete':
response = requests.get(url, headers=headers, verify=False)
r = json.loads(response.text)
result['log'] += "开始删除:%s\n" % response.text
# 检测是否删除成功
for i in range(3):
time.sleep(30)
response = service_opt(spacename, serivce, 'query', json_data)
result['log'] += "检查第%s次删除:%s\n" % (i + 1, response.text)
if response['baseType'] == "error" and response['code'] == "NotFound" and response['status'] == 404:
result['log'] += "检查第%s次删除:%s\n" % (i + 1, response.text)
break
elif operation == 'query':
response = requests.get(url, headers=headers, verify=False)
r = json.loads(response.text)
for i in range(30):
time.sleep(3)
elif operation == "namespace":
# 判断是否存在命名空间,不存在就创建
namesapce_url = os.getenv("RANCHER_BASE_URL") + 'v3/cluster/%s/namespace' % os.getenv("RANCHER_CLUSTER_ID")
response = requests.get(namesapce_url + '/' + os.getenv("RANCHER_NAMESPACEID"), headers=headers, verify=False)
r = json.loads(response.text)
if r.get('status') == 404:
result['log'] = "命名空间不存在,创建命名空间"
post_json = {"type": "namespace", "name": os.getenv("RANCHER_NAMESPACEID"),
"projectId": os.getenv("RANCHER_PROJECT_ID")}
requests.post(namesapce_url, data=json.dumps(post_json), headers=headers, verify=False)
else:
result['log'] = "命名空间已存在,无操作"
elif operation == 'create':
response = requests.post(base_url[:-1], data=json.dumps(json_data), headers=headers, verify=False)
result['log'] += "开始创建:%s\n" % response.text
r = json.loads(response.text)
if r.get('status') is not None:
raise AnsibleRuntimeError("创建服务出错:\tURL:%s\t状态码:%s\t错误信息:%s" % (base_url[:-1], r['status'], response.text))
for i in range(30):
time.sleep(3)
query_response = requests.get(url, headers=headers, verify=False)
qr = json.loads(query_response.text)
if qr.get('deploymentStatus') is None:
raise AnsibleRuntimeError("创建服务出错:\t状态码:%s\t错误信息:%s" % (qr['status'], query_response.text))
if qr['deploymentStatus']['availableReplicas'] == json_data['scale']:
break
result['log'] += "第%s次查询状态:%s\n" % (i + 1, query_response.text)
elif operation == 'update':
response = requests.put(url, data=json_data, headers=headers, verify=False)
r = response.text
elif operation == 'pod_status':
url = status_url + spacename + ':' + serivce
response = requests.get(url, headers=headers, verify=False)
r = response.text
else:
rtn = '{"message": "arg:[%s] NOTFOUND", "status": 122, "code": "arg NOTFOUND", "type": "arg error"}' \
% operation
r = json.loads(rtn)
try:
return json.loads(r)
except:
return r
def run_module(module):
global result
json_data = {}
with open(module.params['json']) as f:
json_content = json.load(f)
pts_service_name = json_content['name']
pts_spacename = json_content['namespaceId']
pts_scale = json_content['scale']
service_opt(pts_spacename, pts_service_name, module.params['type'], json_content)
module.exit_json(**result)
def main():
module_args = dict(
type=dict(type='str', required=True),
json=dict(type='str', required=False),
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)
if module.check_mode:
module.exit_json(**result)
run_module(module)
if __name__ == '__main__':
main()
写好之后随便找一个路径放进去。定义一个全局的环境变量
export ANSIBLE_LIBRARY="写好的py文件所在目录"
然后就可以用了