-
Notifications
You must be signed in to change notification settings - Fork 740
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
Macsec profile deploy on peer VM's and DUT for macsec topo pipeline. #16048
base: master
Are you sure you want to change the base?
Changes from all commits
1e567c8
a09e9a2
177d69b
0fa4cd4
0525872
3e903e1
9c59e85
a99c8d8
f2bc4ef
a864aa7
48a6afe
e716584
290d761
5ffa399
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
|
||
|
||
import copy | ||
import jinja2 | ||
import json | ||
|
||
from ansible.module_utils.basic import AnsibleModule | ||
|
@@ -25,15 +26,22 @@ | |
TEMP_DHCP_SERVER_CONFIG_PATH = "/tmp/dhcp_server.json" | ||
TEMP_SMARTSWITCH_CONFIG_PATH = "/tmp/smartswitch.json" | ||
DUMMY_QUOTA = "dummy_single_quota" | ||
MACSEC_PROFILE_PATH = '/tmp/profile.json' | ||
GOLDEN_CONFIG_TEMPLATE = 'golden_config_db_t2.j2' | ||
GOLDEN_CONFIG_TEMPLATE_PATH = '/tmp/golden_config_db_t2.j2' | ||
|
||
|
||
class GenerateGoldenConfigDBModule(object): | ||
def __init__(self): | ||
self.module = AnsibleModule(argument_spec=dict(topo_name=dict(required=True, type='str'), | ||
port_index_map=dict(require=False, type='dict', default=None)), | ||
port_index_map=dict(require=False, type='dict', default=None), | ||
macsec_profile=dict(require=False, type='str', default=None), | ||
num_asics=dict(require=False, type='int', default=1)), | ||
supports_check_mode=True) | ||
self.topo_name = self.module.params['topo_name'] | ||
self.port_index_map = self.module.params['port_index_map'] | ||
self.macsec_profile = self.module.params['macsec_profile'] | ||
self.num_asics = self.module.params['num_asics'] | ||
|
||
def generate_mgfx_golden_config_db(self): | ||
rc, out, err = self.module.run_command("sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --print-data") | ||
|
@@ -115,18 +123,42 @@ def generate_smartswitch_golden_config_db(self): | |
gold_config_db.update(smartswitch_config_obj) | ||
return json.dumps(gold_config_db, indent=4) | ||
|
||
def generate_t2_golden_config_db(self): | ||
with open(MACSEC_PROFILE_PATH) as f: | ||
macsec_profiles = json.load(f) | ||
for k, v in list(macsec_profiles.items()): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you avoid iterating by just grabbing the key directly? eg: Also, should we explicitly error out/fail here if there is not a matching profile in the json? |
||
if k == self.macsec_profile: | ||
profile = v | ||
# Update the macsec profile name in the profile context | ||
profile['macsec_profile'] = k | ||
break | ||
|
||
# Update the profile context with the asic count | ||
profile['asic_cnt'] = self.num_asics | ||
|
||
# Render the template using the profile | ||
j2_env = jinja2.Environment(loader=jinja2.FileSystemLoader('/tmp')) | ||
j2_template = j2_env.get_template(GOLDEN_CONFIG_TEMPLATE) | ||
rendered_json = j2_template.render(profile) | ||
|
||
return rendered_json | ||
|
||
def generate(self): | ||
if self.topo_name == "mx" or "m0" in self.topo_name: | ||
config = self.generate_mgfx_golden_config_db() | ||
self.module.run_command("sudo rm -f {}".format(TEMP_DHCP_SERVER_CONFIG_PATH)) | ||
elif self.topo_name == "t1-28-lag": | ||
config = self.generate_smartswitch_golden_config_db() | ||
self.module.run_command("sudo rm -f {}".format(TEMP_SMARTSWITCH_CONFIG_PATH)) | ||
elif "t2" in self.topo_name: | ||
config = self.generate_t2_golden_config_db() | ||
self.module.run_command("sudo rm -f {}".format(MACSEC_PROFILE_PATH)) | ||
self.module.run_command("sudo rm -f {}".format(GOLDEN_CONFIG_TEMPLATE_PATH)) | ||
else: | ||
config = "{}" | ||
|
||
with open(GOLDEN_CONFIG_DB_PATH, "w") as temp_file: | ||
temp_file.write(config) | ||
self.module.run_command("sudo rm -f {}".format(TEMP_DHCP_SERVER_CONFIG_PATH)) | ||
self.module.run_command("sudo rm -f {}".format(TEMP_SMARTSWITCH_CONFIG_PATH)) | ||
self.module.exit_json(change=True, msg="Success to generate golden_config_db.json") | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
import json | ||
from ansible.module_utils.basic import AnsibleModule | ||
|
||
|
||
def get_macsec_profile(module, macsec_profile): | ||
with open('/tmp/profile.json') as f: | ||
macsec_profiles = json.load(f) | ||
for k, v in list(macsec_profiles.items()): | ||
if k == macsec_profile: | ||
profile = v | ||
# Update the macsec profile name in the profile context | ||
profile['macsec_profile'] = k | ||
break | ||
return profile | ||
|
||
|
||
def main(): | ||
module = AnsibleModule(argument_spec=dict(macsec_profile=dict(required=True, type='str'))) | ||
|
||
macsec_profile = module.params['macsec_profile'] | ||
module.exit_json(profile=get_macsec_profile(module, macsec_profile), changed=False) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,6 +57,15 @@ interface Management {{ mgmt_if_index }} | |
ip address {{ mgmt_ip }}/{{ mgmt_prefixlen }} | ||
no shutdown | ||
! | ||
{% if enable_macsec is defined %} | ||
judyjoseph marked this conversation as resolved.
Show resolved
Hide resolved
|
||
mac security | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to add similar change when using SONiC vm as neighbor ? |
||
profile {{ profile.macsec_profile }} | ||
cipher aes256-gcm-xpn | ||
key {{ profile.primary_ckn }} 7 {{ profile.primary_cak }} | ||
traffic unprotected drop | ||
sci | ||
{% endif %} | ||
! | ||
{% set ns = namespace(po_mbr_cnt=0) %} | ||
{% for name, iface in host['interfaces'].items() %} | ||
{% if name.startswith('Ethernet') %} | ||
|
@@ -75,6 +84,10 @@ interface {{ name }} | |
{% if name.startswith('Port-Channel') %} | ||
{% set min_links = (ns.po_mbr_cnt * 0.75) | round(0, 'ceil') | int %} | ||
port-channel min-links {{ min_links }} | ||
{% else %} | ||
{% if enable_macsec is defined %} | ||
mac security profile {{ profile.macsec_profile }} | ||
{% endif %} | ||
{% endif %} | ||
{% if iface['lacp'] is defined %} | ||
channel-group {{ iface['lacp'] }} mode active | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
{%- set asic_cnt = asic_cnt|int -%} | ||
{% if asic_cnt > 1 %} | ||
"localhost": { | ||
"MACSEC_PROFILE": {} | ||
}, | ||
{% for ns in range(asic_cnt) %} | ||
"asic{{ns}}": { | ||
"MACSEC_PROFILE": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we check for |
||
"{{macsec_profile}}": { | ||
"priority": "{{priority}}", | ||
"cipher_suite": "{{cipher_suite}}", | ||
"primary_cak": "{{primary_cak}}", | ||
"primary_ckn": "{{primary_ckn}}", | ||
"policy": "{{policy}}", | ||
"send_sci": "{{send_sci}}" | ||
} | ||
} | ||
{% if ns == asic_cnt-1 %} | ||
} | ||
{% else %} | ||
}, | ||
{% endif %} | ||
{%- endfor -%} | ||
{% else %} | ||
{ | ||
"MACSEC_PROFILE": {} | ||
}, | ||
{%- endif -%} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to be gated on something like
when: "('t2' not in topo)"
, or moved lower, otherwise deploy-mg will fail here on t2 since the profile/templates are not on the dut