Tuesday 6 June 2017

Can Ansible make a REST call

In this article, we will learn how Ansible can make a REST call

Introduction:

RESTful API’s is a platform independent architecture based on representational state transfer (REST) technology and are now a days used to  integrate  different applications. So, if we want to interact with an existing infrastructure we can expose the infrastructure as REST webservice and other applications can use its API to make calls.

Ansible, using URI module, provides way to make the REST calls. The URI module allows us to send XML or JSON payload and get the necessary details. In this article we will see how we can use the URI module and make the REST calls. 



REST call - 

In the below example, we are using the Nexus artifactory to connect to REST Webservice running on 8081 Port. The URL are specified in the vars/main.yml file.

The idea here is to make a Get REST Call using the Ansible URI module to fetch the necessary details. Get call doesn't change anything on REST Server.



- name: Make a Call


  uri:

   url: "{{nexus_url}}/repositories"

   method: GET

   user: user1

   password: user123

   force_basic_auth: yes

   return_content: yes


In the above code, we are making the Get REST call to the “nexus_url/respositories” URL by passing them the user name and password along with the method as “Get” and the return_content.  We can use the Ansible debug to check the obtained response.



POST call – 

Making a Post call needs a little extra details. Now for making a post call we need the JSON data. We have option to create a file with JSON data and pass that to the file or we can include the JSON data at the same POST call. Lets create a JSON file first as below:


{


    "data": {

        "repoType": "proxy",

        "id": "somerepo1",

        "name": "Some Repo Name1",

        "browseable": true,

        "indexable": true,

        "notFoundCacheTTL": 1440,

        "artifactMaxAge": -1,

        "metadataMaxAge": 1440,

        "itemMaxAge": 1440,

        "repoPolicy": "RELEASE",

        "provider": "maven2",

        "providerRole": "org.sonatype.nexus.proxy.repository.Repository",

        "downloadRemoteIndexes": true,

        "autoBlockActive": true,

        "fileTypeValidation": true,

        "exposed": true,

        "checksumPolicy": "WARN",

        "remoteStorage": {

            "remoteStorageUrl": "http://testserver.com:8081/local",

            "authentication": null,

            "connectionSettings": null

        }

    }

}

Next, we will save this file as proxy.json and move the file to the files location. Now we can use the proxy.json using the lookup in ansible as follows:



- name: Make a Proxy Repository


  uri:

    url: "{{ nexus_url }}/repositories"

    method: POST

    body: "{{ lookup('file','proxy.json') }}"

    user: user1

    password: user123

    force_basic_auth: yes

    body_format: json

    HEADER_Content-Type: application/json

    HEADER_Accept: application/json,version=2

    return_content: yes

    status_code: 201



Explanation:

In the above code,we passed the JSON file an argument to the  Ansible lookup. Besides this we passed the user name , password and most importantly the body_format , Header fields etc. We also need to pass the return code of the REST call so that Ansible will compare the return status code with the status code that we defined. In the above example we passed the status code as 201. In this example Ansible will check the rest call status code and passed status code to check if that is success or not. Even though the rest call is success if the status codes are not same Ansible will throw an error.

If we want to pass the JSON format in the body itself without using the file, we can use it this way:



- name: Make a Hosted Repository


  uri:

    url: "{{nexus_url}}/{{ nexus_endpoint }}/{{ nexus_repositories_service }}"

    method: POST

    body: >

     {

      data: {

        "repoType": "{{ hosted_repo_data.repoType }}",

        "id": "{{ repoId }}",

        "name": "{{ repoName }}",

        "provider": "{{ repoProvider}}",

        "browseable": {{ hosted_repo_data.browseable }},

        "repoPolicy": {{ hosted_repo_data.repoPolicy }},

        "providerRole": {{ hosted_repo_data.providerRole }}

           }

     }

    user: "{{ nexus_admin }}"

    password: "{{ nexus_admin_password }}"

    force_basic_auth: yes

    body_format: json

    HEADER_Content-Type: application/json

    HEADER_Accept: application/json,version=2

    return_content: yes

    status_code: 201

The body can be added directory to the Body method in the Ansible JSON call.


Thats all for different ways to make REST call via Ansible. If you have a query please mention in comments section and don't forget to subscribe to latest articles -> Subscribe to Tech693