Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ansible changes for Image Verification and GPG key installation #380

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/380-sonic-image-verification.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- sonic_image_management - Add support for image GPG Key installation and verification in sonic_image_management module (https://github.com/ansible-collections/dellemc.enterprise_sonic/pull/380).
78 changes: 72 additions & 6 deletions plugins/modules/sonic_image_management.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this PR is still in draft, but please make sure to add version_added to each new attribute

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
short_description: Manage installation of Enterprise SONiC image, software patch and firmware updater
description:
- Manage installation of Enterprise SONiC image, software patch and firmware updater.
author: 'Arun Saravanan Balachandran (@ArunSaravananBalachandran)'
author: 'Arun Saravanan Balachandran (@ArunSaravananBalachandran), Aravind Mani (@aravindmani-1)'

options:
image:
Expand All @@ -35,6 +35,8 @@
- C(set-default) - Set the image specified by I(name) as default boot image.
- C(get-list) - Retrieve list of installed images.
- C(get-status) - Retrieve image installation status.
- C(gpg-key) - Installs the GPG key.
- C(verify) - Verifies the image using gpg and pki methods.
type: str
choices:
- install
Expand All @@ -43,6 +45,8 @@
- set-default
- get-list
- get-status
- gpg-key
- verify
required: true
path:
description:
Expand All @@ -51,9 +55,37 @@
type: str
name:
description:
- When I(command=remove) or I(command=set-default), specifies the name of the image.
- When I(command=remove), name can be specified as C(all) to remove all images which are not current or next.
- When I(command=remove) or I(command=set-default), specifies the name of the image.
- When I(command=remove), name can be specified as C(all) to remove all images which are not current or next.
type: str
keyserver:
version_added: '3.0.0'
description:
- GPG Key server URL
type: str
pubkeyid:
version_added: '3.0.0'
description:
- GPG Key ID to be installed
type: str
signaturefile:
version_added: '3.0.0'
description:
- GPG/PKI file to be verified
type: str
pubkeyfilename:
version_added: '3.0.0'
description:
- Provide the certificate for the signature file
type: str
verifymethod:
version_added: '3.0.0'
description:
- Image verification GPG or PKI method
type: str
choices:
- gpg
- pki
patch:
description:
- Manage installation of software patch.
Expand Down Expand Up @@ -197,7 +229,17 @@ def validate_and_retrieve_params(module, warnings):
module.fail_json(msg="{0} -> name is required when {0} -> command = {1}".format(params['category'], params['command']))
if params.get('path'):
warnings.append("{0} -> path is ignored when {0} -> command = {1}".format(params['category'], params['command']))

elif params['command'] == 'gpg-key':
if not params.get('keyserver') or not params.get('pubkeyid'):
module.fail_json(msg="{0} -> keyserver URL and Key ID are required when {0} -> command = {1}".format(params['category'], params['command']))
elif params['command'] == 'verify':
if params.get('verifymethod') == 'gpg':
if not params.get('name') or not params.get('signaturefile'):
module.fail_json(msg="{0} -> Image name and GPG signature are required when {0} -> command = {1}".format(params['category'], params['command']))
else:
if not params.get('name') or not params.get('signaturefile') or not params.get('pubkeyfilename'):
module.fail_json(
msg="{0} -> Image name, PKI signature and certificate are required when {0} -> command = {1}".format(params['category'], params['command']))
return params


Expand Down Expand Up @@ -225,6 +267,12 @@ def execute_command(module, params, result):
'get-list': {
'path': 'data/openconfig-image-management:image-management',
'response_key': 'openconfig-image-management:image-management'
},
'gpg-key': {
'path': 'operations/openconfig-image-management:image-gpg'
},
'verify': {
'path': 'operations/openconfig-image-management:image-verify'
}
},
'patch': {
Expand Down Expand Up @@ -351,6 +399,16 @@ def execute_command(module, params, result):
payload['openconfig-image-management:input'] = {'image-name': params['path']}
elif (params['command'] == 'remove' and params['name'] != 'all') or params['command'] == 'set-default':
payload['openconfig-image-management:input'] = {'image-name': params['name']}
elif params['command'] == 'gpg-key':
payload['openconfig-image-management:input'] = {"key-server": params['keyserver'], "key-id": params['pubkeyid']}
elif params['command'] == 'verify':
if params['verifymethod'] == 'gpg':
payload['openconfig-image-management:input'] = {
"image-name": params['name'], "verify-method": params['verifymethod'], "sigfilename": params['signaturefile']}
else:
payload['openconfig-image-management:input'] = {
"image-name": params['name'], "verify-method": params['verifymethod'],
"sigfilename": params['signaturefile'], "keyfilename": params['pubkeyfilename']}
elif params['category'] == 'patch':
if params['command'] == 'install':
payload['openconfig-image-management:input'] = {'patch-name': params['path'], 'skip-image-check': ''}
Expand Down Expand Up @@ -388,10 +446,18 @@ def main():
'command': {
'type': 'str',
'required': True,
'choices': ['install', 'cancel', 'remove', 'set-default', 'get-list', 'get-status']
'choices': ['install', 'cancel', 'remove', 'set-default', 'get-list', 'get-status', 'gpg-key', 'verify']
},
'name': {'type': 'str'},
'path': {'type': 'str'}
'path': {'type': 'str'},
'keyserver': {'type': 'str'},
'pubkeyid': {'type': 'str'},
'pubkeyfilename': {'type': 'str'},
'signaturefile': {'type': 'str'},
'verifymethod': {
'type': 'str',
'choices': ['gpg', 'pki']
}
}
},
'patch': {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
- name: Test case - image gpg-key - Installs GPG key
dellemc.enterprise_sonic.sonic_image_management:
image:
command: 'gpg-key'
keyserver: 'hkp://keyserver.ubuntu.com:80'
pubkeyid: 'DC6E36CC7FDA043B'
register: result
ignore_errors: yes

- ansible.builtin.assert:
that:
- result.failed == false
- result.status is defined
- result.status == 'Installed public GPG key successfully'
register: assert_result
ignore_errors: yes

- ansible.builtin.include_tasks: image_management.test.facts.report.yml
vars:
test_case_name: 'image_gpg_key_01'
test_case_input:
image:
command: 'gpg-key'
keyserver: 'hkp://keyserver.ubuntu.com:80'
pubkeyid: 'DC6E36CC7FDA043B'

- name: Test case - image gpg-key - Installs GPG key
dellemc.enterprise_sonic.sonic_image_management:
image:
command: 'gpg-key'
keyserver: 'hkp://keyserver.ubuntu.com:80'
pubkeyid: 'DC6E36CC7FDA043A'
register: result
ignore_errors: yes

- ansible.builtin.assert:
that:
- result.failed == false
- result.status is defined
- result.status == 'Failed to install public GPG key'
register: assert_result
ignore_errors: yes

- ansible.builtin.include_tasks: image_management.test.facts.report.yml
vars:
test_case_name: 'image_gpg_key_02'
test_case_input:
image:
command: 'gpg-key'
keyserver: 'hkp://keyserver.ubuntu.com:80'
pubkeyid: 'DC6E36CC7FDA043A'
119 changes: 119 additions & 0 deletions tests/regression/roles/sonic_image_management/tasks/image_verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
- name: Test case - image verify - Verifies image using GPG-01
dellemc.enterprise_sonic.sonic_image_management:
image:
command: 'verify'
verifymethod: 'gpg'
name: 'home://sonic-verify.bin'
signaturefile: 'home://sign.gpg'
register: result
ignore_errors: yes


- ansible.builtin.assert:
that:
- result.failed == false
- result.status is defined
- result.status == 'GPG validation succeeded.'
register: assert_result
ignore_errors: yes

- ansible.builtin.include_tasks: image_management.test.facts.report.yml
vars:
test_case_name: 'image_verify_gpg_01'
test_case_input:
image:
command: 'verify'
verifymethod: 'gpg'
name: 'home://sonic-verify.bin'
signaturefile: 'home://sign.gpg'

- name: Test case - image verify - Verifies image using GPG-02
dellemc.enterprise_sonic.sonic_image_management:
image:
command: 'verify'
verifymethod: 'gpg'
name: 'home://sonic-verify.bin'
signaturefile: 'home://sign.sig'
register: result
ignore_errors: yes


- ansible.builtin.assert:
that:
- result.failed == false
- result.status is defined
- result.status == 'GPG validation failed.'
register: assert_result
ignore_errors: yes

- ansible.builtin.include_tasks: image_management.test.facts.report.yml
vars:
test_case_name: 'image_verify_gpg_02'
test_case_input:
image:
command: 'verify'
verifymethod: 'gpg'
name: 'home://sonic-verify.bin'
signaturefile: 'home://sign.sig'

- name: Test case - image verify - Verifies image using PKI
dellemc.enterprise_sonic.sonic_image_management:
image:
command: 'verify'
verifymethod: 'pki'
name: 'home://sonic-verify.bin'
signaturefile: 'home://sign.sig'
pubkeyfilename: 'home://DellOS10.cert.pem'
register: result
ignore_errors: yes


- ansible.builtin.assert:
that:
- result.failed == false
- result.status is defined
- result.status == 'PKI validation succeeded.'
register: assert_result
ignore_errors: yes

- ansible.builtin.include_tasks: image_management.test.facts.report.yml
vars:
test_case_name: 'image_verify_pki_01'
test_case_input:
image:
command: 'verify'
verifymethod: 'pki'
name: 'home://sonic-verify.bin'
signaturefile: 'home://sign.sig'
pubkeyfilename: 'home://DellOS10.cert.pem'

- name: Test case - image verify - Verifies image using PKI
dellemc.enterprise_sonic.sonic_image_management:
image:
command: 'verify'
verifymethod: 'pki'
name: 'home://sonic-verify.bin'
signaturefile: 'home://sign.gpg'
pubkeyfilename: 'home://DellOS10.cert.pem'
register: result
ignore_errors: yes

- ansible.builtin.assert:
that:
- result.failed == false
- result.status is defined
- result.status == 'PKI validation failed.'
register: assert_result
ignore_errors: yes

- ansible.builtin.include_tasks: image_management.test.facts.report.yml
vars:
test_case_name: 'image_verify_pki_02'
test_case_input:
image:
command: 'verify'
verifymethod: 'pki'
name: 'home://sonic-verify.bin'
signaturefile: 'home://sign.gpg'
pubkeyfilename: 'home://DellOS10.cert.pem'
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- ansible.builtin.include_tasks: image_set_default.yml
- ansible.builtin.include_tasks: image_get_list.yml
- ansible.builtin.include_tasks: image_get_status.yml
- ansible.builtin.include_tasks: image_gpg.yml
- ansible.builtin.include_tasks: image_verify.yml

- ansible.builtin.include_tasks: patch_install.yml
- ansible.builtin.include_tasks: patch_rollback.yml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,74 @@ image_set_default:
status: 0
status-detail: 'SUCCESS'

image_gpg:
module_args:
image:
command: 'gpg-key'
#name: 'SONiC-OS-x.y.z-Enterprise'
keyserver: 'hkp://keyserver.ubuntu.com:80'
pubkeyid: 'DC6E36CC7FDA043B'
requests:
- path: 'operations/openconfig-image-management:image-gpg'
method: 'post'
data:
openconfig-image-management:input:
key-server: 'hkp://keyserver.ubuntu.com:80'
key-id: 'DC6E36CC7FDA043B'
response:
code: 200
value:
openconfig-image-management:output:
status: 0
status-detail: 'Installed public GPG key successfully'

image_verify_01:
module_args:
image:
command: 'verify'
name: 'home://sonic-verify.bin'
verifymethod: 'gpg'
signaturefile: 'home://sign.gpg'
requests:
- path: 'operations/openconfig-image-management:image-verify'
method: 'post'
data:
openconfig-image-management:input:
image-name: 'home://sonic-verify.bin'
verify-method: 'gpg'
sigfilename: 'home://sign.gpg'
response:
code: 200
value:
openconfig-image-management:output:
status: 0
status-detail: 'GPG validation succeeded.'

image_verify_02:
module_args:
image:
command: 'verify'
name: 'home://sonic-verify.bin'
verifymethod: 'pki'
signaturefile: 'home://sign.sig'
pubkeyfilename: 'home://DellOS10.cert.pem'
requests:
- path: 'operations/openconfig-image-management:image-verify'
method: 'post'
data:
openconfig-image-management:input:
image-name: 'home://sonic-verify.bin'
verify-method: 'pki'
sigfilename: 'home://sign.sig'
keyfilename: 'home://DellOS10.cert.pem'
response:
code: 200
value:
openconfig-image-management:output:
status: 0
status-detail: 'PKI validation succeeded.'


image_get_list:
module_args:
image:
Expand Down
Loading
Loading