Membuat modul Ansible pertama Anda

Di blog ini, saya akan menunjukkan cara membuat modul Ansible pertama Anda.













Tentu saja, ada dokumentasi yang tersedia di Ansible.com, tetapi sulit untuk mengetahuinya. Memulai modul pertama saya berdasarkan pengantar ini diberikan kepada saya dengan susah payah. Itulah mengapa saya membuat panduan ini. Pengguna baru berhak mendapatkan titik awal yang lebih baik.







Blog ini membahas topik-topik berikut:







  • Apa itu modul yang mungkin
  • Menyiapkan lingkungan build kami
  • API Server
  • Pengembangan modul itu sendiri


Apa itu modul yang mungkin



Jika Anda terbiasa dengan Ansible, Anda mungkin tahu bahwa setiap tugas yang Anda lakukan di Ansible adalah modul Ansible. Jika tidak, sekarang Anda mengetahuinya.







, Ansible:







- name:    python-requests
  yum:
    name: python-requests
    state: latest
      
      





Ansible yum



.







. .







- , . , , - Ansible Galaxy, Ansible.







Ansible, API . , , , , , , .







Ansible, .









VSCode Ansible. - , , , -.







, Ansible API, .







API . — . .







, VSCode.







git clone https://gitlab.com/techforce1/ansible-module.git -b blog-setup
      
      





, blog-setup!







3 (.devcontainer



, ansible



, api-server



). API. cmd



, api-server



docker build -t api-server



( ).







. docker run -it -d -p 5000: 5000 api-server



. API-. http://localhost:5000, -.







, , Ansible, — VSCode. .devcontainer. VSCode , devcontainer



.







devcontainer



VSCode devcontainer



.







, , devcontainer



. Ansible devcontainer



. , Ansible , VSCode.







VSCode , , Reopen in container



.













.







API



API API, . * http://localhost:5000/. - , . API, http://localhost:5000/API/users.







, « », , API . , http://localhost:5000/API/get-token. . admin



initial_password



.







, , API







API , - , , - .







API curl



. curl, :







$ curl -u admin:initial_password http:/172.17.0.1:5000/API/get-token
{
  "duration": 600, 
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjA1NzE0NjI5Ljk1NzU4ODd9.8yDkOzN0umO2hN_D84KLV4Q4OuWzQoNf8puXWku9F14"
}
      
      





URL . , VSCode. , , IP- , API. .







, API, curl



:







$ curl -H 'Accept: application/json' -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjA1NzE0NjI5Ljk1NzU4ODd9.8yDkOzN0umO2hN_D84KLV4Q4OuWzQoNf8puXWku9F14" http:/172.17.0.1:5000/API/users
{
  "Users": [
    {
      "admin": true, 
      "created": "Wed, 18 Nov 2020 14:41:31 GMT", 
      "email": "admin@api.local", 
      "id": 1, 
      "username": "admin"
    }
  ]
}
      
      





, API, GET



POST



:







{
  "Users": [
    {
      "username": "test",
      "email": "test@api.local", 
      "password": "password",
      "admin": true
    }
  ]
}
      
      





Ansible



. ansible/tasks/main.yml



. :







name: Add test user to API
our_api_module:
  name: test1
  state: present
  email: test1@test.local
  admin: False
      
      





our_api_module



, 4 . . , Ansible.







. , , playbook. , Ansible , .







. 44, , , Ansible . arguments_spec



, playbook. false. , Ansible.







def main():
    module = AnsibleModule(
        argument_spec=dict(
            state=dict(type='str', default='present',
                       choices=['absent', 'present']),
            name=dict(type='str', required=True),
            email=dict(type='str', required=True),
            admin=dict(type='bool', default=False),
            base_url=dict(requred=False, default=None),
            username=dict(requred=False, default=None),
            password=dict(requred=False, default=None, no_log=True),
        ),
        supports_check_mode=False,
    )
      
      





59 ApiModule



, , 23. init. API. , , getToken



37.







urls



Ansible 3 .







def getToken(self):
    url = "{baseUrl}/API/get-token".format(baseUrl=self.baseUrl)
    response = open_url(url, method="GET", url_username=self.username, url_password=self.password, validate_certs=self.verifySsl)
    return json.loads(response.read())['token']
      
      





. , . 69. , . 2 : , (state). , if



, :







if api.state == 'absent':
    if api.user_exist(api.name):
       # do something to delete user
elif api.state == 'present':
    if not api.user_exist(api.name):
       # do something to add user
      
      





. user_exist. ApiModule



:







def user_exist(self, name):
    url = "{baseUrl}/API/users".format(baseUrl=self.baseUrl)
    headers = {
        'Accept': "application/json",
        "Authorization": "Bearer {}" . format(self.token),
    }
    response = open_url(url, method="GET", headers=headers, validate_certs=self.verifySsl)
    results = json.loads(response.read())
    for user in results['Users']:
        if name == user['username']:
            return True
    return False
      
      





, , , . api endpoint /API/users , . True, False.







, , .







:







def user_add(self):
        url = "{baseUrl}/API/users".format(baseUrl=self.baseUrl)
        headers = {
            'Accept': "application/json",
            'Content-Type': "application/json",
            "Authorization": "Bearer {}" . format(self.token),
        }
        data = {
            'username': self.name,
            'email': self.email,
            'admin': self.admin,
            'password': self.password
        }
        json_data = json.dumps(data, ensure_ascii=False)
        try:
            open_url(url, method="POST", headers=headers, data=json_data, validate_certs=self.verifySsl)
            return True
        except:
            return False
      
      





. user_add . : HTTP



POST



DELETE



, , URL-.

, URL- :







url = "{baseUrl}/API/users/{username}".format(baseUrl=self.baseUrl, username=self.name)
      
      





if.







, playbook (tasks/main.yml



) :







- name: Add test2 user to API
  our_api_module:
    name: test2
    state: present
    email: test2@test.local
    admin: False
    password: "test2test2"

- name: Delete test1 user to API
  our_api_module:
    name: test1
    state: absent
    email: test1@test.local
    admin: False
    password: "test3test3"
      
      





playbook, , 2 , 1 , .









Selamat! Anda sekarang memiliki modul Ansible fungsional. Sudahkah Anda mencoba menambahkan fitur perubahan pengguna? Pertimbangkan juga untuk menambahkan penanganan kesalahan ke modul ini seolah-olah Anda melakukannya dalam modul nyata untuk menangani kesalahan dan mengembalikannya dengan benar ke Ansible.







Tidak terlalu sulit, bukan? Ini tidak benar. Kode Python sederhana sangat penting.

Jika Anda ingin melihat hasil akhir lengkap, lihat di blog hasil cabang.














All Articles