From fc65941d86558711daba8d8ddd7d72c88eeff6b2 Mon Sep 17 00:00:00 2001 From: Xu Yuandong Date: Sun, 13 Oct 2019 00:57:56 +0800 Subject: [PATCH] Backport/2.9/63332 ce_netstream_global: bugs fix(list index out of range) (#63332) (#63389) * ce_netstream_global: bugs fix(list index out of range) (#63332) * update to fix bugs:index out of range * list index out of range * list index out of range * update for bad-whitespace * Update ce_netstream_aging.py * Update ce_netstream_aging.py * Update ce_netstream_global.py * Update ce_netstream_global.py * Update ce_netstream_global.py * Update ce_netstream_template.py * Update ce_netstream_global.py * Update ce_netstream_global.py * Update ce_netstream_template.py * Update ce_netstream_aging.py (cherry picked from commit b7f12f9ff3c103abcf0f80966625895869463855) * add a changelog fragment. * Update 63389_ce_netsream_list_index_out_of_range.yml empty-lines too many blank lines (1 > 0) --- ...89_ce_netsream_list_index_out_of_range.yml | 4 + .../network/cloudengine/ce_netstream_aging.py | 11 ++- .../cloudengine/ce_netstream_global.py | 81 ++++++++++--------- .../cloudengine/ce_netstream_template.py | 25 +++--- 4 files changed, 65 insertions(+), 56 deletions(-) create mode 100644 changelogs/fragments/63389_ce_netsream_list_index_out_of_range.yml diff --git a/changelogs/fragments/63389_ce_netsream_list_index_out_of_range.yml b/changelogs/fragments/63389_ce_netsream_list_index_out_of_range.yml new file mode 100644 index 00000000000..244d11460d3 --- /dev/null +++ b/changelogs/fragments/63389_ce_netsream_list_index_out_of_range.yml @@ -0,0 +1,4 @@ +bugfixes: + - ce_netstream_aging - Fix bugs(list index out of range). + - ce_netstream_global - Fix bugs(list index out of range and key error). + - ce_netstream_template - Fix bugs(list index out of range and update commands error). diff --git a/lib/ansible/modules/network/cloudengine/ce_netstream_aging.py b/lib/ansible/modules/network/cloudengine/ce_netstream_aging.py index bdb478bcd1a..7dbf63bef02 100644 --- a/lib/ansible/modules/network/cloudengine/ce_netstream_aging.py +++ b/lib/ansible/modules/network/cloudengine/ce_netstream_aging.py @@ -191,6 +191,7 @@ changed: sample: true ''' +import re from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.network.cloudengine.ce import exec_command, load_config from ansible.module_utils.network.cloudengine.ce import ce_argument_spec @@ -285,14 +286,14 @@ class NetStreamAging(object): for config_mem in config_list: config_mem = config_mem.lstrip() config_mem_list = config_mem.split(' ') - if config_mem_list[2] == "ip": + if len(config_mem_list) > 4 and config_mem_list[2] == "ip": if config_mem_list[3] == "active": active_tmp["ip"] = config_mem_list[4] if config_mem_list[3] == "inactive": inactive_tmp["ip"] = config_mem_list[4] if config_mem_list[3] == "tcp-session": tcp_tmp["ip"] = "present" - if config_mem_list[2] == "vxlan": + if len(config_mem_list) > 4 and config_mem_list[2] == "vxlan": if config_mem_list[4] == "active": active_tmp["vxlan"] = config_mem_list[5] if config_mem_list[4] == "inactive": @@ -333,7 +334,7 @@ class NetStreamAging(object): inactive_tmp["ip"] = config_mem_list[4] if config_mem_list[3] == "tcp-session": tcp_tmp["ip"] = "present" - if len(config_mem_list) > 5 and config_mem_list[2] == "vxlan": + if len(config_mem_list) > 4 and config_mem_list[2] == "vxlan": if config_mem_list[4] == "active": active_tmp["vxlan"] = config_mem_list[5] if config_mem_list[4] == "inactive": @@ -363,7 +364,7 @@ class NetStreamAging(object): if not self.manual_slot: self.module.fail_json( msg="Error: If use manual timeout mode,slot number is needed.") - if not str(self.manual_slot).isdigit(): + if re.match(r'^\d+(\/\d*)?$', self.manual_slot) is None: self.module.fail_json( msg='Error: Slot number should be numerical.') @@ -481,6 +482,8 @@ class NetStreamAging(object): self.get_proposed() self.operate_time_out() self.get_end_state() + if self.existing == self.end_state: + self.changed = False self.results['changed'] = self.changed self.results['proposed'] = self.proposed self.results['existing'] = self.existing diff --git a/lib/ansible/modules/network/cloudengine/ce_netstream_global.py b/lib/ansible/modules/network/cloudengine/ce_netstream_global.py index a11257fd685..952dd3ede4d 100644 --- a/lib/ansible/modules/network/cloudengine/ce_netstream_global.py +++ b/lib/ansible/modules/network/cloudengine/ce_netstream_global.py @@ -212,6 +212,7 @@ changed: sample: true ''' +import re from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.network.cloudengine.ce import load_config from ansible.module_utils.network.cloudengine.ce import get_connection, rm_config_prefix @@ -252,6 +253,7 @@ def get_config(module, flags): """Retrieves the current config from the device or cache """ + time_stamp_regex = re.compile(r'\s*\d{4}-\d{1,2}-\d{1,2}\s+\d{2}\:\d{2}\:\d{2}\.\d+\s*') flags = [] if flags is None else flags if isinstance(flags, str): flags = [flags] @@ -271,13 +273,14 @@ def get_config(module, flags): if "include-default" in flag: cfg = rm_config_prefix(cfg) break + lines = cfg.split('\n') + lines = [l for l in lines if time_stamp_regex.match(l) is None] if cfg.startswith('display'): - lines = cfg.split('\n') if len(lines) > 1: - return '\n'.join(lines[1:]) + lines.pop(0) else: return '' - return cfg + return '\n'.join(lines) class NetStreamGlobal(object): @@ -360,12 +363,13 @@ class NetStreamGlobal(object): sampler_tmp = dict() sampler_tmp1 = dict() flags = list() - exp = " | ignore-case include ^netstream sampler random-packets" + exp = " | ignore-case include ^netstream sampler random-packets" flags.append(exp) config = get_config(self.module, flags) if not config: sampler_tmp["sampler_interval"] = "null" sampler_tmp["sampler_direction"] = "null" + sampler_tmp["interface"] = "null" else: config_list = config.split(' ') config_num = len(config_list) @@ -389,12 +393,13 @@ class NetStreamGlobal(object): sampler_tmp1 = dict() config_mem_list = config_mem.split(' ') config_num = len(config_mem_list) - sampler_tmp1["sampler_direction"] = config_mem_list[ - config_num - 1] - sampler_tmp1["sampler_interval"] = config_mem_list[ - config_num - 2] - sampler_tmp1["interface"] = self.interface - self.existing["sampler"].append(sampler_tmp1) + if config_num > 1: + sampler_tmp1["sampler_direction"] = config_mem_list[ + config_num - 1] + sampler_tmp1["sampler_interval"] = config_mem_list[ + config_num - 2] + sampler_tmp1["interface"] = self.interface + self.existing["sampler"].append(sampler_tmp1) def get_exist_statistic_record(self): """get exist netstream statistic record parameter""" @@ -426,7 +431,7 @@ class NetStreamGlobal(object): config_mem = config_mem.lstrip() statistic_tmp["statistics_record"] = list() config_mem_list = config_mem.split(' ') - if str(config_mem_list[3]) == "ip": + if len(config_mem_list) > 3 and str(config_mem_list[3]) == "ip": statistic_tmp["statistics_record"].append( str(config_mem_list[2])) statistic_tmp["type"] = "ip" @@ -435,7 +440,7 @@ class NetStreamGlobal(object): statistic_tmp1["statistics_record"] = list() config_mem = config_mem.lstrip() config_mem_list = config_mem.split(' ') - if str(config_mem_list[3]) == "vxlan": + if len(config_mem_list) > 3 and str(config_mem_list[3]) == "vxlan": statistic_tmp1["statistics_record"].append( str(config_mem_list[2])) statistic_tmp1["type"] = "vxlan" @@ -461,8 +466,9 @@ class NetStreamGlobal(object): for config_mem in config_list: config_mem = config_mem.lstrip() config_mem_list = config_mem.split(' ') - statistic_tmp1["statistics_direction"].append( - str(config_mem_list[1])) + if len(config_mem_list) > 1: + statistic_tmp1["statistics_direction"].append( + str(config_mem_list[1])) statistic_tmp1["interface"] = self.interface self.existing["statistic"].append(statistic_tmp1) @@ -487,10 +493,10 @@ class NetStreamGlobal(object): config_list = config.split('\n') for config_mem in config_list: config_mem_list = config_mem.split(' ') - if str(config_mem_list[2]) == "ip": + if len(config_mem_list) > 2 and str(config_mem_list[2]) == "ip": index_switch_tmp["index-switch"] = "32" index_switch_tmp["type"] = "ip" - if str(config_mem_list[2]) == "vxlan": + if len(config_mem_list) > 2 and str(config_mem_list[2]) == "vxlan": index_switch_tmp1["index-switch"] = "32" index_switch_tmp1["type"] = "vxlan" self.existing["index-switch"].append(index_switch_tmp) @@ -508,9 +514,9 @@ class NetStreamGlobal(object): config_list = config.split('\n') for config_mem in config_list: config_mem_list = config_mem.split(' ') - if config_mem_list[3] == "ip": + if len(config_mem_list) > 3 and config_mem_list[3] == "ip": self.existing["ip_record"].append(config_mem_list[2]) - if config_mem_list[3] == "vxlan": + if len(config_mem_list) > 3 and config_mem_list[3] == "vxlan": self.existing["vxlan_record"].append(config_mem_list[2]) def get_end_sampler_interval(self): @@ -519,7 +525,7 @@ class NetStreamGlobal(object): sampler_tmp = dict() sampler_tmp1 = dict() flags = list() - exp = " | ignore-case include ^netstream sampler random-packets" + exp = " | ignore-case include ^netstream sampler random-packets" flags.append(exp) config = get_config(self.module, flags) if not config: @@ -528,13 +534,14 @@ class NetStreamGlobal(object): else: config_list = config.split(' ') config_num = len(config_list) - sampler_tmp["sampler_direction"] = config_list[config_num - 1] - sampler_tmp["sampler_interval"] = config_list[config_num - 2] + if config_num > 1: + sampler_tmp["sampler_direction"] = config_list[config_num - 1] + sampler_tmp["sampler_interval"] = config_list[config_num - 2] sampler_tmp["interface"] = "all" self.end_state["sampler"].append(sampler_tmp) if self.interface != "all": flags = list() - exp = r" | ignore-case section include ^#\s+interface %s" \ + exp = r" | ignore-case section include ^#\s+interface %s" \ r" | include netstream sampler random-packets" % self.interface flags.append(exp) config = get_config(self.module, flags) @@ -548,12 +555,13 @@ class NetStreamGlobal(object): sampler_tmp1 = dict() config_mem_list = config_mem.split(' ') config_num = len(config_mem_list) - sampler_tmp1["sampler_direction"] = config_mem_list[ - config_num - 1] - sampler_tmp1["sampler_interval"] = config_mem_list[ - config_num - 2] - sampler_tmp1["interface"] = self.interface - self.end_state["sampler"].append(sampler_tmp1) + if config_num > 1: + sampler_tmp1["sampler_direction"] = config_mem_list[ + config_num - 1] + sampler_tmp1["sampler_interval"] = config_mem_list[ + config_num - 2] + sampler_tmp1["interface"] = self.interface + self.end_state["sampler"].append(sampler_tmp1) def get_end_statistic_record(self): """get end netstream statistic record parameter""" @@ -585,7 +593,7 @@ class NetStreamGlobal(object): config_mem = config_mem.lstrip() statistic_tmp["statistics_record"] = list() config_mem_list = config_mem.split(' ') - if str(config_mem_list[3]) == "ip": + if len(config_mem_list) > 3 and str(config_mem_list[3]) == "ip": statistic_tmp["statistics_record"].append( str(config_mem_list[2])) statistic_tmp["type"] = "ip" @@ -594,7 +602,7 @@ class NetStreamGlobal(object): statistic_tmp1["statistics_record"] = list() config_mem = config_mem.lstrip() config_mem_list = config_mem.split(' ') - if str(config_mem_list[3]) == "vxlan": + if len(config_mem_list) > 3 and str(config_mem_list[3]) == "vxlan": statistic_tmp1["statistics_record"].append( str(config_mem_list[2])) statistic_tmp1["type"] = "vxlan" @@ -620,8 +628,9 @@ class NetStreamGlobal(object): for config_mem in config_list: config_mem = config_mem.lstrip() config_mem_list = config_mem.split(' ') - statistic_tmp1["statistics_direction"].append( - str(config_mem_list[1])) + if len(config_mem_list) > 1: + statistic_tmp1["statistics_direction"].append( + str(config_mem_list[1])) statistic_tmp1["interface"] = self.interface self.end_state["statistic"].append(statistic_tmp1) @@ -646,10 +655,10 @@ class NetStreamGlobal(object): config_list = config.split('\n') for config_mem in config_list: config_mem_list = config_mem.split(' ') - if str(config_mem_list[2]) == "ip": + if len(config_mem_list) > 2 and str(config_mem_list[2]) == "ip": index_switch_tmp["index-switch"] = "32" index_switch_tmp["type"] = "ip" - if str(config_mem_list[2]) == "vxlan": + if len(config_mem_list) > 2 and str(config_mem_list[2]) == "vxlan": index_switch_tmp1["index-switch"] = "32" index_switch_tmp1["type"] = "vxlan" self.end_state["index-switch"].append(index_switch_tmp) @@ -843,13 +852,13 @@ class NetStreamGlobal(object): tmp_list = statistic_tmp["statistics_record"] if self.type == statistic_tmp["type"]: if self.type == "ip": - if len(tmp_list): + if len(tmp_list) > 0: cmd = "netstream record %s ip" % tmp_list[0] self.cli_add_command(cmd, undo=True) cmd = "netstream record %s ip" % self.statistics_record self.cli_add_command(cmd) if self.type == "vxlan": - if len(tmp_list): + if len(tmp_list) > 0: cmd = "netstream record %s vxlan inner-ip" % tmp_list[ 0] self.cli_add_command(cmd, undo=True) diff --git a/lib/ansible/modules/network/cloudengine/ce_netstream_template.py b/lib/ansible/modules/network/cloudengine/ce_netstream_template.py index 2254b25d1f1..75b5659f879 100644 --- a/lib/ansible/modules/network/cloudengine/ce_netstream_template.py +++ b/lib/ansible/modules/network/cloudengine/ce_netstream_template.py @@ -264,13 +264,13 @@ class NetstreamTemplate(object): self.cli_get_netstream_config() - if self.netstream_cfg: + if self.netstream_cfg is not None and "netstream record" in self.netstream_cfg: self.existing["type"] = self.type self.existing["record_name"] = self.record_name if self.description: tmp_value = re.findall(r'description (.*)', self.netstream_cfg) - if tmp_value: + if tmp_value is not None and len(tmp_value) > 0: self.existing["description"] = tmp_value[0] if self.match: @@ -297,13 +297,13 @@ class NetstreamTemplate(object): self.cli_get_netstream_config() - if self.netstream_cfg: + if self.netstream_cfg is not None and "netstream record" in self.netstream_cfg: self.end_state["type"] = self.type self.end_state["record_name"] = self.record_name if self.description: tmp_value = re.findall(r'description (.*)', self.netstream_cfg) - if tmp_value: + if tmp_value is not None and len(tmp_value) > 0: self.end_state["description"] = tmp_value[0] if self.match: @@ -340,13 +340,13 @@ class NetstreamTemplate(object): cmd = "netstream record %s vxlan inner-ip" % self.record_name cmds.append(cmd) - if not self.netstream_cfg: + if self.existing.get('record_name') != self.record_name: self.updates_cmd.append(cmd) need_create_record = True if self.description: cmd = "description %s" % self.description.strip() - if not self.netstream_cfg or cmd not in self.netstream_cfg: + if need_create_record or not self.netstream_cfg or cmd not in self.netstream_cfg: cmds.append(cmd) self.updates_cmd.append(cmd) @@ -358,29 +358,22 @@ class NetstreamTemplate(object): cmd = "match inner-ip %s" % self.match cfg = "match inner-ip" - if not self.netstream_cfg or cfg not in self.netstream_cfg or self.match != self.existing["match"][0]: + if need_create_record or cfg not in self.netstream_cfg or self.match != self.existing["match"][0]: cmds.append(cmd) self.updates_cmd.append(cmd) if self.collect_counter: cmd = "collect counter %s" % self.collect_counter - if not self.netstream_cfg or cmd not in self.netstream_cfg: + if need_create_record or cmd not in self.netstream_cfg: cmds.append(cmd) self.updates_cmd.append(cmd) if self.collect_interface: cmd = "collect interface %s" % self.collect_interface - if not self.netstream_cfg or cmd not in self.netstream_cfg: + if need_create_record or cmd not in self.netstream_cfg: cmds.append(cmd) self.updates_cmd.append(cmd) - if not need_create_record and len(cmds) == 1: - if self.type == "ip": - cmd = "netstream record %s ip" % self.record_name - else: - cmd = "netstream record %s vxlan inner-ip" % self.record_name - cmds.remove(cmd) - if cmds: self.cli_load_config(cmds) self.changed = True