Change Control

Change Control Resource APIs are supported from CVP 2021.2.0 or newer and in CloudVision-as-a-Service.

jq can be used to easily format and parse the outputs.

changeControl.v1

A change can be only be in unapproved state if it was approved initially. Change Controls which have never been approved will have the status of Pending Approval

Get the approval state for a specific change control

curl -sS -kX GET --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ApproveConfig?key.id=-WIh3Xnwu'

Output:

{"value":{"key":{"id":"-WIh3Xnwu"}, "approve":{"value":true}, "version":"2021-12-03T10:41:40.810064204Z"}, "time":"2021-12-03T10:41:44.109088624Z"}

Changes that were never approved will have a nil state and the following result will be returned:

{"code":5, "message":"resource not found"}

The state of a change that was unapproved will result in the following:

{"value":{"key":{"id":"gKCZL1eNG"}, "approve":{"value":false, "notes":"Unapproved explicitly by user"}, "version":"2021-12-08T13:18:16.436235494Z"}, "time":"2021-12-13T18:05:08.243031760Z"}

Get the approval state for all approved/unapproved changes

curl -sS -kX GET --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ApproveConfig/all'

Output:

{"result":{"value":{"key":{"id":"-WIh3Xnwu"},"approve":{"value":true},"version":"2021-12-03T10:41:40.810064204Z"},"time":"2021-12-03T10:41:44.109088624Z","type":"INITIAL"}}
{"result":{"value":{"key":{"id":"-5UxLHCBk"},"approve":{"value":true},"version":"2021-12-03T10:53:58.819000425Z"},"time":"2021-12-03T10:54:05.099957401Z","type":"INITIAL"}}
{"result":{"value":{"key":{"id":"-gKtnAX0s"},"approve":{"value":true},"version":"2021-08-19T18:27:25.312165529Z"},"time":"2021-08-19T18:27:28.961559476Z","type":"INITIAL"}}
{"result":{"value":{"key":{"id":"Dpum-Owhq"},"approve":{"value":true},"version":"2021-08-02T09:47:47.324298592Z"},"time":"2021-08-02T09:47:49.603355580Z","type":"INITIAL"}}
{"result":{"value":{"key":{"id":"1ZgkJ.Wed"},"approve":{"value":true},"version":"2021-11-29T20:42:25.298103662Z"},"time":"2021-11-29T20:42:41.187649168Z","type":"INITIAL"}}

Approve a change

First we need to get the change control state for the specified key and extract the value of time from the change dictionary:

curl -sS -kX GET --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ChangeControl?key.id=rxwA-N65u'

Output:

{"value":{"key":{"id":"rxwA-N65u"}, "change":{"name":"Change 20211213_183228", "rootStageId":"c2uIKIkq0c", "stages":{"values":{"c2uIKIkq0c":{"name":"Change 20211213_183228 Root", "rows":{"values":[{"values":["gaKs4SdpMj"]}]}}, "gaKs4SdpMj":{"name":"Update Config", "action":{"name":"task", "timeout":3000, "args":{"values":{"TaskID":"542"}}}}}}, "notes":"", "time":"2021-12-13T18:32:31.830585136Z", "user":"cvpadmin"}}, "time":"2021-12-13T18:32:31.830585136Z"}

Then use the time value in the version value in the ApproveConfig POST message as below:

curl -sS -kX POST --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ApproveConfig' -H 'Content-Type: application/json' \
-d '{"key":{"id":"rxwA-N65u"}, "approve": {"value": true, "notes": "REST API test"}, "version": "2021-12-13T18:32:31.830585136Z"}'

Output:

{"value":{"key":{"id":"rxwA-N65u"}, "approve":{"value":true, "notes":"REST API test"}, "version":"2021-12-13T18:32:31.830585136Z"}, "time":"2021-12-13T19:00:11.500491001Z"}

Create a change control

curl -sS -kX POST --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ChangeControlConfig' -d "`cat task_data.json`"

where task_data.json looks like below:

cat task_data.json | jq

Output:

{
  "key": {
    "id": "5821c7c1-e276-4387-b60a"
  },
  "change": {
    "name": "Change_20211222_191032",
    "rootStageId": "root",
    "stages": {
      "values": {
        "root": {
          "name": "root",
          "rows": {
            "values": [
              {
                "values": [
                  "stage0",
                  "stage1",
                  "stage2",
                  "stage3"
                ]
              }
            ]
          }
        },
        "stage0": {
          "name": "stage0",
          "action": {
            "name": "task",
            "timeout": 3000,
            "args": {
              "values": {
                "TaskID": "1245"
              }
            }
          }
        },
        "stage1": {
          "name": "stage1",
          "action": {
            "name": "task",
            "timeout": 3000,
            "args": {
              "values": {
                "TaskID": "1246"
              }
            }
          }
        },
        "stage2": {
          "name": "stage2",
          "action": {
            "name": "task",
            "timeout": 3000,
            "args": {
              "values": {
                "TaskID": "1247"
              }
            }
          }
        },
        "stage3": {
          "name": "stage3",
          "action": {
            "name": "task",
            "timeout": 3000,
            "args": {
              "values": {
                "TaskID": "1248"
              }
            }
          }
        }
      }
    },
    "notes": "curl_cc_test"
  }
}

