Skip to content

Commit

Permalink
Merge pull request #136 from dsoper2/json-patch
Browse files Browse the repository at this point in the history
Fixes #135 to support JSON Patch of existing resources with example p…
  • Loading branch information
dsoper2 authored Sep 9, 2024
2 parents eb8c570 + 3ce9e38 commit 1d4f524
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# cisco.intersight Ansible Collection Changelog

## Version 2.0.17
- Fixes #135 to support JSON Patch of existing resources with example port_policy_json_patch.yml playbook

## Version 2.0.16
- Fixes #133 to add support for Power Policies in Server Profiles

Expand Down
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace: cisco
name: intersight

# The version of the collection. Must be compatible with semantic versioning
version: 2.0.16
version: 2.0.17

# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md
Expand Down
100 changes: 100 additions & 0 deletions playbooks/port_policy_json_patch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
#
# Configure Fabric Port Policies
#
- name: Configure Fabric Port Policies
hosts: localhost
connection: local
gather_facts: false
vars:
# Create an anchor for api_info that can be used throughout the file
api_info: &api_info
# if api_key vars are omitted, INTERSIGHT_API_KEY_ID, INTERSIGHT_API_PRIVATE_KEY,
# and INTERSIGHT_API_URI environment variables used for API key data
api_private_key: "{{ api_private_key | default(omit) }}"
api_key_id: "{{ api_key_id | default(omit) }}"
api_uri: "{{ api_uri | default(omit) }}"
validate_certs: "{{ validate_certs | default(omit) }}"
# Port Policy name
port_name: eth-pc
org_name: dsoper-DevNet
tasks:
# Get the Organization Moid
- name: "Get Organization Moid"
cisco.intersight.intersight_rest_api:
<<: *api_info
resource_path: /organization/Organizations
query_params:
$filter: "Name eq '{{ org_name }}'"
register: org_resp
# Config Port Policy
- name: "Configure Port Policy"
cisco.intersight.intersight_rest_api:
<<: *api_info
state: "{{ state | default('present') }}"
resource_path: /fabric/PortPolicies
query_params:
$filter: "Name eq '{{ port_name }}'"
api_body: {
"Name": "{{ port_name }}",
"DeviceModel": "UCS-FI-6454",
"Organization": {
"Moid": "{{ org_resp.api_response.Moid }}"
}
}
register: port_resp
# Config Uplink Port Channel Roles
- name: "Configure Uplink Port Channel Roles"
cisco.intersight.intersight_rest_api:
<<: *api_info
resource_path: /fabric/UplinkPcRoles
query_params:
$filter: "PortPolicy.Moid eq '{{ port_resp.api_response.Moid }}'"
api_body: {
"AdminSpeed": "Auto",
"PcId": 47,
"PortPolicy": {
"Moid": "{{ port_resp.api_response.Moid }}"
},
"Ports": [
{
"PortId": 47,
"SlotId": 1
}
]
}
when: port_resp.api_response is defined and port_resp.api_response
# JSON Patch for Uplink Port Channel Roles
- name: "JSON Patch Uplink Port Channel Roles"
cisco.intersight.intersight_rest_api:
<<: *api_info
resource_path: /fabric/UplinkPcRoles
query_params:
$filter: "PortPolicy.Moid eq '{{ port_resp.api_response.Moid }}'"
update_method: json-patch
list_body: [
{
"op": "add",
"path": "/AdminSpeed",
"value": "Auto"
},
{
"op": "add",
"path": "/PcId",
"value": 47
},
{
"op": "add",
"path": "/PortPolicy/Moid",
"value": "{{ port_resp.api_response.Moid }}"
},
{
"op": "add",
"path": "/Ports/-",
"value": {
"PortId": 48,
"SlotId": 1
}
}
]
when: port_resp.api_response is defined and port_resp.api_response
11 changes: 10 additions & 1 deletion plugins/module_utils/intersight.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ def __init__(self, module):
self.private_key = self.module.params['api_private_key']
self.digest_algorithm = ''
self.response_list = []
self.update_method = ''

def get_sig_b64encode(self, data):
"""
Expand Down Expand Up @@ -285,6 +286,9 @@ def intersight_call(self, http_method="", resource_path="", query_params=None, b
if (moid is not None and len(moid.encode('utf-8')) != 24):
raise ValueError('Invalid *moid* value!')

if (method != 'PATCH' and self.update_method == 'json-patch'):
raise ValueError('json-patch is only supported with PATCH on existing resource')

# Check for query_params, encode, and concatenate onto URL
if query_params:
query_path = "?" + urlencode(query_params)
Expand Down Expand Up @@ -331,9 +335,13 @@ def intersight_call(self, http_method="", resource_path="", query_params=None, b
auth_header = self.get_auth_header(auth_header, b64_signed_msg)

# Generate the HTTP requests header
if self.update_method == 'json-patch':
content_type = 'application/json-patch+json'
else:
content_type = 'application/json'
request_header = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Content-Type': content_type,
'Host': '{0}'.format(target_host),
'Date': '{0}'.format(cdate),
'Digest': 'SHA-256={0}'.format(b64_body_digest.decode('ascii')),
Expand Down Expand Up @@ -367,6 +375,7 @@ def get_resource(self, resource_path, query_params, return_list=False):
self.result['trace_id'] = response.get('trace_id')

def configure_resource(self, moid, resource_path, body, query_params, update_method=''):
self.update_method = update_method
if not self.module.check_mode:
if moid and update_method != 'post':
# update the resource - user has to specify all the props they want updated
Expand Down
7 changes: 5 additions & 2 deletions plugins/modules/intersight_rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@
description:
- The HTTP method used for update operations.
- Some Intersight resources require POST operations for modifications.
- json-patch is used for partial updates.
- json-patch is only supported for patch operations on existing resources and requires the list_body to be a list of dictionaries.
- See L(The Intersight API Docs, https://intersight.com/apidocs/introduction/methods/) for details on JSON Patch.
type: str
choices: [ patch, post ]
choices: [ patch, post, json-patch ]
default: patch
api_body:
description:
Expand Down Expand Up @@ -145,7 +148,7 @@ def main():
argument_spec.update(
resource_path=dict(type='str', required=True),
query_params=dict(type='dict'),
update_method=dict(type='str', choices=['patch', 'post'], default='patch'),
update_method=dict(type='str', choices=['patch', 'post', 'json-patch'], default='patch'),
api_body=dict(type='dict'),
list_body=dict(type='list', elements='dict'),
return_list=dict(type='bool', default=False),
Expand Down
Binary file added releases/cisco-intersight-2.0.17.tar.gz
Binary file not shown.

0 comments on commit 1d4f524

Please sign in to comment.