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

Merged
merged 18 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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).
73 changes: 67 additions & 6 deletions plugins/modules/sonic_image_management.py
aravindmani-1 marked this conversation as resolved.
Show resolved Hide resolved
aravindmani-1 marked this conversation as resolved.
Show resolved Hide resolved
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.
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
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,32 @@
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.
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
- When I(command=remove), name can be specified as C(all) to remove all images which are not current or next.
type: str
keyserver:
description:
- GPG Key server URL
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
type: str
pubkeyid:
description:
- GPG Key ID to be installed
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
type: str
signaturefile:
description:
- GPG/PKI file to be verified
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
type: str
pubkeyfilename:
description:
- Provide the certificate for the signature file
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
type: str
verifymethod:
description:
- Image verification GPG or PKI method
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
type: str
choices:
- gpg
- pki
patch:
description:
- Manage installation of software patch.
Expand Down Expand Up @@ -197,7 +224,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':
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
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
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved


Expand Down Expand Up @@ -225,6 +262,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 +394,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']}
ArunSaravananBalachandran marked this conversation as resolved.
Show resolved Hide resolved
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 +441,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