def get_tam_int_ifa_ts_flow_stats(args): api_response = {} api = cc.ApiClient() # connect to COUNTERS_DB counters_db = ConfigDBConnector() counters_db.db_connect('COUNTERS_DB') if len(args) == 1 and args[0] != "all": path = cc.Path('/restconf/data/sonic-tam-int-ifa-ts:sonic-tam-int-ifa-ts/TAM_INT_IFA_TS_FLOW_TABLE/TAM_INT_IFA_TS_FLOW_TABLE_LIST={name}', name=args[0]) else: path = cc.Path('/restconf/data/sonic-tam-int-ifa-ts:sonic-tam-int-ifa-ts/TAM_INT_IFA_TS_FLOW_TABLE') response = api.get(path) if response.ok(): if response.content: if len(args) == 1 and args[0] != "all": api_response = response.content['sonic-tam-int-ifa-ts:TAM_INT_IFA_TS_FLOW_TABLE_LIST'] else: api_response = response.content['sonic-tam-int-ifa-ts:TAM_INT_IFA_TS_FLOW_TABLE']['TAM_INT_IFA_TS_FLOW_TABLE_LIST'] for i in range(len(api_response)): api_response[i]['Packets'] = 0 api_response[i]['Bytes'] = 0 if "acl-table-name" not in api_response[i] and "acl-rule-name" not in api_response[i]: return acl_counter_key = 'COUNTERS:' + api_response[i]['acl-table-name'] + ':' + api_response[i]['acl-rule-name'] flow_stats = counters_db.get_all(counters_db.COUNTERS_DB, acl_counter_key) if flow_stats is not None: api_response[i]['Packets'] = flow_stats['Packets'] api_response[i]['Bytes'] = flow_stats['Bytes'] show_cli_output("show_tam_int_ifa_ts_flow_stats.j2", api_response)
def get_keypath(func, args): keypath = None instance = None if func == 'get_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_neighbors': keypath = cc.Path( '/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv4/neighbors', name=args[1], index="0") elif func == 'get_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_neighbors': keypath = cc.Path( '/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv6/neighbors', name=args[1], index="0") elif func == 'get_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv4_neighbors_neighbor': keypath = cc.Path( '/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv4/neighbors/neighbor={ip}', name=args[1], index="0", ip=args[3]) elif func == 'get_openconfig_if_ip_interfaces_interface_subinterfaces_subinterface_ipv6_neighbors_neighbor': keypath = cc.Path( '/restconf/data/openconfig-interfaces:interfaces/interface={name}/subinterfaces/subinterface={index}/openconfig-if-ip:ipv6/neighbors/neighbor={ip}', name=args[1], index="0", ip=args[3]) return keypath
def get_vrf_data(vrf_name, vrf_show_data): api = cc.ApiClient() vrf = {} vrf_data = {} keypath = cc.Path( '/restconf/data/openconfig-network-instance:network-instances/network-instance={name}/config', name=vrf_name) vrf_config = api.get(keypath) if vrf_config.ok(): if len(vrf_config.content) == 0: return vrf_config vrf_data['openconfig-network-instance:config'] = vrf_config.content[ 'openconfig-network-instance:config'] if vrf_name == 'mgmt': vrf_data['openconfig-network-instance:interface'] = [] else: keypath = cc.Path( '/restconf/data/openconfig-network-instance:network-instances/network-instance={name}/interfaces/interface', name=vrf_name) vrf_intfs = api.get(keypath) if vrf_intfs.ok(): vrf_data[ 'openconfig-network-instance:interface'] = vrf_intfs.content[ 'openconfig-network-instance:interface'] else: vrf_data['openconfig-network-instance:interface'] = [] vrf[vrf_name] = vrf_data vrf_show_data.append(vrf) return vrf_config
def generate_community_standard_delete_keypath(args): member_exits = 0 community_member = '' for arg in args[6:]: member_exits = 1 if "local-AS" == arg: community_member += "NO_EXPORT_SUBCONFED" community_member += "," elif "no-peer" == arg: community_member += "NOPEER" community_member += "," elif "no-export" == arg: community_member += "NO_EXPORT" community_member += "," elif "no-advertise" == arg: community_member += "NO_ADVERTISE" community_member += "," else: community_member += arg community_member += "," if member_exits: community_member = community_member[:-1] keypath = cc.Path( '/restconf/data/openconfig-routing-policy:routing-policy/defined-sets/openconfig-bgp-policy:bgp-defined-sets/community-sets/community-set={community_list_name}/config/community-member={members}', community_list_name=args[5], members=community_member) else: keypath = cc.Path( '/restconf/data/openconfig-routing-policy:routing-policy/defined-sets/openconfig-bgp-policy:bgp-defined-sets/community-sets/community-set={community_list_name}', community_list_name=args[5]) return keypath
def invoke_show_api(func, args=[]): api = cc.ApiClient() keypath = [] body = None if func == 'get_bfd_peers': keypath = cc.Path( '/restconf/data/openconfig-bfd:bfd/openconfig-bfd-ext:bfd-state') return api.get(keypath) elif func == 'get_openconfig_bfd_ext_bfd_sessions_single_hop': keypath = cc.Path( '/restconf/data/openconfig-bfd:bfd/openconfig-bfd-ext:bfd-state/single-hop-state={address},{interfacename},{vrfname},{localaddress}', address=args[1], interfacename=args[2], vrfname=args[3], localaddress=args[4]) return api.get(keypath) elif func == 'get_openconfig_bfd_ext_bfd_sessions_multi_hop': keypath = cc.Path( '/restconf/data/openconfig-bfd:bfd/openconfig-bfd-ext:bfd-state/multi-hop-state={address},{interfacename},{vrfname},{localaddress}', address=args[1], interfacename=args[2], vrfname=args[3], localaddress=args[4]) return api.get(keypath) else: return api.cli_not_implemented(func)
def invoke_api(func, args): body = None api = cc.ApiClient() if func.startswith("rpc") == True: if func == 'rpc_sonic_image_management_image_install': body= validate_imagename(args, 'install') path = cc.Path('/restconf/operations/sonic-image-management:image-install') return api.post(path, body) if func == 'rpc_sonic_image_management_image_remove': body =validate_imagename(args, 'remove') path = cc.Path('/restconf/operations/sonic-image-management:image-remove') return api.post(path,body) if func == 'rpc_sonic_image_management_image_default': body =validate_imagename(args, 'default') path = cc.Path('/restconf/operations/sonic-image-management:image-default') return api.post(path,body) if func == 'get_sonic_image_management_sonic_image_management': path = cc.Path('/restconf/data/sonic-image-management:sonic-image-management') return api.get(path)
def invoke_api(func, args=[]): api = cc.ApiClient() if func == 'get_sonic_portchannel_sonic_portchannel_lag_table': path = cc.Path( '/restconf/data/sonic-portchannel:sonic-portchannel/LAG_TABLE') return api.get(path) if func == 'get_sonic_portchannel_sonic_portchannel_lag_table_lag_table_list': path = cc.Path( '/restconf/data/sonic-portchannel:sonic-portchannel/LAG_TABLE/LAG_TABLE_LIST={lagname}', lagname=args[0]) return api.get(path) if func == 'get_openconfig_lacp_lacp_interfaces': path = cc.Path('/restconf/data/openconfig-lacp:lacp/interfaces') return api.get(path) if func == 'get_openconfig_lacp_lacp_interfaces_interface': path = cc.Path( '/restconf/data/openconfig-lacp:lacp/interfaces/interface={name}', name=args[0]) return api.get(path) if func == 'get_openconfig_interfaces_interfaces_interface_state_counters': path = cc.Path( '/restconf/data/openconfig-interfaces:interfaces/interface={name}/state/counters', name=args[0]) return api.get(path) #print "invoke_api done" return api.cli_not_implemented(func)
def invoke_api(func, args): body = None api = cc.ApiClient() # Set/Get aaa configuration body = { "openconfig-system-ext:failthrough": False, "openconfig-system:authentication-method": ['local'] } failthrough = 'None' authmethod = [] # authentication-method is a leaf-list. So patch is not supported. A put opeartion # would clear existing other parameters as well. So reading existing contents and # trying to change only the user input parameter with a put path = cc.Path( '/restconf/data/openconfig-system:system/aaa/authentication/config') get_response = api.get(path) if get_response.ok(): if get_response.content: api_response = get_response.content if 'failthrough' in api_response['openconfig-system:config']: body["openconfig-system-ext:failthrough"] = api_response[ 'openconfig-system:config']['failthrough'] if 'authentication-method' in api_response[ 'openconfig-system:config']: body["openconfig-system:authentication-method"] = api_response[ 'openconfig-system:config']['authentication-method'] if func == 'put_openconfig_system_ext_system_aaa_authentication_config_failthrough': path = cc.Path( '/restconf/data/openconfig-system:system/aaa/authentication/config/openconfig-system-ext:failthrough' ) body["openconfig-system-ext:failthrough"] = (args[0] == "True") return api.put(path, body) elif func == 'put_openconfig_system_system_aaa_authentication_config_authentication_method': path = cc.Path( '/restconf/data/openconfig-system:system/aaa/authentication/config/authentication-method' ) # tricky logic: xml sends frist selection and values of both local and tacacs+ params # when user selects "local tacacs+", actioner receives "local local tacacs+" # when user selects "tacacs+ local", actioner receives "tacacs+ local tacacs+" authmethod.append(args[0]) if len(args) == 3: if args[0] == args[1]: authmethod.append(args[2]) else: authmethod.append(args[1]) else: pass body["openconfig-system:authentication-method"] = authmethod return api.put(path, body) elif func == 'get_openconfig_system_system_aaa_authentication_config': return get_response else: body = {} return api.cli_not_implemented(func)
def invoke(func, args): body = None aa = cc.ApiClient() if func == 'create_mirror_session': keypath = cc.Path( '/restconf/data/sonic-mirror-session:sonic-mirror-session/MIRROR_SESSION/MIRROR_SESSION_LIST={name}', name=args.session) body = collections.defaultdict(dict) entry = { "name": args.session, } if args.destination is not '': if args.destination != "erspan": entry["dst_port"] = args.destination if args.source is not '': entry["src_port"] = args.source if args.direction is not '': entry["direction"] = args.direction if args.destination == "erspan": if args.dst_ip is not '': entry["dst_ip"] = args.dst_ip if args.src_ip is not '': entry["src_ip"] = args.src_ip if args.dscp is not '': entry["dscp"] = int(args.dscp) if args.ttl is not '': entry["ttl"] = int(args.ttl) if args.gre is not '': entry["gre_type"] = args.gre if args.queue is not '': entry["queue"] = int(args.queue) body["MIRROR_SESSION_LIST"] = [entry] return aa.patch(keypath, body) # Remove mirror session if func == 'delete_mirror_session': keypath = cc.Path( '/restconf/data/sonic-mirror-session:sonic-mirror-session/MIRROR_SESSION/MIRROR_SESSION_LIST={name}', name=args.session) return aa.delete(keypath) else: print("%Error: not implemented") exit(1)
def show_link_state_tracking_group_info(args): aa = cc.ApiClient() if len(args): uri = cc.Path( '/restconf/data/sonic-link-state-tracking:sonic-link-state-tracking/INTF_TRACKING_TABLE/INTF_TRACKING_TABLE_LIST={grp_name}', grp_name=args[0]) else: uri = cc.Path( '/restconf/data/sonic-link-state-tracking:sonic-link-state-tracking/INTF_TRACKING_TABLE/INTF_TRACKING_TABLE_LIST' ) return aa.get(uri)
def get_tam_ifa_flow_stats(args): api_response = {} api = cc.ApiClient() if (len(args) == 1) and (args[0] != "all"): path = cc.Path( '/restconf/data/sonic-ifa:sonic-ifa/TAM_INT_IFA_FLOW_TABLE/TAM_INT_IFA_FLOW_TABLE_LIST={name}', name=args[0]) else: path = cc.Path( '/restconf/data/sonic-ifa:sonic-ifa/TAM_INT_IFA_FLOW_TABLE') response = api.get(path) if response.ok(): if response.content: if (len(args) == 1) and (args[0] != "all"): api_response = response.content[ 'sonic-ifa:TAM_INT_IFA_FLOW_TABLE_LIST'] else: api_response = response.content[ 'sonic-ifa:TAM_INT_IFA_FLOW_TABLE'][ 'TAM_INT_IFA_FLOW_TABLE_LIST'] for i in range(len(api_response)): api_response[i]['Packets'] = 0 api_response[i]['Bytes'] = 0 path = cc.Path('/restconf/data/openconfig-acl:acl/acl-sets') acl_info = api.get(path) if acl_info.ok(): if acl_info.content: acl_list = acl_info.content["openconfig-acl:acl-sets"][ "acl-set"] for acl in acl_list: if acl['name'] == api_response[i][ 'acl-table-name']: rule = api_response[i]['acl-rule-name'] # tokenize the rulename with '_' and fetch last number tmpseq = (rule.split("_", 1))[-1] acl_entry_list = acl["acl-entries"][ "acl-entry"] for entry in acl_entry_list: if int(tmpseq) == int( entry["sequence-id"]): api_response[i]['Packets'] = entry[ "state"]["matched-packets"] api_response[i]['Bytes'] = entry[ "state"]["matched-octets"] show_cli_output("show_tam_ifa_flow_stats.j2", api_response)
def invoke(func, args): body = {} aa = cc.ApiClient() if func == 'get_openconfig_ztp_ztp_state': path = cc.Path('/restconf/data/openconfig-ztp:ztp/state') return aa.get(path) else: path = cc.Path('/restconf/data/openconfig-ztp:ztp/config') if 'no' in sys.argv: body["openconfig-ztp:admin_mode"] = False else: body["openconfig-ztp:admin_mode"] = True return aa.post(path, body)
def invoke(func, args): body = None aa = cc.ApiClient() if func == 'get_openconfig_network_instance_network_instances_network_instance_fdb_mac_table_entries': keypath = cc.Path( '/restconf/data/openconfig-network-instance:network-instances/network-instance={name}/fdb/mac-table/entries', name='default') return aa.get(keypath) elif func == 'rpc_sonic_fdb_clear_fdb': keypath = cc.Path('/restconf/operations/sonic-fdb:clear_fdb') body = {"sonic-fdb:input": {"mac-param": "all"}} return aa.post(keypath, body) else: return body
def invoke_api(func, args=[]): api = cc.ApiClient() if func == 'get_sonic_portchannel_sonic_portchannel_lag_table': path = cc.Path('/restconf/data/sonic-portchannel:sonic-portchannel/LAG_TABLE') return api.get(path) if func == 'get_sonic_portchannel_sonic_portchannel_lag_member_table': path = cc.Path('/restconf/data/sonic-portchannel:sonic-portchannel/LAG_MEMBER_TABLE') return api.get(path) if func == 'get_sonic_port_sonic_port_port_table_port_table_list_oper_status': path = cc.Path('/restconf/data/sonic-port:sonic-port/PORT_TABLE/PORT_TABLE_LIST={ifname}/oper_status', ifname=args[0]) return api.get(path) return api.cli_not_implemented(func)
def get_unicast_table(aa, instance_num, port_num): tmp_keypath = cc.Path( '/restconf/data/ietf-ptp:ptp/instance-list={instance_number}', instance_number=instance_num) tmp_response = aa.get(tmp_keypath) if tmp_response is None: return 0, "None" found = 0 if tmp_response.ok(): response = tmp_response.content if response is not None and response != {}: for i in response['ietf-ptp:instance-list']: if 'port-ds-list' in i: for j in i['port-ds-list']: if 'port-number' in j: if j['port-number'] == int(port_num): found = 1 if 'ietf-ptp-ext:unicast-table' in j: if j['ietf-ptp-ext:unicast-table'] == '': return found, "None" else: return found, j[ 'ietf-ptp-ext:unicast-table'] return found, "None"
def set_link_state_tracking_group_downstream(args): aa = cc.ApiClient() uri = cc.Path( '/restconf/data/sonic-link-state-tracking:sonic-link-state-tracking/INTF_TRACKING/INTF_TRACKING_LIST={grp_name}/downstream', grp_name=args[0]) body = {"sonic-link-state-tracking:downstream": args[1:]} return aa.patch(uri, body)
def get_sonic_tacacs_server_api(args): api_response = [] api = cc.ApiClient() path = cc.Path( '/restconf/data/openconfig-system:system/aaa/server-groups/server-group=TACACS/servers/', address=args[0]) response = api.get(path) if response.ok(): if response.content: server_list = response.content["openconfig-system:servers"][ "server"] for i in range(len(server_list)): if args[0] == server_list[i]['address'] or args[ 0] == 'show_tacacs_server.j2': api_response_data = {} api_response_data['address'] = server_list[i]['address'] api_response_data['authtype'] = server_list[i]['config'][ 'openconfig-system-ext:auth-type'] api_response_data['priority'] = server_list[i]['config'][ 'openconfig-system-ext:priority'] api_response_data['timeout'] = server_list[i]['config'][ 'timeout'] if 'tacacs' in server_list[i]: tac_cfg = {} tac_cfg = server_list[i]['tacacs']['config'] api_response_data['port'] = tac_cfg['port'] if "secret-key" in tac_cfg: api_response_data['key'] = tac_cfg['secret-key'] api_response.append(api_response_data) return api_response
def delete_link_state_tracking_group_downstream(args): aa = cc.ApiClient() uri = cc.Path( '/restconf/data/sonic-link-state-tracking:sonic-link-state-tracking/INTF_TRACKING/INTF_TRACKING_LIST={grp_name}/downstream={downstr}', grp_name=args[0], downstr=args[1]) return aa.delete(uri)
def build_mac_list(): global macDict keypath = cc.Path( '/restconf/data/openconfig-network-instance:network-instances/network-instance={name}/fdb/mac-table/entries', name='default') try: response = aa.get(keypath) response = response.content macContainer = response.get('openconfig-network-instance:entries') macList = macContainer.get('entry') for macEntry in macList: vlan = macEntry.get('vlan') if vlan is None: continue mac = macEntry.get('mac-address') if mac is None: continue intf = macEntry.get('interface').get('interface-ref').get( 'state').get('interface') if intf is None: continue key = "Vlan" + str(vlan) + "-" + mac macDict[key] = intf except: print "%Error: Internal error"
def fdb_call(macAddr, vlanName): aa = cc.ApiClient() vlanId = vlanName[len("Vlan"):] macAddr = macAddr.strip() keypath = cc.Path( '/restconf/data/openconfig-network-instance:network-instances/network-instance={name}/fdb/mac-table/entries/entry={macaddress},{vlan}', name='default', macaddress=macAddr, vlan=vlanId) try: response = aa.get(keypath) response = response.content if 'openconfig-network-instance:entry' in response.keys(): instance = response['openconfig-network-instance:entry'][0][ 'interface']['interface-ref']['state']['interface'] if instance is not None: return instance return "-" except: return "-"
def invoke_api(func, args=[]): if func == 'get_sonic_vlan_sonic_vlan': path = cc.Path('/restconf/data/sonic-vlan:sonic-vlan') return api.get(path) if func == 'get_sonic_vxlan_sonic_vxlan_suppress_vlan_neigh': path = cc.Path('/restconf/data/sonic-vxlan:sonic-vxlan') return api.get(path) if func == 'get_sonic_vxlan_remote_vni': path = cc.Path( '/restconf/data/sonic-vxlan:sonic-vxlan/EVPN_REMOTE_VNI_TABLE/EVPN_REMOTE_VNI_TABLE_LIST' ) return api.get(path) return api.cli_not_implemented(func)
def invoke_api(func, args=[]): api = cc.ApiClient() keypath = [] body = None keypath = cc.Path('/restconf/data/sonic-sag:sonic-sag/SAG/SAG_LIST') res = api.get(keypath) output["sag"] = res.content keypath = cc.Path( '/restconf/data/sonic-sag:sonic-sag/SAG_GLOBAL/SAG_GLOBAL_LIST') res = api.get(keypath) output["global"] = res.content if func == 'get_ip_sag': output["family"] = "IPv4" else: output["family"] = "IPv6" return output
def invoke_api(func, args=[]): api = cc.ApiClient() if func == 'get_sonic_vlan_sonic_vlan': path = cc.Path('/restconf/data/sonic-vlan:sonic-vlan') return api.get(path) return api.cli_not_implemented(func)
def run(func, args): aa = cc.ApiClient() path = cc.Path('/restconf/data/openconfig-platform:components/component=%s'%args[0]) response = aa.get(path) if response.ok(): show_cli_output(sys.argv[3], response.content) else: print response.error_message()
def invoke_api(func, args): body = None prefix="" vrfname="default" api = cc.ApiClient() if len(args) < 4: print("Invalid arguments") return try: id = args.index("route") except ValueError: print("Invalid arguments") return args = args[id+1:] if len(args) < 2: vrfname = "default" if len(args) == 1: prefix = args[0] elif len(args) < 4: vrfname = args[1] if len(args) == 3: prefix = args[2] if func == 'get_network_instance_afts_ipv4_unicast': if len(prefix) > 0: keypath = cc.Path('/restconf/data/openconfig-network-instance:network-instances/network-instance={name}'\ '/afts/ipv4-unicast/ipv4-entry={prfxKey}',name=vrfname, prfxKey=prefix) else: keypath = cc.Path('/restconf/data/openconfig-network-instance:network-instances/network-instance={name}'\ '/afts/ipv4-unicast',name=vrfname) return api.get(keypath) elif func == 'get_network_instance_afts_ipv6_unicast': if len(prefix) > 0: keypath = cc.Path('/restconf/data/openconfig-network-instance:network-instances/network-instance={name}'\ '/afts/ipv6-unicast/ipv6-entry={prfxKey}',name=vrfname, prfxKey=prefix) else: keypath = cc.Path('/restconf/data/openconfig-network-instance:network-instances/network-instance={name}'\ '/afts/ipv6-unicast',name=vrfname) return api.get(keypath)
def generate_aspath_delete_keypath(args): paths_exits = 0 paths = '' for arg in args[1:]: paths_exits = 1 paths += arg paths += "," if paths_exits: paths = paths[:-1] keypath = cc.Path( '/restconf/data/openconfig-routing-policy:routing-policy/defined-sets/openconfig-bgp-policy:bgp-defined-sets/as-path-sets/as-path-set={as_path_set_name}/config/as-path-set-member={path}', as_path_set_name=args[0], path=paths) else: keypath = cc.Path( '/restconf/data/openconfig-routing-policy:routing-policy/defined-sets/openconfig-bgp-policy:bgp-defined-sets/as-path-sets/as-path-set={as_path_set_name}', as_path_set_name=args[0]) return keypath
def generate_extcommunity_expanded_delete_keypath(args): member_exits = 0 community_member = '' for arg in args[6:]: member_exits = 1 community_member += "REGEX:" + arg community_member += "," if member_exits: community_member = community_member[:-1] keypath = cc.Path( '/restconf/data/openconfig-routing-policy:routing-policy/defined-sets/openconfig-bgp-policy:bgp-defined-sets/ext-community-sets/ext-community-set={community_list_name}/config/ext-community-member={members}', community_list_name=args[5], members=community_member) else: keypath = cc.Path( '/restconf/data/openconfig-routing-policy:routing-policy/defined-sets/openconfig-bgp-policy:bgp-defined-sets/ext-community-sets/ext-community-set={community_list_name}', community_list_name=args[5]) return keypath
def invoke(func, args): body = None aa = cc.ApiClient() keypath = cc.Path('/restconf/operations/sonic-config-mgmt:copy') body = { "sonic-config-mgmt:input":{"source":args[0], "destination":args[1]}} if len(args) == 3: body["sonic-config-mgmt:input"].update({"overwrite":True}) return aa.post(keypath, body)
def get_sonic_radius_global(): api_response = {} api = cc.ApiClient() path = cc.Path(RADIUS_SERVER_GROUP + 'config') response = api.get(path) if response.ok(): if response.content: api_response = response.content show_cli_output("show_radius_global.j2", api_response)
def set_link_state_tracking_group_timeout(args): timeout = int(args[1]) if timeout > 999: raise RuntimeError("Timeout not in range 1-999") aa = cc.ApiClient() uri = cc.Path( '/restconf/data/sonic-link-state-tracking:sonic-link-state-tracking/INTF_TRACKING/INTF_TRACKING_LIST={grp_name}/timeout', grp_name=args[0]) body = {"sonic-link-state-tracking:timeout": timeout} return aa.patch(uri, body)