or without jq formatting:

{"key": {"id": "5821c7c1-e276-4387-b60a"}, "change": {"name": "Change_20211222_191032", "rootStageId": "root", "stages": {"values": {"root": {"name": "root", "rows": {"values": [{"values": ["stage0", "stage1", "stage2", "stage3"]}]}}, "stage0": {"name": "stage0", "action": {"name": "task", "timeout": 3000, "args": {"values": {"TaskID": "1245"}}}}, "stage1": {"name": "stage1", "action": {"name": "task", "timeout": 3000, "args": {"values": {"TaskID": "1246"}}}}, "stage2": {"name": "stage2", "action": {"name": "task", "timeout": 3000, "args": {"values": {"TaskID": "1247"}}}}, "stage3": {"name": "stage3", "action": {"name": "task", "timeout": 3000, "args": {"values": {"TaskID": "1248"}}}}}}, "notes": "curl_cc_test"}}

Delete a change control

Pending Change controls can be deleted as below:

curl -sS -kX DELETE --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ChangeControlConfig?key.id=wvisXUy5N'

Output:

{"key":{"id":"wvisXUy5N"}, "time":"2021-12-14T20:01:42.058348061Z"}

Start a change control

curl -sS -kX POST --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ChangeControlConfig' -d '{"key":{"id":"VhkkzxK4U"},"start":{"value":true,"notes":"Starting change via REST call"}}'

Output:

{"value":{"key":{"id":"VhkkzxK4U"}, "start":{"value":true, "notes":"starting change via curl"}}, "time":"2021-12-14T21:02:18.940285772Z"}

Stop a change control

curl -sS -kX POST --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ChangeControlConfig' -d '{"key":{"id":"VhkkzxK4U"},"start":{"value":false,"notes":"Stopping change via REST call"}}'

Output:

{"value":{"key":{"id":"VhkkzxK4U"}, "start":{"value":false, "notes":"stopping change via curl"}}, "time":"2021-12-14T21:02:21.830306071Z"}

Schedule a change control

Change control scheduling using Resource APIs is only supported in 2022.1.0 or newer.

The below example shows how to schedule a Change Control at 2:07 AM on 2021-12-23:

curl -sS -kX POST --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ChangeControlConfig' -d '{"key":{"id":"5821c7c1-e276-4387-b60a"},"schedule":{"value":"2021-12-23T02:07:00.0Z","notes":"CC schedule via curl"}}'

Output:

{"value":{"key":{"id":"5821c7c1-e276-4387-b60a"}, "schedule":{"value":"2021-12-23T01:49:00Z", "notes":"CC schedule via curl"}}, "time":"2021-12-23T01:47:32.521200888Z"}

A scheduled change will be only successfully executed if the change was approved.

Fetching the state of a scheduled change which wasn’t approved before execution time will result in the following error:

"error":"Reschedule required: not approved at schedule time"

e.g.:

curl -sS -kX GET --header 'Accept: application/json' -b access_token=`cat token.tok` 'https://192.0.2.100/api/resources/changecontrol/v1/ChangeControl?key.id=5821c7c1-e276-4387-b60a'

{"value":{"key":{"id":"5821c7c1-e276-4387-b60a"}, "change":{"name":"Change_20211222_191032", "rootStageId":"root", "stages":{"values":{"root":{"name":"root", "rows":{"values":[{"values":["stage0", "stage1", "stage2", "stage3"]}]}}, "stage0":{"name":"stage0", "action":{"name":"task", "timeout":3000, "args":{"values":{"TaskID":"1245"}}}}, "stage1":{"name":"stage1", "action":{"name":"task", "timeout":3000, "args":{"values":{"TaskID":"1246"}}}}, "stage2":{"name":"stage2", "action":{"name":"task", "timeout":3000, "args":{"values":{"TaskID":"1247"}}}}, "stage3":{"name":"stage3", "action":{"name":"task", "timeout":3000, "args":{"values":{"TaskID":"1248"}}}}}}, "notes":"curl_cc_test", "time":"2021-12-22T19:10:35.472979755Z", "user":"resourceapis"}, "error":"Reschedule required: not approved at schedule time", "schedule":{"notes":"Reschedule required: not approved at schedule time", "time":"2021-12-23T01:49:00.004927172Z"}}, "time":"2021-12-23T01:49:00.004927172Z"}