diff --git a/crm/main.py b/crm/main.py index 37e0b8eb12c5..b419cc212f21 100644 --- a/crm/main.py +++ b/crm/main.py @@ -40,7 +40,11 @@ def show_summary(self): crm_info = configdb.get_entry('CRM', 'Config') if crm_info: - click.echo('\nPolling Interval: ' + crm_info['polling_interval'] + ' second(s)\n') + try: + click.echo('\nPolling Interval: ' + crm_info['polling_interval'] + ' second(s)\n') + except KeyError: + click.echo('\nError! Could not get CRM configuration.\n') + click.echo('\nError! Please configure polling interval.\n') else: click.echo('\nError! Could not get CRM configuration.\n') @@ -66,10 +70,16 @@ def show_thresholds(self, resource): if resource == 'all': for res in ["ipv4_route", "ipv6_route", "ipv4_nexthop", "ipv6_nexthop", "ipv4_neighbor", "ipv6_neighbor", "nexthop_group_member", "nexthop_group", "acl_table", "acl_group", "acl_entry", - "acl_counter", "fdb_entry"]: - data.append([res, crm_info[res + "_threshold_type"], crm_info[res + "_low_threshold"], crm_info[res + "_high_threshold"]]) + "acl_counter", "fdb_entry", "ipmc_entry", "snat_entry", "dnat_entry"]: + try: + data.append([res, crm_info[res + "_threshold_type"], crm_info[res + "_low_threshold"], crm_info[res + "_high_threshold"]]) + except KeyError: + pass else: - data.append([resource, crm_info[resource + "_threshold_type"], crm_info[resource + "_low_threshold"], crm_info[resource + "_high_threshold"]]) + try: + data.append([resource, crm_info[resource + "_threshold_type"], crm_info[resource + "_low_threshold"], crm_info[resource + "_high_threshold"]]) + except KeyError: + pass else: click.echo('\nError! Could not get CRM configuration.') @@ -87,10 +97,12 @@ def get_resources(self, resource): if crm_stats: if resource == 'all': for res in ["ipv4_route", "ipv6_route", "ipv4_nexthop", "ipv6_nexthop", "ipv4_neighbor", "ipv6_neighbor", - "nexthop_group_member", "nexthop_group", "fdb_entry"]: - data.append([res, crm_stats['crm_stats_' + res + "_used"], crm_stats['crm_stats_' + res + "_available"]]) + "nexthop_group_member", "nexthop_group", "fdb_entry", "ipmc_entry", "snat_entry", "dnat_entry"]: + if 'crm_stats_' + res + "_used" in crm_stats.keys() and 'crm_stats_' + res + "_available" in crm_stats.keys(): + data.append([res, crm_stats['crm_stats_' + res + "_used"], crm_stats['crm_stats_' + res + "_available"]]) else: - data.append([resource, crm_stats['crm_stats_' + resource + "_used"], crm_stats['crm_stats_' + resource + "_available"]]) + if 'crm_stats_' + resource + "_used" in crm_stats.keys() and 'crm_stats_' + resource + "_available" in crm_stats.keys(): + data.append([resource, crm_stats['crm_stats_' + resource + "_used"], crm_stats['crm_stats_' + resource + "_available"]]) return data @@ -353,6 +365,36 @@ def fdb(ctx): fdb.add_command(low) fdb.add_command(high) +@thresholds.group() +@click.pass_context +def ipmc(ctx): + """CRM configuration for IPMC resource""" + ctx.obj["crm"].res_type = 'ipmc_entry' + +ipmc.add_command(type) +ipmc.add_command(low) +ipmc.add_command(high) + +@thresholds.group() +@click.pass_context +def snat(ctx): + """CRM configuration for Source NAT resource""" + ctx.obj["crm"].res_type = 'snat_entry' + +snat.add_command(type) +snat.add_command(low) +snat.add_command(high) + +@thresholds.group() +@click.pass_context +def dnat(ctx): + """CRM configuration for Destination NAT resource""" + ctx.obj["crm"].res_type = 'dnat_entry' + +dnat.add_command(type) +dnat.add_command(low) +dnat.add_command(high) + @thresholds.group() @click.pass_context def acl(ctx): @@ -540,12 +582,42 @@ def fdb(ctx): elif ctx.obj["crm"].cli_mode == 'resources': ctx.obj["crm"].show_resources('fdb_entry') +@resources.command() +@click.pass_context +def ipmc(ctx): + """Show CRM information for IPMC resource""" + if ctx.obj["crm"].cli_mode == 'thresholds': + ctx.obj["crm"].show_thresholds('ipmc_entry') + elif ctx.obj["crm"].cli_mode == 'resources': + ctx.obj["crm"].show_resources('ipmc_entry') + +@resources.command() +@click.pass_context +def snat(ctx): + """Show CRM information for SNAT resource""" + if ctx.obj["crm"].cli_mode == 'thresholds': + ctx.obj["crm"].show_thresholds('snat_entry') + elif ctx.obj["crm"].cli_mode == 'resources': + ctx.obj["crm"].show_resources('snat_entry') + +@resources.command() +@click.pass_context +def dnat(ctx): + """Show CRM information for DNAT resource""" + if ctx.obj["crm"].cli_mode == 'thresholds': + ctx.obj["crm"].show_thresholds('dnat_entry') + elif ctx.obj["crm"].cli_mode == 'resources': + ctx.obj["crm"].show_resources('dnat_entry') + thresholds.add_command(acl) thresholds.add_command(all) thresholds.add_command(fdb) thresholds.add_command(ipv4) thresholds.add_command(ipv6) thresholds.add_command(nexthop) +thresholds.add_command(ipmc) +thresholds.add_command(snat) +thresholds.add_command(dnat) if __name__ == '__main__': diff --git a/tests/crm_test.py b/tests/crm_test.py index 2056b90775e5..f4fdcece100b 100644 --- a/tests/crm_test.py +++ b/tests/crm_test.py @@ -47,6 +47,9 @@ acl_entry percentage 70 85 acl_counter percentage 70 85 fdb_entry percentage 70 85 +ipmc_entry percentage 70 85 +snat_entry percentage 70 85 +dnat_entry percentage 70 85 """ @@ -122,6 +125,30 @@ """ +crm_show_thresholds_snat = """\ + +Resource Name Threshold Type Low Threshold High Threshold +--------------- ---------------- --------------- ---------------- +snat_entry percentage 70 85 + +""" + +crm_show_thresholds_dnat = """\ + +Resource Name Threshold Type Low Threshold High Threshold +--------------- ---------------- --------------- ---------------- +dnat_entry percentage 70 85 + +""" + +crm_show_thresholds_ipmc = """\ + +Resource Name Threshold Type Low Threshold High Threshold +--------------- ---------------- --------------- ---------------- +ipmc_entry percentage 70 85 + +""" + crm_new_show_summary = """\ Polling Interval: 30 second(s) @@ -216,6 +243,30 @@ """ +crm_new_show_thresholds_snat = """\ + +Resource Name Threshold Type Low Threshold High Threshold +--------------- ---------------- --------------- ---------------- +snat_entry percentage 60 90 + +""" + +crm_new_show_thresholds_dnat = """\ + +Resource Name Threshold Type Low Threshold High Threshold +--------------- ---------------- --------------- ---------------- +dnat_entry percentage 60 90 + +""" + +crm_new_show_thresholds_ipmc = """\ + +Resource Name Threshold Type Low Threshold High Threshold +--------------- ---------------- --------------- ---------------- +ipmc_entry percentage 60 90 + +""" + crm_show_resources_acl_group = """\ Stage Bind Point Resource Name Used Count Available Count @@ -267,6 +318,9 @@ nexthop_group_member 0 16384 nexthop_group 0 512 fdb_entry 0 32767 +ipmc_entry 0 24576 +snat_entry 0 1024 +dnat_entry 0 1024 Stage Bind Point Resource Name Used Count Available Count @@ -374,6 +428,30 @@ """ +crm_show_resources_snat = """\ + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +snat_entry 0 1024 + +""" + +crm_show_resources_dnat = """\ + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +dnat_entry 0 1024 + +""" + +crm_show_resources_ipmc = """\ + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +ipmc_entry 0 24576 + +""" + crm_multi_asic_show_resources_acl_group = """\ ASIC0 @@ -467,6 +545,9 @@ nexthop_group_member 0 16384 nexthop_group 0 512 fdb_entry 0 32767 +ipmc_entry 0 24576 +snat_entry 0 1024 +dnat_entry 0 1024 ASIC1 @@ -482,6 +563,9 @@ nexthop_group_member 0 16384 nexthop_group 0 512 fdb_entry 0 32767 +ipmc_entry 0 24576 +snat_entry 0 1024 +dnat_entry 0 1024 ASIC0 @@ -710,6 +794,58 @@ """ +crm_multi_asic_show_resources_snat = """\ + +ASIC0 + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +snat_entry 0 1024 + + +ASIC1 + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +snat_entry 0 1024 + +""" + +crm_multi_asic_show_resources_dnat = """\ + +ASIC0 + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +dnat_entry 0 1024 + + +ASIC1 + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +dnat_entry 0 1024 + +""" + +crm_multi_asic_show_resources_ipmc = """\ + +ASIC0 + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +ipmc_entry 0 24576 + + +ASIC1 + +Resource Name Used Count Available Count +--------------- ------------ ----------------- +ipmc_entry 0 24576 + +""" + + class TestCrm(object): @classmethod def setup_class(cls): @@ -913,6 +1049,54 @@ def test_crm_show_thresholds_nexthop_group_object(self): assert result.exit_code == 0 assert result.output == crm_new_show_thresholds_nexthop_group_object + def test_crm_show_thresholds_snat(self): + runner = CliRunner() + db = Db() + result = runner.invoke(crm.cli, ['show', 'thresholds', 'snat'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_thresholds_snat + result = runner.invoke(crm.cli, ['config', 'thresholds', 'snat', 'high', '90'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['config', 'thresholds', 'snat', 'low', '60'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['show', 'thresholds', 'snat'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_new_show_thresholds_snat + + def test_crm_show_thresholds_dnat(self): + runner = CliRunner() + db = Db() + result = runner.invoke(crm.cli, ['show', 'thresholds', 'dnat'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_thresholds_dnat + result = runner.invoke(crm.cli, ['config', 'thresholds', 'dnat', 'high', '90'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['config', 'thresholds', 'dnat', 'low', '60'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['show', 'thresholds', 'dnat'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_new_show_thresholds_dnat + + def test_crm_show_thresholds_ipmc(self): + runner = CliRunner() + db = Db() + result = runner.invoke(crm.cli, ['show', 'thresholds', 'ipmc'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_thresholds_ipmc + result = runner.invoke(crm.cli, ['config', 'thresholds', 'ipmc', 'high', '90'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['config', 'thresholds', 'ipmc', 'low', '60'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['show', 'thresholds', 'ipmc'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_new_show_thresholds_ipmc + def test_crm_show_resources_acl_group(self): runner = CliRunner() result = runner.invoke(crm.cli, ['show', 'resources', 'acl', 'group']) @@ -997,6 +1181,27 @@ def test_crm_show_resources_nexthop(self): assert result.exit_code == 0 assert result.output == crm_show_resources_nexthop_group_object + def test_crm_show_resources_snat(self): + runner = CliRunner() + result = runner.invoke(crm.cli, ['show', 'resources', 'snat']) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_resources_snat + + def test_crm_show_resources_dnat(self): + runner = CliRunner() + result = runner.invoke(crm.cli, ['show', 'resources', 'dnat']) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_resources_dnat + + def test_crm_show_resources_ipmc(self): + runner = CliRunner() + result = runner.invoke(crm.cli, ['show', 'resources', 'ipmc']) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_resources_ipmc + @classmethod def teardown_class(cls): print("TEARDOWN") @@ -1209,6 +1414,55 @@ def test_crm_show_thresholds_nexthop_group_object(self): assert result.exit_code == 0 assert result.output == crm_new_show_thresholds_nexthop_group_object + def test_crm_show_thresholds_snat(self): + runner = CliRunner() + db = Db() + result = runner.invoke(crm.cli, ['show', 'thresholds', 'snat'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_thresholds_snat + result = runner.invoke(crm.cli, ['config', 'thresholds', 'snat', 'high', '90'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['config', 'thresholds', 'snat', 'low', '60'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['show', 'thresholds', 'snat'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_new_show_thresholds_snat + + def test_crm_show_thresholds_dnat(self): + runner = CliRunner() + db = Db() + result = runner.invoke(crm.cli, ['show', 'thresholds', 'dnat'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_thresholds_dnat + result = runner.invoke(crm.cli, ['config', 'thresholds', 'dnat', 'high', '90'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['config', 'thresholds', 'dnat', 'low', '60'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['show', 'thresholds', 'dnat'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_new_show_thresholds_dnat + + def test_crm_show_thresholds_ipmc(self): + runner = CliRunner() + db = Db() + result = runner.invoke(crm.cli, ['show', 'thresholds', 'ipmc'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_show_thresholds_ipmc + result = runner.invoke(crm.cli, ['config', 'thresholds', 'ipmc', 'high', '90'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['config', 'thresholds', 'ipmc', 'low', '60'], obj=db) + print(sys.stderr, result.output) + result = runner.invoke(crm.cli, ['show', 'thresholds', 'ipmc'], obj=db) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_new_show_thresholds_ipmc + + def test_crm_multi_asic_show_resources_acl_group(self): runner = CliRunner() result = runner.invoke(crm.cli, ['show', 'resources', 'acl', 'group']) @@ -1293,6 +1547,28 @@ def test_crm_multi_asic_show_resources_nexthop(self): assert result.exit_code == 0 assert result.output == crm_multi_asic_show_resources_nexthop_group_object + def test_crm_multi_asic_show_resources_snat(self): + runner = CliRunner() + result = runner.invoke(crm.cli, ['show', 'resources', 'snat']) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_multi_asic_show_resources_snat + + def test_crm_multi_asic_show_resources_dnat(self): + runner = CliRunner() + result = runner.invoke(crm.cli, ['show', 'resources', 'dnat']) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_multi_asic_show_resources_dnat + + def test_crm_multi_asic_show_resources_ipmc(self): + runner = CliRunner() + result = runner.invoke(crm.cli, ['show', 'resources', 'ipmc']) + print(sys.stderr, result.output) + assert result.exit_code == 0 + assert result.output == crm_multi_asic_show_resources_ipmc + + @classmethod def teardown_class(cls): print("TEARDOWN") diff --git a/tests/mock_tables/asic0/config_db.json b/tests/mock_tables/asic0/config_db.json index 826daf4c6e74..cd7b49fd0aa1 100644 --- a/tests/mock_tables/asic0/config_db.json +++ b/tests/mock_tables/asic0/config_db.json @@ -148,7 +148,16 @@ "ipv6_route_low_threshold": "70", "acl_entry_high_threshold": "85", "fdb_entry_low_threshold": "70", - "ipv6_nexthop_high_threshold": "85" + "ipv6_nexthop_high_threshold": "85", + "snat_entry_threshold_type": "percentage", + "snat_entry_high_threshold": "85", + "snat_entry_low_threshold": "70", + "dnat_entry_threshold_type": "percentage", + "dnat_entry_high_threshold": "85", + "dnat_entry_low_threshold": "70", + "ipmc_entry_threshold_type": "percentage", + "ipmc_entry_high_threshold": "85", + "ipmc_entry_low_threshold": "70" }, "MUX_CABLE|Ethernet32": { "state": "auto", diff --git a/tests/mock_tables/asic0/counters_db.json b/tests/mock_tables/asic0/counters_db.json index 488915a79c8b..9976978c642f 100644 --- a/tests/mock_tables/asic0/counters_db.json +++ b/tests/mock_tables/asic0/counters_db.json @@ -1687,7 +1687,13 @@ "crm_stats_ipv6_route_used":"60", "crm_stats_ipv6_route_available":"16324", "crm_stats_ipv6_nexthop_used":"8", - "crm_stats_ipv6_neighbor_available":"4084" + "crm_stats_ipv6_neighbor_available":"4084", + "crm_stats_ipmc_entry_used":"0", + "crm_stats_ipmc_entry_available":"24576", + "crm_stats_snat_entry_used":"0", + "crm_stats_snat_entry_available":"1024", + "crm_stats_dnat_entry_used":"0", + "crm_stats_dnat_entry_available":"1024" }, "CRM:ACL_STATS:EGRESS:PORT":{ "crm_stats_acl_table_used":"0", diff --git a/tests/mock_tables/asic1/config_db.json b/tests/mock_tables/asic1/config_db.json index 9bd34c08a1cf..4d515ba2d3f2 100644 --- a/tests/mock_tables/asic1/config_db.json +++ b/tests/mock_tables/asic1/config_db.json @@ -117,7 +117,16 @@ "ipv6_route_low_threshold": "70", "acl_entry_high_threshold": "85", "fdb_entry_low_threshold": "70", - "ipv6_nexthop_high_threshold": "85" + "ipv6_nexthop_high_threshold": "85", + "snat_entry_threshold_type": "percentage", + "snat_entry_high_threshold": "85", + "snat_entry_low_threshold": "70", + "dnat_entry_threshold_type": "percentage", + "dnat_entry_high_threshold": "85", + "dnat_entry_low_threshold": "70", + "ipmc_entry_threshold_type": "percentage", + "ipmc_entry_high_threshold": "85", + "ipmc_entry_low_threshold": "70" }, "MUX_CABLE|Ethernet32": { "state": "auto", diff --git a/tests/mock_tables/asic1/counters_db.json b/tests/mock_tables/asic1/counters_db.json index a323ecde3e92..798bb80b4fbf 100644 --- a/tests/mock_tables/asic1/counters_db.json +++ b/tests/mock_tables/asic1/counters_db.json @@ -894,7 +894,13 @@ "crm_stats_ipv6_route_used":"60", "crm_stats_ipv6_route_available":"16324", "crm_stats_ipv6_nexthop_used":"8", - "crm_stats_ipv6_neighbor_available":"4084" + "crm_stats_ipv6_neighbor_available":"4084", + "crm_stats_ipmc_entry_used":"0", + "crm_stats_ipmc_entry_available":"24576", + "crm_stats_snat_entry_used":"0", + "crm_stats_snat_entry_available":"1024", + "crm_stats_dnat_entry_used":"0", + "crm_stats_dnat_entry_available":"1024" }, "CRM:ACL_STATS:EGRESS:PORT":{ "crm_stats_acl_table_used":"0", diff --git a/tests/mock_tables/config_db.json b/tests/mock_tables/config_db.json index 74437b197a9a..fde2f7dc47ca 100644 --- a/tests/mock_tables/config_db.json +++ b/tests/mock_tables/config_db.json @@ -1314,7 +1314,16 @@ "ipv6_route_low_threshold": "70", "acl_entry_high_threshold": "85", "fdb_entry_low_threshold": "70", - "ipv6_nexthop_high_threshold": "85" + "ipv6_nexthop_high_threshold": "85", + "snat_entry_threshold_type": "percentage", + "snat_entry_high_threshold": "85", + "snat_entry_low_threshold": "70", + "dnat_entry_threshold_type": "percentage", + "dnat_entry_high_threshold": "85", + "dnat_entry_low_threshold": "70", + "ipmc_entry_threshold_type": "percentage", + "ipmc_entry_high_threshold": "85", + "ipmc_entry_low_threshold": "70" }, "CHASSIS_MODULE|LINE-CARD1": { "admin_status": "down" diff --git a/tests/mock_tables/counters_db.json b/tests/mock_tables/counters_db.json index b2de41ae9d5c..0a06fc22d965 100644 --- a/tests/mock_tables/counters_db.json +++ b/tests/mock_tables/counters_db.json @@ -1114,7 +1114,13 @@ "crm_stats_ipv6_route_used":"60", "crm_stats_ipv6_route_available":"16324", "crm_stats_ipv6_nexthop_used":"8", - "crm_stats_ipv6_neighbor_available":"4084" + "crm_stats_ipv6_neighbor_available":"4084", + "crm_stats_ipmc_entry_used":"0", + "crm_stats_ipmc_entry_available":"24576", + "crm_stats_snat_entry_used":"0", + "crm_stats_snat_entry_available":"1024", + "crm_stats_dnat_entry_used":"0", + "crm_stats_dnat_entry_available":"1024" }, "CRM:ACL_STATS:EGRESS:PORT":{ "crm_stats_acl_table_used":"0",