diff --git a/config/transformer/models_list b/config/transformer/models_list index 89ba79e9c..38fc5d007 100644 --- a/config/transformer/models_list +++ b/config/transformer/models_list @@ -11,3 +11,9 @@ openconfig-if-aggregate.yang openconfig-mclag.yang openconfig-mclag-annot.yang openconfig-vlan.yang +openconfig-system.yang +openconfig-system-annot.yang +openconfig-system-terminal.yang +openconfig-messages.yang +openconfig-system-logging.yang +openconfig-aaa.yang diff --git a/go.mod b/go.mod index 65d97ab43..a111adf7f 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/pkg/profile v1.7.0 golang.org/x/text v0.3.3 google.golang.org/grpc v1.28.0 + gopkg.in/yaml.v2 v2.2.1 inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a ) diff --git a/go.sum b/go.sum index d53532d67..5166e6605 100644 --- a/go.sum +++ b/go.sum @@ -109,7 +109,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= @@ -163,6 +162,7 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.20.1/go.mod h1:KqelGeouBkcbcuB3HCk4/YH2tmNLk6YSWA5LIWeI/lY= google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -175,6 +175,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -inet.af v0.0.0-20181218191229-53da77bc832c h1:U3RoiyEF5b3Y1SVL6NNvpkgqUz2qS3a0OJh9kpSCN04= inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a h1:1XCVEdxrvL6c0TGOhecLuB7U9zYNdxZEjvOqJreKZiM= inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a/go.mod h1:e83i32mAQOW1LAqEIweALsuK2Uw4mhQadA5r7b0Wobo= diff --git a/models/yang/annotations/openconfig-system-annot.yang b/models/yang/annotations/openconfig-system-annot.yang new file mode 100644 index 000000000..a75faa401 --- /dev/null +++ b/models/yang/annotations/openconfig-system-annot.yang @@ -0,0 +1,660 @@ +module openconfig-system-annot { + yang-version "1"; + namespace "http:/openconfig.net/yang/system/annotation"; + prefix "oc-sys-annot"; + + import sonic-extensions { prefix sonic-ext; } + + import openconfig-extensions { prefix oc-ext; } + + import openconfig-system { prefix oc-sys; } + + organization "SONiC Manageability"; + contact "SONiC"; + + description + "Annotations for openconfig-system model."; + + oc-ext:openconfig-version "0.5.0"; + + revision "2024-09-20" { + description + "Adding support for AAA - authentication,authorization & accounting login method"; + reference + "0.5.0"; + } + + revision "2024-09-13" { + description + "Adding support for dns container"; + reference + "0.4.0"; + } + + revision "2024-09-02" { + description + "Added support for ntp container"; + reference + "0.3.0"; + } + + revision "2024-08-12" { + description + "Added support for login,motd banners & timezone"; + reference + "0.2.0"; + } + + revision "2024-05-02" { + description + "Initial version"; + reference + "0.1.0"; + } + + + deviation /oc-sys:system { + deviate add { + sonic-ext:post-transformer "system_post_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:config { + deviate add { + sonic-ext:virtual-table "true"; + } + } + + deviation /oc-sys:system/oc-sys:config/oc-sys:hostname { + deviate add { + sonic-ext:table-name "DEVICE_METADATA"; + sonic-ext:key-name "localhost"; + } + } + + deviation /oc-sys:system/oc-sys:config/oc-sys:login-banner { + deviate add { + sonic-ext:table-name "BANNER_MESSAGE"; + sonic-ext:key-name "global"; + sonic-ext:field-name "login"; + } + } + + deviation /oc-sys:system/oc-sys:config/oc-sys:motd-banner { + deviate add { + sonic-ext:table-name "BANNER_MESSAGE"; + sonic-ext:key-name "global"; + sonic-ext:field-name "motd"; + } + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:hostname { + deviate add { + sonic-ext:field-transformer "sys_not_implemented_leaf_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:login-banner { + deviate add { + sonic-ext:field-transformer "sys_not_implemented_leaf_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:motd-banner { + deviate add { + sonic-ext:field-transformer "sys_not_implemented_leaf_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:current-datetime { + deviate add { + sonic-ext:field-transformer "sys_current_datetime_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:up-time { + deviate add { + sonic-ext:field-transformer "sys_up_time_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:boot-time { + deviate add { + sonic-ext:field-transformer "sys_boot_time_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:software-version { + deviate add { + sonic-ext:field-transformer "sys_software_version_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:clock { + deviate add { + sonic-ext:table-name "DEVICE_METADATA"; + sonic-ext:key-name "localhost"; + } + } + + deviation /oc-sys:system/oc-sys:clock/oc-sys:config/oc-sys:timezone-name { + deviate add { + sonic-ext:field-name "timezone"; + sonic-ext:field-transformer "sys_clock_timezone_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:clock/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process { + deviate add { + sonic-ext:db-name "STATE_DB"; + sonic-ext:table-name "PROCESS_STATS"; + sonic-ext:key-transformer "sys_proc_pid_key_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:pid { + deviate add { + sonic-ext:field-transformer "sys_proc_pid_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:pid { + deviate add { + sonic-ext:field-transformer "sys_proc_pid_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:name { + deviate add { + sonic-ext:field-name "CMD"; + sonic-ext:field-transformer "sys_proc_name_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:args { + deviate add { + sonic-ext:field-name "CMD"; + sonic-ext:field-transformer "sys_proc_args_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:cpu-utilization { + deviate add { + sonic-ext:field-name "%CPU"; + sonic-ext:field-transformer "sys_process_cpu_utilization_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:memory-utilization { + deviate add { + sonic-ext:field-name "%MEM"; + sonic-ext:field-transformer "sys_process_mem_utilization_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ssh-server { + deviate add { + sonic-ext:table-name "SSH_SERVER"; + sonic-ext:key-name "POLICIES"; + } + } + + deviation /oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:timeout { + deviate add { + sonic-ext:field-name "login_timeout"; + sonic-ext:field-transformer "sys_ssh_timeout_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ssh-server/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server { + deviate add { + sonic-ext:table-name "SYSLOG_SERVER"; + sonic-ext:key-transformer "sys_logging_remote_server_key_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:host { + deviate add { + sonic-ext:field-name "server_address"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:config/oc-sys:host { + deviate add { + sonic-ext:field-name "server_address"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:config/oc-sys:source-address { + deviate add { + sonic-ext:field-name "source"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:config/oc-sys:network-instance { + deviate add { + sonic-ext:field-name "vrf"; + sonic-ext:field-transformer "sys_logging_vrf_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:config/oc-sys:remote-port { + deviate add { + sonic-ext:field-name "port"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:selectors/oc-sys:selector { + deviate add { + sonic-ext:table-name "SYSLOG_SERVER"; + sonic-ext:key-transformer "sys_logging_selector_key_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:selectors/oc-sys:selector/oc-sys:facility { + deviate add { + sonic-ext:field-transformer "sys_logging_selector_facility_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:selectors/oc-sys:selector/oc-sys:severity { + deviate add { + sonic-ext:field-transformer "sys_logging_selector_severity_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:selectors/oc-sys:selector/oc-sys:config/oc-sys:facility { + deviate add { + sonic-ext:field-transformer "sys_logging_selector_facility_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:selectors/oc-sys:selector/oc-sys:config/oc-sys:severity { + deviate add { + sonic-ext:field-transformer "sys_logging_selector_severity_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:remote-servers/oc-sys:remote-server/oc-sys:selectors/oc-sys:selector/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:messages/oc-sys:config { + deviate add { + sonic-ext:table-name "SYSLOG_CONFIG"; + sonic-ext:key-name "GLOBAL"; + } + } + + deviation /oc-sys:system/oc-sys:messages/oc-sys:config/oc-sys:severity { + deviate add { + sonic-ext:field-transformer "sys_msgs_severity_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:messages/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:config { + deviate add { + sonic-ext:table-name "NTP"; + sonic-ext:key-name "global"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:config/oc-sys:enabled { + deviate add { + sonic-ext:field-name "admin_state"; + sonic-ext:field-transformer "sys_ntp_config_enabled_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:config/oc-sys:enable-ntp-auth { + deviate add { + sonic-ext:field-name "authentication"; + sonic-ext:field-transformer "sys_ntp_config_enable_auth_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:ntp-keys/oc-sys:ntp-key { + deviate add { + sonic-ext:table-name "NTP_KEY"; + sonic-ext:key-transformer "sys_ntp_key_key_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:ntp-keys/oc-sys:ntp-key/oc-sys:key-id { + deviate add { + sonic-ext:field-name "id"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:ntp-keys/oc-sys:ntp-key/oc-sys:config/oc-sys:key-id { + deviate add { + sonic-ext:field-name "id"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:ntp-keys/oc-sys:ntp-key/oc-sys:config/oc-sys:key-type { + deviate add { + sonic-ext:field-name "type"; + sonic-ext:field-transformer "sys_ntp_key_type_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:ntp-keys/oc-sys:ntp-key/oc-sys:config/oc-sys:key-value { + deviate add { + sonic-ext:field-name "value"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:ntp-keys/oc-sys:ntp-key/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server { + deviate add { + sonic-ext:table-name "NTP_SERVER"; + sonic-ext:key-transformer "sys_ntp_server_key_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:address { + deviate add { + sonic-ext:field-name "server_address"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:address { + deviate add { + sonic-ext:field-name "server_address"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:association-type { + deviate add { + sonic-ext:field-name "association_type"; + sonic-ext:field-transformer "sys_ntp_server_association_type_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:iburst { + deviate add { + sonic-ext:field-transformer "sys_ntp_server_iburst_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:network-instance { + deviate add { + sonic-ext:field-transformer "sys_ntp_server_vrf_xfmr"; + sonic-ext:table-name "NTP"; + sonic-ext:key-name "global"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:source-address { + deviate add { + sonic-ext:field-transformer "sys_ntp_server_source_address_xfmr"; + sonic-ext:table-name "NTP"; + sonic-ext:key-name "global"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:key-id { + deviate add { + sonic-ext:field-name "key"; + } + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:dns/oc-sys:config { + deviate add { + sonic-ext:table-name "DNS_NAMESERVER"; + sonic-ext:subtree-transformer "sys_dns_config_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:dns/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa { + deviate add { + sonic-ext:table-name "AAA"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authentication { + deviate add { + sonic-ext:table-name "AAA"; + sonic-ext:key-name "authentication"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authentication/oc-sys:config/oc-sys:authentication-method { + deviate add { + sonic-ext:field-transformer "sys_aaa_authentication_method_xfmr"; + sonic-ext:field-name "login"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authentication/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authorization { + deviate add { + sonic-ext:table-name "AAA"; + sonic-ext:key-name "authorization"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authorization/oc-sys:config/oc-sys:authorization-method { + deviate add { + sonic-ext:field-transformer "sys_aaa_authorization_method_xfmr"; + sonic-ext:field-name "login"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authorization/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:accounting { + deviate add { + sonic-ext:table-name "AAA"; + sonic-ext:key-name "accounting"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:accounting/oc-sys:config/oc-sys:accounting-method { + deviate add { + sonic-ext:field-transformer "sys_aaa_accounting_method_xfmr"; + sonic-ext:field-name "login"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:accounting/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups { + deviate add { + sonic-ext:table-name "NONE"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group { + deviate add { + sonic-ext:table-transformer "sys_aaa_server_groups_table_xfmr"; + sonic-ext:key-transformer "sys_aaa_server_group_name_key_xfmr"; + sonic-ext:virtual-table "true"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:config/oc-sys:name { + deviate add { + sonic-ext:field-transformer "sys_aaa_server_group_name_field_xfmr"; + sonic-ext:field-name "name"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:config/oc-sys:type { + deviate add { + sonic-ext:field-transformer "sys_aaa_server_group_type_field_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:state/oc-sys:name { + deviate add { + sonic-ext:field-transformer "sys_aaa_server_group_name_field_xfmr"; + sonic-ext:field-name "name"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:state/oc-sys:type { + deviate add { + sonic-ext:field-transformer "sys_aaa_server_group_type_field_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers { + deviate add { + sonic-ext:table-name "NONE"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server { + deviate add { + sonic-ext:table-transformer "sys_aaa_server_table_xfmr"; + sonic-ext:key-transformer "sys_aaa_server_groups_address_key_xfmr"; + sonic-ext:virtual-table "true"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:name { + deviate add { + sonic-ext:field-transformer "sys_aaa_server_name_field_xfmr"; + sonic-ext:field-name "name"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:address { + deviate add { + sonic-ext:field-name "ipaddress"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:timeout { + deviate add { + sonic-ext:field-name "timeout"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:tacacs/oc-sys:config/oc-sys:port { + deviate add { + sonic-ext:field-name "tcp_port"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:tacacs/oc-sys:config/oc-sys:secret-key { + deviate add { + sonic-ext:field-name "passkey"; + sonic-ext:field-transformer "aaa_server_secret_key_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:tacacs/oc-sys:config/oc-sys:source-address { + deviate add { + sonic-ext:field-transformer "aaa_sys_source_address_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:tacacs/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:config/oc-sys:auth-port { + deviate add { + sonic-ext:field-name "auth_port"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:config/oc-sys:secret-key { + deviate add { + sonic-ext:field-name "passkey"; + sonic-ext:field-transformer "aaa_server_secret_key_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:config/oc-sys:source-address { + deviate add { + sonic-ext:field-transformer "aaa_sys_source_address_xfmr"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:config/oc-sys:retransmit-attempts { + deviate add { + sonic-ext:field-name "retransmit"; + } + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:state { + deviate add { + sonic-ext:subtree-transformer "sys_not_implemented_container_err_xfmr"; + } + } + +} \ No newline at end of file diff --git a/models/yang/annotations/sonic-extensions.yang b/models/yang/annotations/sonic-extensions.yang index f77bc9311..f00e9d381 100644 --- a/models/yang/annotations/sonic-extensions.yang +++ b/models/yang/annotations/sonic-extensions.yang @@ -18,6 +18,11 @@ module sonic-extensions { "This module provides extensions to the YANG language to allow Sonic specific functionality and meta-data to be defined."; + revision "2024-08-05" { + description + "Added missing key-name extension for redis DB mappings to identify the Redis DB name."; + } + revision "2019-08-30" { description "Add extensions for redis DB mappings to identify the Redis DB name."; @@ -128,4 +133,10 @@ module sonic-extensions { description "To mention the name of the path transformer which is to resolve the yang uri by filling the yang keys in the path using the db table key information"; } + + extension key-name { + argument "key-name"; + description "Fixed key name, used for YANG container mapped to TABLE with a fixed key, processed by the default + transformer method. Used to define a fixed key, mainly for container mapped to TABLE key"; + } } diff --git a/models/yang/extensions/openconfig-system-deviation.yang b/models/yang/extensions/openconfig-system-deviation.yang new file mode 100644 index 000000000..7354823bc --- /dev/null +++ b/models/yang/extensions/openconfig-system-deviation.yang @@ -0,0 +1,228 @@ +module openconfig-system-deviation { + yang-version "1"; + namespace "http://openconfig.net/yang/system/deviation"; + prefix "oc-sys-deviate"; + + import openconfig-extensions { prefix oc-ext; } + + import openconfig-system { prefix oc-sys; } + + import openconfig-system-utilization { prefix oc-sys-util; } + + import openconfig-system-grpc { prefix oc-sys-grpc; } + + import openconfig-hashing { prefix oc-hash; } + + import openconfig-system-bootz { prefix oc-sys-bootz; } + + import openconfig-interfaces { prefix oc-intf; } + + organization "SONiC Manageability"; + contact "SONiC"; + + description + "Deviations for openconfig-system model."; + + oc-ext:openconfig-version "0.5.0"; + + revision "2024-09-20" { + description + "Adding support for AAA - authentication,authorization & accounting login method"; + reference + "0.5.0"; + } + + revision "2024-09-13" { + description + "Adding support for dns container"; + reference + "0.4.0"; + } + + revision "2024-09-02" { + description + "Added support for ntp container"; + reference + "0.3.0"; + } + + revision "2024-08-12" { + description + "Added support for login,motd banners & timezone"; + reference + "0.2.0"; + } + + revision "2024-05-02" { + description + "Initial version"; + reference + "0.1.0"; + } + + + deviation /oc-sys:system/oc-sys:config/oc-sys:domain-name { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:domain-name { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:state/oc-sys:last-configuration-timestamp { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:start-time { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:cpu-usage-user { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:cpu-usage-system { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:processes/oc-sys:process/oc-sys:state/oc-sys:memory-usage { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:enable { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:protocol-version { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:rate-limit { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:ssh-server/oc-sys:config/oc-sys:session-limit { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:telnet-server { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:console { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:files { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:logging/oc-sys:vty { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:messages/oc-sys:debug-entries { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:memory { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:cpus { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:port { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:ntp/oc-sys:servers/oc-sys:server/oc-sys:config/oc-sys:prefer { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:dns/oc-sys:servers { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:dns/oc-sys:host-entries { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:config { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:state { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authentication/oc-sys:admin-user { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authentication/oc-sys:users { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:authorization/oc-sys:events { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:accounting/oc-sys:events { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:tacacs/oc-sys:config/oc-sys:secret-key-hashed { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:config/oc-sys:acct-port { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:aaa/oc-sys:server-groups/oc-sys:server-group/oc-sys:servers/oc-sys:server/oc-sys:radius/oc-sys:config/oc-sys:secret-key-hashed { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:alarms { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:mount-points { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:license { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys:mac-address { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys-grpc:grpc-servers { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys-util:utilization { + deviate not-supported; + } + + deviation /oc-sys:system/oc-hash:hashing { + deviate not-supported; + } + + deviation /oc-sys:system/oc-sys-bootz:bootz { + deviate not-supported; + } + + deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:config/oc-hash:hashing-policy { + deviate not-supported; + } + + deviation /oc-intf:interfaces/oc-intf:interface/oc-intf:state/oc-hash:hashing-policy { + deviate not-supported; + } + +} \ No newline at end of file diff --git a/models/yang/sonic/import.mk b/models/yang/sonic/import.mk index e28360c30..061509339 100644 --- a/models/yang/sonic/import.mk +++ b/models/yang/sonic/import.mk @@ -5,6 +5,11 @@ # or glob patterns of basenames (like sonic-telemetry*.yang) can be specified. # Other sonic yangs referred by these will also be copied. # + +ifneq ($(SONIC_YANG_IMPORTS),) +SONICYANG_IMPORTS = $(shell echo $(SONIC_YANG_IMPORTS)) +endif + SONICYANG_IMPORTS += sonic-sflow.yang SONICYANG_IMPORTS += sonic-interface.yang SONICYANG_IMPORTS += sonic-port.yang @@ -12,4 +17,15 @@ SONICYANG_IMPORTS += sonic-portchannel.yang SONICYANG_IMPORTS += sonic-vlan.yang SONICYANG_IMPORTS += sonic-mclag.yang SONICYANG_IMPORTS += sonic-types.yang -SONICYANG_IMPORTS += sonic-vrf.yang \ No newline at end of file +SONICYANG_IMPORTS += sonic-vrf.yang +SONICYANG_IMPORTS += sonic-mgmt_vrf.yang +SONICYANG_IMPORTS += sonic-device_metadata.yang +SONICYANG_IMPORTS += sonic-banner.yang +SONICYANG_IMPORTS += sonic-versions.yang +SONICYANG_IMPORTS += sonic-ssh-server.yang +SONICYANG_IMPORTS += sonic-syslog.yang +SONICYANG_IMPORTS += sonic-ntp.yang +SONICYANG_IMPORTS += sonic-dns.yang +SONICYANG_IMPORTS += sonic-system-aaa.yang +SONICYANG_IMPORTS += sonic-system-tacacs.yang +SONICYANG_IMPORTS += sonic-system-radius.yang diff --git a/translib/pfm_app.go b/translib/pfm_app.go index f2dab02a3..09e676973 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -29,6 +29,13 @@ import ( "strconv" ) +type reqType int + +type dbEntry struct { + op reqType + entry db.Value +} + type PlatformApp struct { path *PathInfo reqData []byte diff --git a/translib/request_binder_test.go b/translib/request_binder_test.go index 55ba2f9c0..8ece8f729 100644 --- a/translib/request_binder_test.go +++ b/translib/request_binder_test.go @@ -185,27 +185,13 @@ func TestUnMarshallUri(t *testing.T) { want: "rpc error: code = InvalidArgument desc = no match found in *ocbinds.OpenconfigAcl_Acl_AclSets_AclSet_State, for path elem:{name:\"descriptXX\"}", }, { tid: 10, - uri: "openconfig-system:system/cpus/cpu[index=3]/", - opcode: 1, - payload: []byte{}, - appRootType: reflect.TypeOf(ocbinds.OpenconfigSystem_System{}), - want: "OpenconfigSystem_System_Cpus_Cpu", - }, { - tid: 11, - uri: "openconfig-system:system/cpus/cpu[index=ALL]/", - opcode: 1, - payload: []byte{}, - appRootType: reflect.TypeOf(ocbinds.OpenconfigSystem_System{}), - want: "OpenconfigSystem_System_Cpus_Cpu", - }, { - tid: 12, uri: "", opcode: 1, payload: []byte{}, appRootType: reflect.TypeOf(ocbinds.OpenconfigSystem_System{}), want: "Error: URI is empty", }, { - tid: 13, + tid: 11, uri: "openconfig-acl:acl/acl-sets/acl-set[name=Sample][type=ACL_IPV4]/", opcode: 3, payload: []byte{}, @@ -249,31 +235,6 @@ func TestUnMarshallUri(t *testing.T) { } else { t.Error("Error in unmarshalling the URI: OpenconfigAcl_Acl_AclSets_AclSet_AclEntries_AclEntry object casting failed") } - } else if tt.tid == 10 { - cpuObj, ok := (*workObj).(*ocbinds.OpenconfigSystem_System_Cpus_Cpu) - if ok == false { - t.Error("Error in unmarshalling the URI: OpenconfigSystem_System_Cpus_Cpu failed") - } - val := cpuObj.Index.(*ocbinds.OpenconfigSystem_System_Cpus_Cpu_State_Index_Union_Uint32) - cIdx, _ := cpuObj.To_OpenconfigSystem_System_Cpus_Cpu_State_Index_Union(uint32(3)) - val2 := cIdx.(*ocbinds.OpenconfigSystem_System_Cpus_Cpu_State_Index_Union_Uint32) - if *val != *val2 { - t.Error("Error in unmarshalling the URI: OpenconfigSystem_System_Cpus_Cpu failed") - } - } else if tt.tid == 11 { - cpuObj, ok := (*workObj).(*ocbinds.OpenconfigSystem_System_Cpus_Cpu) - if ok == false { - t.Error("Error in unmarshalling the URI: OpenconfigSystem_System_Cpus_Cpu failed") - } - val := cpuObj.Index.(*ocbinds.OpenconfigSystem_System_Cpus_Cpu_State_Index_Union_E_OpenconfigSystem_System_Cpus_Cpu_State_Index) - cIdx, err := cpuObj.To_OpenconfigSystem_System_Cpus_Cpu_State_Index_Union(ocbinds.E_OpenconfigSystem_System_Cpus_Cpu_State_Index(1)) - if err != nil { - t.Errorf("Error in unmarshalling the URI: OpenconfigSystem_System_Cpus_Cpu failed %s", fmt.Sprint(err)) - } - val2 := cIdx.(*ocbinds.OpenconfigSystem_System_Cpus_Cpu_State_Index_Union_E_OpenconfigSystem_System_Cpus_Cpu_State_Index) - if *val != *val2 { - t.Error("Error in unmarshalling the URI: OpenconfigSystem_System_Cpus_Cpu failed") - } } else if reflect.TypeOf(*workObj).Elem().Name() != tt.want { t.Error("Error in unmarshalling the URI: Invalid target node: ", reflect.TypeOf(*workObj).Elem().Name()) } diff --git a/translib/sys_app.go b/translib/sys_app.go deleted file mode 100644 index ccc48a3ae..000000000 --- a/translib/sys_app.go +++ /dev/null @@ -1,353 +0,0 @@ -////////////////////////////////////////////////////////////////////////// -// -// Copyright 2024 Dell, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -////////////////////////////////////////////////////////////////////////// - -package translib - -import ( - "errors" - "reflect" - "strconv" - - "github.com/Azure/sonic-mgmt-common/translib/db" - "github.com/Azure/sonic-mgmt-common/translib/ocbinds" - "github.com/Azure/sonic-mgmt-common/translib/tlerr" - log "github.com/golang/glog" - "github.com/openconfig/ygot/ygot" -) - -type SysApp struct { - path *PathInfo - reqData []byte - ygotRoot *ygot.GoStruct - ygotTarget *interface{} - - dockerTs *db.TableSpec - procTs *db.TableSpec - - dockerTable map[string]dbEntry - procTable map[uint64]dbEntry -} - -type reqType int - -type dbEntry struct { - op reqType - entry db.Value -} - -func init() { - log.Info("SysApp: Init called for System module") - err := register("/openconfig-system:system", - &appInfo{appType: reflect.TypeOf(SysApp{}), - ygotRootType: reflect.TypeOf(ocbinds.OpenconfigSystem_System{}), - isNative: false}) - if err != nil { - log.Fatal("SysApp: Register System app module with App Interface failed with error=", err) - } - - err = addModel(&ModelData{Name: "openconfig-system", - Org: "OpenConfig working group", - Ver: "1.0.2"}) - if err != nil { - log.Fatal("SysApp: Adding model data to appinterface failed with error=", err) - } -} - -func (app *SysApp) initialize(data appData) { - log.Info("SysApp: initialize:if:path =", data.path) - - app.path = NewPathInfo(data.path) - app.reqData = data.payload - app.ygotRoot = data.ygotRoot - app.ygotTarget = data.ygotTarget - - app.dockerTs = &db.TableSpec{Name: "DOCKER_STATS"} - app.procTs = &db.TableSpec{Name: "PROCESS_STATS"} -} - -func (app *SysApp) getAppRootObject() *ocbinds.OpenconfigSystem_System { - deviceObj := (*app.ygotRoot).(*ocbinds.Device) - return deviceObj.System -} - -func (app *SysApp) translateAction(dbs [db.MaxDB]*db.DB) error { - err := errors.New("Not supported") - return err -} - -func (app *SysApp) translateSubscribe(req translateSubRequest) (translateSubResponse, error) { - return emptySubscribeResponse(req.path) -} - -func (app *SysApp) processSubscribe(req processSubRequest) (processSubResponse, error) { - return processSubResponse{}, tlerr.New("not implemented") -} - -func (app *SysApp) translateCreate(d *db.DB) ([]db.WatchKeys, error) { - var err error - var keys []db.WatchKeys - - err = errors.New("SysApp Not implemented, translateCreate") - return keys, err -} - -func (app *SysApp) translateUpdate(d *db.DB) ([]db.WatchKeys, error) { - var err error - var keys []db.WatchKeys - err = errors.New("SysApp Not implemented, translateUpdate") - return keys, err -} - -func (app *SysApp) translateReplace(d *db.DB) ([]db.WatchKeys, error) { - var err error - var keys []db.WatchKeys - err = errors.New("Not implemented SysApp translateReplace") - return keys, err -} - -func (app *SysApp) translateDelete(d *db.DB) ([]db.WatchKeys, error) { - var err error - var keys []db.WatchKeys - - err = errors.New("Not implemented SysApp translateDelete") - return keys, err -} - -func (app *SysApp) translateGet(dbs [db.MaxDB]*db.DB) error { - var err error - log.Info("SysApp: translateGet:intf:path =", app.path) - return err -} - -func (app *SysApp) processCreate(d *db.DB) (SetResponse, error) { - var err error - var resp SetResponse - - err = errors.New("Not implemented SysApp processCreate") - return resp, err -} - -func (app *SysApp) processUpdate(d *db.DB) (SetResponse, error) { - var err error - var resp SetResponse - - err = errors.New("Not implemented SysApp processUpdate") - return resp, err -} - -func (app *SysApp) processReplace(d *db.DB) (SetResponse, error) { - var err error - var resp SetResponse - err = errors.New("Not implemented, SysApp processReplace") - return resp, err -} - -func (app *SysApp) processDelete(d *db.DB) (SetResponse, error) { - var err error - var resp SetResponse - - err = errors.New("Not implemented SysApp processDelete") - return resp, err -} - -type ProcessState struct { - Args []string - CpuUsageSystem uint64 - CpuUsageUser uint64 - CpuUtilization uint8 - MemoryUsage uint64 - MemoryUtilization uint8 - Name string - Pid uint64 - StartTime uint64 -} - -func (app *SysApp) getSystemProcess(sysproc *ocbinds.OpenconfigSystem_System_Processes_Process, pid uint64) { - - log.Info("getSystemProcess pid=", pid) - - e := app.procTable[pid].entry - - var procstate ProcessState - - procstate.CpuUsageUser = 0 - procstate.CpuUsageSystem = 0 - procstate.MemoryUsage = 0 - f, _ := strconv.ParseFloat(e.Get("%MEM"), 32) - procstate.MemoryUtilization = uint8(f) - f, _ = strconv.ParseFloat(e.Get("%CPU"), 32) - procstate.CpuUtilization = uint8(f) - procstate.Name = e.Get("CMD") - procstate.Pid = pid - procstate.StartTime = 0 - - targetUriPath, perr := getYangPathFromUri(app.path.Path) - if perr != nil { - log.Infof("getYangPathFromUri failed.") - return - } - - ygot.BuildEmptyTree(sysproc) - - switch targetUriPath { - - case "/openconfig-system:system/processes/process/state/name": - sysproc.State.Name = &procstate.Name - case "/openconfig-system:system/processes/process/state/args": - case "/openconfig-system:system/processes/process/state/start-time": - sysproc.State.StartTime = &procstate.StartTime - case "/openconfig-system:system/processes/process/state/cpu-usage-user": - sysproc.State.CpuUsageUser = &procstate.CpuUsageUser - case "/openconfig-system:system/processes/process/state/cpu-usage-system": - sysproc.State.CpuUsageSystem = &procstate.CpuUsageSystem - case "/openconfig-system:system/processes/process/state/cpu-utilization": - sysproc.State.CpuUtilization = &procstate.CpuUtilization - case "/openconfig-system:system/processes/process/state/memory-usage": - sysproc.State.MemoryUsage = &procstate.MemoryUsage - case "/openconfig-system:system/processes/process/state/memory-utilization": - sysproc.State.MemoryUtilization = &procstate.MemoryUtilization - default: - sysproc.Pid = &procstate.Pid - sysproc.State.CpuUsageSystem = &procstate.CpuUsageSystem - sysproc.State.CpuUsageUser = &procstate.CpuUsageUser - sysproc.State.CpuUtilization = &procstate.CpuUtilization - sysproc.State.MemoryUsage = &procstate.MemoryUsage - sysproc.State.MemoryUtilization = &procstate.MemoryUtilization - sysproc.State.Name = &procstate.Name - sysproc.State.Pid = &procstate.Pid - sysproc.State.StartTime = &procstate.StartTime - } -} - -func (app *SysApp) getSystemProcesses(sysprocs *ocbinds.OpenconfigSystem_System_Processes, ispid bool) { - log.Infof("getSystemProcesses Entry") - - if ispid == true { - pid, _ := app.path.IntVar("pid") - sysproc := sysprocs.Process[uint64(pid)] - - app.getSystemProcess(sysproc, uint64(pid)) - - } else { - - for pid, _ := range app.procTable { - sysproc, err := sysprocs.NewProcess(pid) - if err != nil { - log.Infof("sysprocs.NewProcess failed") - return - } - - app.getSystemProcess(sysproc, pid) - } - } - return -} - -func (app *SysApp) processGet(dbs [db.MaxDB]*db.DB, fmtType TranslibFmtType) (GetResponse, error) { - log.Info("SysApp: processGet Path: ", app.path.Path) - - stateDb := dbs[db.StateDB] - - var payload []byte - empty_resp := GetResponse{Payload: payload} - - // Read docker info from DB - - app.dockerTable = make(map[string]dbEntry) - - tbl, err := stateDb.GetTable(app.dockerTs) - if err != nil { - log.Error("DOCKER_STATS table get failed!") - return empty_resp, err - } - - keys, _ := tbl.GetKeys() - for _, key := range keys { - e, err := tbl.GetEntry(key) - if err != nil { - log.Error("DOCKER_STATS entry get failed!") - return empty_resp, err - } - - app.dockerTable[key.Get(0)] = dbEntry{entry: e} - } - - // Read process info from DB - - app.procTable = make(map[uint64]dbEntry) - - tbl, err = stateDb.GetTable(app.procTs) - if err != nil { - log.Error("PROCESS_STATS table get failed!") - return empty_resp, err - } - - keys, _ = tbl.GetKeys() - for _, key := range keys { - e, err := tbl.GetEntry(key) - if err != nil { - log.Error("PROCESS_STATS entry get failed!") - return empty_resp, err - } - - pid, _ := strconv.ParseUint(key.Get(0), 10, 64) - app.procTable[pid] = dbEntry{entry: e} - } - - sysObj := app.getAppRootObject() - - targetUriPath, perr := getYangPathFromUri(app.path.Path) - if perr != nil { - log.Infof("getYangPathFromUri failed.") - return GetResponse{Payload: payload}, perr - } - - log.Info("targetUriPath : ", targetUriPath, "Args: ", app.path.Vars) - - if isSubtreeRequest(targetUriPath, "/openconfig-system:system/processes") { - if targetUriPath == "/openconfig-system:system/processes" { - ygot.BuildEmptyTree(sysObj) - app.getSystemProcesses(sysObj.Processes, false) - } else if targetUriPath == "/openconfig-system:system/processes/process" { - pid, perr := app.path.IntVar("pid") - if perr == nil { - if pid == 0 { - ygot.BuildEmptyTree(sysObj) - app.getSystemProcesses(sysObj.Processes, false) - } else { - app.getSystemProcesses(sysObj.Processes, true) - } - } - } else if targetUriPath == "/openconfig-system:system/processes/process/state" { - app.getSystemProcesses(sysObj.Processes, true) - } else if isSubtreeRequest(targetUriPath, "/openconfig-system:system/processes/process/state") { - app.getSystemProcesses(sysObj.Processes, true) - } - } else { - return GetResponse{Payload: payload}, errors.New("Not implemented processGet, path: ") - } - - return generateGetResponse(app.path.Path, app.ygotRoot, fmtType) -} - -func (app *SysApp) processAction(dbs [db.MaxDB]*db.DB) (ActionResponse, error) { - var resp ActionResponse - err := errors.New("Not implemented") - - return resp, err -} diff --git a/translib/transformer/subscribe_resp_xlate.go b/translib/transformer/subscribe_resp_xlate.go index a731405f9..9c98205a5 100644 --- a/translib/transformer/subscribe_resp_xlate.go +++ b/translib/transformer/subscribe_resp_xlate.go @@ -362,20 +362,21 @@ func (dbYgXlateInfo *DbYgXlateInfo) handleDbToYangKeyXlate() error { dbYgXlateInfo.tableName = *dbYgXlateInfo.ygXpathInfo.tableName } else if dbYgXlateInfo.ygXpathInfo.xfmrTbl == nil { return tlerr.InternalError{Format: dbYgXlateInfo.xlateReq.reqLogId + "Could not find the table information for the path", Path: dbYgXlateInfo.uriPath} - } - tblLst, err := dbYgXlateInfo.handleTableXfmrCallback() - if err != nil { - return fmt.Errorf("%v : Error: %v - in handleDbToYangKeyXlate; table name: %v", - dbYgXlateInfo.xlateReq.reqLogId, err, *dbYgXlateInfo.ygXpathInfo.tableName) - } - if len(tblLst) == 0 { - return fmt.Errorf("%v handleDbToYangKeyXlate: Error: No tables are returned by the table "+ - "transformer: for the path: %v", dbYgXlateInfo.xlateReq.reqLogId, dbYgXlateInfo.uriPath) - } - // taking the first table, since number of keys should be same between the tables returned by table transformer - dbYgXlateInfo.tableName = tblLst[0] - if log.V(dbLgLvl) { - log.Info(dbYgXlateInfo.xlateReq.reqLogId, "handleDbToYangKeyXlate: Found table from the table transformer: table name: ", dbYgXlateInfo.tableName) + } else { + tblLst, err := dbYgXlateInfo.handleTableXfmrCallback() + if err != nil { + return fmt.Errorf("%v : Error: %v - in handleDbToYangKeyXlate; table name: %v", + dbYgXlateInfo.xlateReq.reqLogId, err, *dbYgXlateInfo.ygXpathInfo.tableName) + } + if len(tblLst) == 0 { + return fmt.Errorf("%v handleDbToYangKeyXlate: Error: No tables are returned by the table "+ + "transformer: for the path: %v", dbYgXlateInfo.xlateReq.reqLogId, dbYgXlateInfo.uriPath) + } + // taking the first table, since number of keys should be same between the tables returned by table transformer + dbYgXlateInfo.tableName = tblLst[0] + if log.V(dbLgLvl) { + log.Info(dbYgXlateInfo.xlateReq.reqLogId, "handleDbToYangKeyXlate: Found table from the table transformer: table name: ", dbYgXlateInfo.tableName) + } } dbKeyRslvr := &DbYangKeyResolver{tableName: dbYgXlateInfo.tableName, key: dbYgXlateInfo.xlateReq.key, dbs: dbYgXlateInfo.xlateReq.dbs, dbIdx: dbYgXlateInfo.xlateReq.dbNum, uriPath: dbYgXlateInfo.uriPath, reqLogId: dbYgXlateInfo.xlateReq.reqLogId} diff --git a/translib/transformer/test/openconfig-test-xfmr-annot.yang b/translib/transformer/test/openconfig-test-xfmr-annot.yang index dd04f6c00..76b45b3a1 100644 --- a/translib/transformer/test/openconfig-test-xfmr-annot.yang +++ b/translib/transformer/test/openconfig-test-xfmr-annot.yang @@ -217,7 +217,7 @@ module openconfig-test-xfmr-annot { deviation /oc-test-xfmr:test-xfmr/oc-test-xfmr:test-ntp/oc-test-xfmr:test-ntp-servers/oc-test-xfmr:test-ntp-server { deviate add { - sonic-ext:table-name "TEST_NTP_SERVER"; + sonic-ext:table-name "TEST_NTP_DUMMY_SERVER"; } } diff --git a/translib/transformer/test/sonic-test-xfmr.yang b/translib/transformer/test/sonic-test-xfmr.yang index fd65a311b..4f6223e47 100644 --- a/translib/transformer/test/sonic-test-xfmr.yang +++ b/translib/transformer/test/sonic-test-xfmr.yang @@ -413,8 +413,8 @@ module sonic-test-xfmr { } } - container TEST_NTP_SERVER { - list NTP_SERVER_LIST { + container TEST_NTP_DUMMY_SERVER { + list NTP_DUMMY_SERVER_LIST { key "server-id"; leaf server-id { diff --git a/translib/transformer/testxfmryang_test.go b/translib/transformer/testxfmryang_test.go index 9b79b5127..499d00afd 100644 --- a/translib/transformer/testxfmryang_test.go +++ b/translib/transformer/testxfmryang_test.go @@ -400,9 +400,9 @@ func test_node_exercising_db_parent_child_nonkey_leafref_relationship(t *testing node's db table mapping in the child hierachy & siblings yang nodes having similar relationship */ prereq := map[string]interface{}{"TEST_NTP": map[string]interface{}{"global": map[string]interface{}{"trusted-key@": "65", "auth-enabled": "true"}}, "TEST_NTP_AUTHENTICATION_KEY": map[string]interface{}{"65": map[string]interface{}{"key-type": "MD5", "key-value": "0x635352e91dd9ddf2ed9542db848d3b31"}}, - "TEST_NTP_SERVER": map[string]interface{}{"24": map[string]interface{}{"key-id": "65", "min-poll": "3"}}} + "TEST_NTP_DUMMY_SERVER": map[string]interface{}{"24": map[string]interface{}{"key-id": "65", "min-poll": "3"}}} cleanuptbl := map[string]interface{}{"TEST_NTP": map[string]interface{}{"global": ""}, "TEST_NTP_AUTHENTICATION_KEY": map[string]interface{}{"68": "", "65": ""}, - "TEST_NTP_SERVER": map[string]interface{}{"24": ""}} + "TEST_NTP_DUMMY_SERVER": map[string]interface{}{"24": ""}} empty_expected := make(map[string]interface{}) expected_test_ntp := map[string]interface{}{"TEST_NTP": map[string]interface{}{"global": map[string]interface{}{"auth-enabled": "false"}}} expected_test_ntp_keys := map[string]interface{}{"TEST_NTP_AUTHENTICATION_KEY": map[string]interface{}{"68": map[string]interface{}{"key-type": "MD5", @@ -429,7 +429,7 @@ func test_node_exercising_db_parent_child_nonkey_leafref_relationship(t *testing time.Sleep(1 * time.Second) verifyDbResultArray := [4]verifyDbResultData{ {test: "Verify replace of yang node having parent-child non-key leafref relationship with sibling yang node matches to request payload.(test-ntp-server|24)", - db_key: "TEST_NTP_SERVER|24", db_result: empty_expected}, + db_key: "TEST_NTP_DUMMY_SERVER|24", db_result: empty_expected}, {test: "Verify replace of yang node having parent-child non-key leafref relationship with child yang node matches to request payload.(test-ntp|global)", db_key: "TEST_NTP|global", db_result: expected_test_ntp}, {test: "Verify replace of child yang node having parent-child non-key leafref relationship with parent yang node matches to request payload.(test-ntp-key|65)", diff --git a/translib/transformer/transformer_test.go b/translib/transformer/transformer_test.go index 1a98df0e4..a54cc776b 100644 --- a/translib/transformer/transformer_test.go +++ b/translib/transformer/transformer_test.go @@ -131,6 +131,11 @@ func prepareDb() bool { fmt.Printf("error in getDbClient(int(db.CountersDB)") return false } + rclientDBNum[db.StateDB] = getDbClient(int(db.StateDB)) + if rclientDBNum[db.StateDB] == nil { + fmt.Printf("error in getDbClient(int(db.StateDB)") + return false + } rclientDBNum[db.ConfigDB] = getDbClient(int(db.ConfigDB)) if rclientDBNum[db.ConfigDB] == nil { fmt.Printf("error in getDbClient(int(db.ConfigDB)") diff --git a/translib/transformer/xfmr_system.go b/translib/transformer/xfmr_system.go new file mode 100644 index 000000000..9c9669af1 --- /dev/null +++ b/translib/transformer/xfmr_system.go @@ -0,0 +1,2386 @@ +////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2024 Cisco Systems, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +////////////////////////////////////////////////////////////////////////// + +package transformer + +import ( + "errors" + "fmt" + "gopkg.in/yaml.v2" + "os" + "strconv" + "strings" + "syscall" + "time" + + "github.com/Azure/sonic-mgmt-common/translib/db" + "github.com/Azure/sonic-mgmt-common/translib/ocbinds" + "github.com/Azure/sonic-mgmt-common/translib/tlerr" + log "github.com/golang/glog" + "github.com/openconfig/ygot/ygot" +) + +// Mapping for severity enumeration oc to sonic +var ocToSonic_severity = map[ocbinds.E_OpenconfigMessages_SyslogSeverity]string{ + ocbinds.OpenconfigMessages_SyslogSeverity_EMERGENCY: "crit", + ocbinds.OpenconfigMessages_SyslogSeverity_ALERT: "crit", + ocbinds.OpenconfigMessages_SyslogSeverity_CRITICAL: "crit", + ocbinds.OpenconfigMessages_SyslogSeverity_ERROR: "error", + ocbinds.OpenconfigMessages_SyslogSeverity_WARNING: "warn", + ocbinds.OpenconfigMessages_SyslogSeverity_NOTICE: "notice", + ocbinds.OpenconfigMessages_SyslogSeverity_INFORMATIONAL: "info", + ocbinds.OpenconfigMessages_SyslogSeverity_DEBUG: "debug", +} + +// Mapping for severity enumeration oc string to sonic +var ocStrToSonic_severity = map[string]string{ + "EMERGENCY": "crit", + "ALERT": "crit", + "CRITICAL": "crit", + "ERROR": "error", + "WARNING": "warn", + "NOTICE": "notice", + "INFORMATIONAL": "info", + "DEBUG": "debug", +} + +// Mapping for severity enumeration sonic to oc +var sonicToOc_severity = map[string]string{ + "crit": "CRITICAL", + "error": "ERROR", + "warn": "WARNING", + "notice": "NOTICE", + "info": "INFORMATIONAL", + "debug": "DEBUG", + "none": "DEBUG", +} + +var invalid_input_err error = errors.New("Invalid input") +var not_implemented_err error = errors.New("Not implemented") +var invalid_db_err error = errors.New("DB not is proper state") +var aaa_failed_no_method_err error = errors.New("Given AAA methods not found. Valid options include: local, radius, ldap, default and tacacs+") + +var intfTblList = []string{"INTERFACE", "LOOPBACK_INTERFACE", "PORTCHANNEL_INTERFACE"} + +var aaa_ocToSonic_serverType = map[ocbinds.E_OpenconfigAaaTypes_AAA_SERVER_TYPE]string{ + ocbinds.OpenconfigAaaTypes_AAA_SERVER_TYPE_RADIUS: "RADIUS_SERVER", + ocbinds.OpenconfigAaaTypes_AAA_SERVER_TYPE_TACACS: "TACPLUS_SERVER", +} + +var aaa_ocStrToSonic_serverType = map[string]string{ + "RADIUS": "RADIUS_SERVER", + "TACACS": "TACPLUS_SERVER", +} + +var aaa_sonicToOc_serverType = map[string]string{ + "RADIUS_SERVER": "RADIUS", + "TACPLUS_SERVER": "TACACS", +} + +func init() { + XlateFuncBind("system_post_xfmr", system_post_xfmr) + + /* system/state */ + XlateFuncBind("DbToYang_sys_current_datetime_xfmr", DbToYang_sys_current_datetime_xfmr) + XlateFuncBind("DbToYang_sys_up_time_xfmr", DbToYang_sys_up_time_xfmr) + XlateFuncBind("DbToYang_sys_boot_time_xfmr", DbToYang_sys_boot_time_xfmr) + XlateFuncBind("DbToYang_sys_software_version_xfmr", DbToYang_sys_software_version_xfmr) + + /* system/clock */ + XlateFuncBind("YangToDb_sys_clock_timezone_xfmr", YangToDb_sys_clock_timezone_xfmr) + XlateFuncBind("DbToYang_sys_clock_timezone_xfmr", DbToYang_sys_clock_timezone_xfmr) + + /* system/processes */ + XlateFuncBind("YangToDb_sys_proc_pid_key_xfmr", YangToDb_sys_proc_pid_key_xfmr) + XlateFuncBind("DbToYang_sys_proc_pid_key_xfmr", DbToYang_sys_proc_pid_key_xfmr) + XlateFuncBind("DbToYang_sys_proc_pid_xfmr", DbToYang_sys_proc_pid_xfmr) + XlateFuncBind("DbToYang_sys_proc_name_xfmr", DbToYang_sys_proc_name_xfmr) + XlateFuncBind("DbToYang_sys_proc_args_xfmr", DbToYang_sys_proc_args_xfmr) + XlateFuncBind("DbToYang_sys_process_cpu_utilization_xfmr", DbToYang_sys_process_cpu_utilization_xfmr) + XlateFuncBind("DbToYang_sys_process_mem_utilization_xfmr", DbToYang_sys_process_mem_utilization_xfmr) + + /* system/ssh-server */ + XlateFuncBind("YangToDb_sys_ssh_timeout_xfmr", YangToDb_sys_ssh_timeout_xfmr) + XlateFuncBind("DbToYang_sys_ssh_timeout_xfmr", DbToYang_sys_ssh_timeout_xfmr) + + /* Not implemented error */ + XlateFuncBind("YangToDb_sys_not_implemented_leaf_err_xfmr", YangToDb_sys_not_implemented_leaf_err_xfmr) + XlateFuncBind("DbToYang_sys_not_implemented_leaf_err_xfmr", DbToYang_sys_not_implemented_leaf_err_xfmr) + XlateFuncBind("YangToDb_sys_not_implemented_container_err_xfmr", YangToDb_sys_not_implemented_container_err_xfmr) + XlateFuncBind("DbToYang_sys_not_implemented_container_err_xfmr", DbToYang_sys_not_implemented_container_err_xfmr) + XlateFuncBind("Subscribe_sys_not_implemented_container_err_xfmr", Subscribe_sys_not_implemented_container_err_xfmr) + + /* system/logging */ + XlateFuncBind("YangToDb_sys_logging_remote_server_key_xfmr", YangToDb_sys_logging_remote_server_key_xfmr) + XlateFuncBind("DbToYang_sys_logging_remote_server_key_xfmr", DbToYang_sys_logging_remote_server_key_xfmr) + XlateFuncBind("YangToDb_sys_logging_vrf_xfmr", YangToDb_sys_logging_vrf_xfmr) + XlateFuncBind("DbToYang_sys_logging_vrf_xfmr", DbToYang_sys_logging_vrf_xfmr) + XlateFuncBind("YangToDb_sys_logging_selector_key_xfmr", YangToDb_sys_logging_selector_key_xfmr) + XlateFuncBind("DbToYang_sys_logging_selector_key_xfmr", DbToYang_sys_logging_selector_key_xfmr) + XlateFuncBind("YangToDb_sys_logging_selector_facility_xfmr", YangToDb_sys_logging_selector_facility_xfmr) + XlateFuncBind("DbToYang_sys_logging_selector_facility_xfmr", DbToYang_sys_logging_selector_facility_xfmr) + XlateFuncBind("YangToDb_sys_logging_selector_severity_xfmr", YangToDb_sys_logging_selector_severity_xfmr) + XlateFuncBind("DbToYang_sys_logging_selector_severity_xfmr", DbToYang_sys_logging_selector_severity_xfmr) + + /* system/messages */ + XlateFuncBind("YangToDb_sys_msgs_severity_xfmr", YangToDb_sys_msgs_severity_xfmr) + XlateFuncBind("DbToYang_sys_msgs_severity_xfmr", DbToYang_sys_msgs_severity_xfmr) + + /* system/ntp */ + XlateFuncBind("YangToDb_sys_ntp_config_enabled_xfmr", YangToDb_sys_ntp_config_enabled_xfmr) + XlateFuncBind("DbToYang_sys_ntp_config_enabled_xfmr", DbToYang_sys_ntp_config_enabled_xfmr) + XlateFuncBind("YangToDb_sys_ntp_config_enable_auth_xfmr", YangToDb_sys_ntp_config_enable_auth_xfmr) + XlateFuncBind("DbToYang_sys_ntp_config_enable_auth_xfmr", DbToYang_sys_ntp_config_enable_auth_xfmr) + XlateFuncBind("YangToDb_sys_ntp_key_key_xfmr", YangToDb_sys_ntp_key_key_xfmr) + XlateFuncBind("DbToYang_sys_ntp_key_key_xfmr", DbToYang_sys_ntp_key_key_xfmr) + XlateFuncBind("YangToDb_sys_ntp_key_type_xfmr", YangToDb_sys_ntp_key_type_xfmr) + XlateFuncBind("DbToYang_sys_ntp_key_type_xfmr", DbToYang_sys_ntp_key_type_xfmr) + XlateFuncBind("YangToDb_sys_ntp_server_key_xfmr", YangToDb_sys_ntp_server_key_xfmr) + XlateFuncBind("DbToYang_sys_ntp_server_key_xfmr", DbToYang_sys_ntp_server_key_xfmr) + XlateFuncBind("YangToDb_sys_ntp_server_association_type_xfmr", YangToDb_sys_ntp_server_association_type_xfmr) + XlateFuncBind("DbToYang_sys_ntp_server_association_type_xfmr", DbToYang_sys_ntp_server_association_type_xfmr) + XlateFuncBind("YangToDb_sys_ntp_server_iburst_xfmr", YangToDb_sys_ntp_server_iburst_xfmr) + XlateFuncBind("DbToYang_sys_ntp_server_iburst_xfmr", DbToYang_sys_ntp_server_iburst_xfmr) + XlateFuncBind("YangToDb_sys_ntp_server_vrf_xfmr", YangToDb_sys_ntp_server_vrf_xfmr) + XlateFuncBind("DbToYang_sys_ntp_server_vrf_xfmr", DbToYang_sys_ntp_server_vrf_xfmr) + XlateFuncBind("YangToDb_sys_ntp_server_source_address_xfmr", YangToDb_sys_ntp_server_source_address_xfmr) + XlateFuncBind("DbToYang_sys_ntp_server_source_address_xfmr", DbToYang_sys_ntp_server_source_address_xfmr) + + /* system/dns */ + XlateFuncBind("YangToDb_sys_dns_config_xfmr", YangToDb_sys_dns_config_xfmr) + XlateFuncBind("DbToYang_sys_dns_config_xfmr", DbToYang_sys_dns_config_xfmr) + XlateFuncBind("Subscribe_sys_dns_config_xfmr", Subscribe_sys_dns_config_xfmr) + + /* system/aaa */ + XlateFuncBind("YangToDb_sys_aaa_authentication_method_xfmr", YangToDb_sys_aaa_authentication_method_xfmr) + XlateFuncBind("DbToYang_sys_aaa_authentication_method_xfmr", DbToYang_sys_aaa_authentication_method_xfmr) + XlateFuncBind("YangToDb_sys_aaa_authorization_method_xfmr", YangToDb_sys_aaa_authorization_method_xfmr) + XlateFuncBind("DbToYang_sys_aaa_authorization_method_xfmr", DbToYang_sys_aaa_authorization_method_xfmr) + XlateFuncBind("YangToDb_sys_aaa_accounting_method_xfmr", YangToDb_sys_aaa_accounting_method_xfmr) + XlateFuncBind("DbToYang_sys_aaa_accounting_method_xfmr", DbToYang_sys_aaa_accounting_method_xfmr) + XlateFuncBind("YangToDb_sys_aaa_server_group_name_key_xfmr", YangToDb_sys_aaa_server_group_name_key_xfmr) + XlateFuncBind("DbToYang_sys_aaa_server_group_name_key_xfmr", DbToYang_sys_aaa_server_group_name_key_xfmr) + XlateFuncBind("YangToDb_sys_aaa_server_group_name_field_xfmr", YangToDb_sys_aaa_server_group_name_field_xfmr) + XlateFuncBind("DbToYang_sys_aaa_server_group_name_field_xfmr", DbToYang_sys_aaa_server_group_name_field_xfmr) + XlateFuncBind("YangToDb_sys_aaa_server_group_type_field_xfmr", YangToDb_sys_aaa_server_group_type_field_xfmr) + XlateFuncBind("DbToYang_sys_aaa_server_group_type_field_xfmr", DbToYang_sys_aaa_server_group_type_field_xfmr) + XlateFuncBind("YangToDb_sys_aaa_server_groups_address_key_xfmr", YangToDb_sys_aaa_server_groups_address_key_xfmr) + XlateFuncBind("DbToYang_sys_aaa_server_groups_address_key_xfmr", DbToYang_sys_aaa_server_groups_address_key_xfmr) + XlateFuncBind("sys_aaa_server_groups_table_xfmr", sys_aaa_server_groups_table_xfmr) + XlateFuncBind("sys_aaa_server_table_xfmr", sys_aaa_server_table_xfmr) + XlateFuncBind("YangToDb_aaa_sys_source_address_xfmr", YangToDb_aaa_sys_source_address_xfmr) + XlateFuncBind("DbToYang_aaa_sys_source_address_xfmr", DbToYang_aaa_sys_source_address_xfmr) + XlateFuncBind("YangToDb_aaa_server_secret_key_xfmr", YangToDb_aaa_server_secret_key_xfmr) + XlateFuncBind("DbToYang_aaa_server_secret_key_xfmr", DbToYang_aaa_server_secret_key_xfmr) + XlateFuncBind("YangToDb_sys_aaa_server_name_field_xfmr", YangToDb_sys_aaa_server_name_field_xfmr) + XlateFuncBind("DbToYang_sys_aaa_server_name_field_xfmr", DbToYang_sys_aaa_server_name_field_xfmr) +} + +var system_post_xfmr PostXfmrFunc = func(inParams XfmrParams) error { + var err error + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return invalid_db_err + } + + if inParams.oper == DELETE { + xpath, _, _ := XfmrRemoveXPATHPredicates(inParams.requestUri) + + switch xpath { + case "/openconfig-system:system/ntp/servers/server": + serverKeys, err := inParams.d.GetKeys(&db.TableSpec{Name: "NTP_SERVER"}) + + if err == nil && len(serverKeys) == 1 { + subOpDeleteMap := make(map[db.DBNum]map[string]map[string]db.Value) + subOpDeleteMap[db.ConfigDB] = make(map[string]map[string]db.Value) + subOpDeleteMap[db.ConfigDB]["NTP"] = make(map[string]db.Value) + subOpDeleteMap[db.ConfigDB]["NTP"]["global"] = db.Value{Field: make(map[string]string, 2)} + subOpDeleteMap[db.ConfigDB]["NTP"]["global"].Field["src_intf"] = "" + subOpDeleteMap[db.ConfigDB]["NTP"]["global"].Field["vrf"] = "" + inParams.subOpDataMap[DELETE] = &subOpDeleteMap + log.Infof("System Post xfmr invoked, return Delete map %v", inParams.subOpDataMap[DELETE]) + } + } + } + return err +} + +var DbToYang_sys_current_datetime_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + // Get the current time. + now := time.Now() + // Get the timezone offset. + _, offset := now.Zone() + + // Format the datetime in YANG format. + yangFormat := fmt.Sprintf("%s%+03d:%02d", now.Format("2006-01-02T15:04:05Z"), offset/3600, offset%3600/60) + + result["current-datetime"] = yangFormat + return result, nil +} + +var DbToYang_sys_up_time_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + var sysInfo syscall.Sysinfo_t + + err := syscall.Sysinfo(&sysInfo) + if err != nil { + return nil, fmt.Errorf("Failed to get system info: %v", err) + } + uptimeSeconds := sysInfo.Uptime + result["up-time"] = strconv.FormatInt(int64(uptimeSeconds*1e9), 10) + return result, nil +} + +var DbToYang_sys_boot_time_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + var uptime syscall.Sysinfo_t + + err := syscall.Sysinfo(&uptime) + if err != nil { + return nil, fmt.Errorf("Failed to get system info: %v", err) + } + + currentTime := time.Now().UnixNano() + bootTime := currentTime - int64(uptime.Uptime)*int64(time.Second) + result["boot-time"] = strconv.FormatInt(bootTime, 10) + return result, nil +} + +var DbToYang_sys_software_version_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + yamlFile, err := os.ReadFile("/etc/sonic/sonic_version.yml") + if err != nil { + return nil, fmt.Errorf("failed to read /etc/sonic/sonic_version.yml: %v", err) + } + + var versionData map[string]interface{} + if err := yaml.Unmarshal(yamlFile, &versionData); err != nil { + return nil, fmt.Errorf("failed to unmarshal sonic_version.yml: %v", err) + } + + buildVer, ok := versionData["build_version"].(string) + if !ok { + return nil, fmt.Errorf("build_version not found or not a string in sonic_version.yml") + } + + result["software-version"] = buildVer + + return result, nil +} + +var YangToDb_sys_clock_timezone_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + var err error + + if inParams.oper == DELETE { + res_map["timezone"] = "" + return res_map, nil + } + + if inParams.param == nil { + return nil, invalid_input_err + } + + timezoneNamePtr, ok := inParams.param.(*string) + if !ok { + return nil, invalid_input_err + } + timezoneName := *timezoneNamePtr + + _, err = time.LoadLocation(timezoneName) + if err != nil { + zoneErr := fmt.Errorf("Timezone %s does not conform format", timezoneName) + return nil, zoneErr + } + + res_map["timezone"] = timezoneName + return res_map, err +} + +var DbToYang_sys_clock_timezone_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["DEVICE_METADATA"]["localhost"] + if !ok { + return nil, nil + } + + if len(entry.Field["timezone"]) == 0 { + return nil, nil + } + rmap["timezone-name"] = entry.Field["timezone"] + return rmap, nil +} + +var YangToDb_sys_proc_pid_key_xfmr KeyXfmrYangToDb = func(inParams XfmrParams) (string, error) { + pathInfo := NewPathInfo(inParams.uri) + ockey := pathInfo.Var("pid") + return ockey, nil +} + +var DbToYang_sys_proc_pid_key_xfmr KeyXfmrDbToYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}, 1) + var err error + + _, err = strconv.Atoi(inParams.key) + if err != nil { + return nil, nil + } + + rmap["pid"] = inParams.key + return rmap, nil +} + +var DbToYang_sys_proc_pid_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + rmap["pid"] = inParams.key + return rmap, nil +} + +var DbToYang_sys_proc_name_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["PROCESS_STATS"][inParams.key] + if !ok { + return nil, nil + } + + if len(entry.Field["CMD"]) > 0 { + rmap["name"] = strings.Split(entry.Field["CMD"], " ")[0] + + return rmap, nil + } + return nil, nil +} + +var DbToYang_sys_proc_args_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["PROCESS_STATS"][inParams.key] + if !ok { + return nil, nil + } + + if len(entry.Field["CMD"]) > 0 { + var args []interface{} + p_name := strings.Split(entry.Field["CMD"], " ")[1:] + args = make([]interface{}, 0, len(p_name)) + for _, v := range p_name { + if len(v) > 0 { + args = append(args, v) + } + } + rmap["args"] = args + return rmap, nil + } + return nil, nil +} + +/* Float to uint8 */ +var DbToYang_sys_process_cpu_utilization_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["PROCESS_STATS"][inParams.key] + if !ok { + return nil, nil + } + + if len(entry.Field["%CPU"]) > 0 { + f, _ := strconv.ParseFloat(entry.Field["%CPU"], 32) + rmap["cpu-utilization"] = uint8(f) + + return rmap, nil + } + return nil, nil +} + +/* Float to uint8 */ +var DbToYang_sys_process_mem_utilization_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["PROCESS_STATS"][inParams.key] + if !ok { + return nil, nil + } + + if len(entry.Field["%MEM"]) > 0 { + f, _ := strconv.ParseFloat(entry.Field["%MEM"], 32) + rmap["memory-utilization"] = uint8(f) + + return rmap, nil + } + return nil, nil +} + +var YangToDb_sys_ssh_timeout_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + var err error + + if inParams.oper == DELETE { + rmap["login_timeout"] = "" + return rmap, nil + } + + if inParams.param == nil { + return nil, invalid_input_err + } + + timeout, ok := inParams.param.(*uint16) + if !ok { + return nil, invalid_input_err + } + if timeout != nil { + rmap["login_timeout"] = fmt.Sprintf("%d", *timeout) + } + return rmap, err +} + +var DbToYang_sys_ssh_timeout_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + var err error + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["SSH_SERVER"]["POLICIES"] + if !ok { + return nil, nil + } + + if len(entry.Field["login_timeout"]) > 0 { + timeoutStr, ok := entry.Field["login_timeout"] + if ok { + timeoutVal, err := strconv.ParseUint(timeoutStr, 10, 16) + if err != nil { + return rmap, err + } + rmap["timeout"] = timeoutVal + } + return rmap, err + } + return rmap, nil +} + +var YangToDb_sys_not_implemented_leaf_err_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + if inParams.requestUri == inParams.uri { + return nil, not_implemented_err + } + return nil, nil +} + +var DbToYang_sys_not_implemented_leaf_err_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + if inParams.requestUri == inParams.uri { + return nil, not_implemented_err + } + return nil, nil +} + +var YangToDb_sys_not_implemented_container_err_xfmr SubTreeXfmrYangToDb = func(inParams XfmrParams) (map[string]map[string]db.Value, error) { + if inParams.requestUri == inParams.uri { + return nil, not_implemented_err + } + return nil, nil +} + +var DbToYang_sys_not_implemented_container_err_xfmr SubTreeXfmrDbToYang = func(inParams XfmrParams) error { + if inParams.requestUri == inParams.uri { + return not_implemented_err + } + return nil +} + +var Subscribe_sys_not_implemented_container_err_xfmr SubTreeXfmrSubscribe = func(inParams XfmrSubscInParams) (XfmrSubscOutParams, error) { + var result XfmrSubscOutParams + return result, nil +} + +var YangToDb_sys_logging_remote_server_key_xfmr KeyXfmrYangToDb = func(inParams XfmrParams) (string, error) { + pathInfo := NewPathInfo(inParams.uri) + ockey := pathInfo.Var("host") + return ockey, nil +} + +var DbToYang_sys_logging_remote_server_key_xfmr KeyXfmrDbToYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}, 1) + + rmap["host"] = inParams.key + return rmap, nil +} + +var YangToDb_sys_logging_vrf_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + + if inParams.param == nil { + return nil, invalid_input_err + } + + vrf, ok := inParams.param.(*string) + if !ok { + return nil, invalid_input_err + } + rmap["vrf"] = *vrf + return rmap, nil +} + +var DbToYang_sys_logging_vrf_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["SYSLOG_SERVER"][inParams.key] + if !ok { + return nil, nil + } + + if len(entry.Field["vrf"]) > 0 { + vrf, ok := entry.Field["vrf"] + if ok { + rmap["network-instance"] = vrf + return rmap, nil + } + return nil, invalid_input_err + } + return nil, nil +} + +var YangToDb_sys_logging_selector_key_xfmr KeyXfmrYangToDb = func(inParams XfmrParams) (string, error) { + pathInfo := NewPathInfo(inParams.uri) + ockey := pathInfo.Var("host") + return ockey, nil +} + +var DbToYang_sys_logging_selector_key_xfmr KeyXfmrDbToYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}, 1) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["SYSLOG_SERVER"][inParams.key] + if !ok { + return nil, nil + } + + if len(entry.Field["severity"]) > 0 { + severity, ok := entry.Field["severity"] + if ok { + rmap["severity"] = sonicToOc_severity[severity] + rmap["facility"] = "ALL" + return rmap, nil + } + return nil, nil + } + return nil, nil +} + +var YangToDb_sys_logging_selector_facility_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + pathInfo := NewPathInfo(inParams.uri) + facility := pathInfo.Var("facility") + + if facility != "ALL" { + return nil, errors.New("Invalid input, only ALL is supported") + } + return rmap, nil +} + +var DbToYang_sys_logging_selector_facility_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + rmap["facility"] = "ALL" + return rmap, nil +} + +var YangToDb_sys_logging_selector_severity_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + pathInfo := NewPathInfo(inParams.uri) + ockey := pathInfo.Var("severity") + + if translation, found := ocStrToSonic_severity[ockey]; found { + rmap["severity"] = translation + return rmap, nil + } + return nil, invalid_input_err +} + +var DbToYang_sys_logging_selector_severity_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["SYSLOG_SERVER"][inParams.key] + if !ok { + return nil, nil + } + + if len(entry.Field["severity"]) > 0 { + severity, ok := entry.Field["severity"] + if ok { + rmap["severity"] = sonicToOc_severity[severity] + return rmap, nil + } + return nil, invalid_input_err + } + return nil, nil +} + +var YangToDb_sys_msgs_severity_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + + if inParams.param == nil { + return nil, invalid_input_err + } + severity, ok := inParams.param.(ocbinds.E_OpenconfigMessages_SyslogSeverity) + if !ok { + return nil, invalid_input_err + } + if translation, found := ocToSonic_severity[severity]; found { + rmap["severity"] = translation + return rmap, nil + } + return nil, invalid_input_err +} + +var DbToYang_sys_msgs_severity_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry, ok := data["SYSLOG_CONFIG"]["GLOBAL"] + if !ok { + return nil, nil + } + + if len(entry.Field["severity"]) > 0 { + severity, ok := entry.Field["severity"] + if ok { + rmap["severity"] = sonicToOc_severity[severity] + return rmap, nil + } + return nil, errors.New("Invalid data") + } + return nil, nil +} + +var YangToDb_sys_ntp_config_enabled_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + var enStr string + + if inParams.param == nil { + return nil, invalid_input_err + } + + enabled, ok := inParams.param.(*bool) + if !ok { + return nil, invalid_input_err + } + if *enabled { + enStr = "enabled" + } else { + enStr = "disabled" + } + res_map["admin_state"] = enStr + + return res_map, nil +} + +var DbToYang_sys_ntp_config_enabled_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + tbl := data["NTP"] + if _, ok := tbl["global"]; !ok { + return nil, nil + } + + tblData := tbl["global"] + dbData, ok := tblData.Field["admin_state"] + if ok { + if dbData == "enabled" { + result["enabled"] = true + } else { + result["enabled"] = false + } + } else { + log.Info("Admin state field not found in DB") + } + return result, nil +} + +var YangToDb_sys_ntp_config_enable_auth_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + var enStr string + + if inParams.param == nil { + return nil, invalid_input_err + } + + enabled, ok := inParams.param.(*bool) + if !ok { + return nil, invalid_input_err + } + if *enabled { + enStr = "enabled" + } else { + enStr = "disabled" + } + res_map["authentication"] = enStr + + return res_map, nil +} + +var DbToYang_sys_ntp_config_enable_auth_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + tbl := data["NTP"] + if _, ok := tbl["global"]; !ok { + return nil, nil + } + + tblData := tbl["global"] + dbData, ok := tblData.Field["authentication"] + if ok { + if dbData == "enabled" { + result["enable-ntp-auth"] = true + } else { + result["enable-ntp-auth"] = false + } + } else { + log.Info("Authentication field not found in DB") + } + return result, nil +} + +var YangToDb_sys_ntp_key_key_xfmr KeyXfmrYangToDb = func(inParams XfmrParams) (string, error) { + pathInfo := NewPathInfo(inParams.uri) + ockey := pathInfo.Var("key-id") + return ockey, nil +} + +var DbToYang_sys_ntp_key_key_xfmr KeyXfmrDbToYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}, 1) + + value, _ := strconv.ParseUint(inParams.key, 10, 16) + rmap["key-id"] = uint16(value) + return rmap, nil +} + +var YangToDb_sys_ntp_key_type_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + var typeStr string + + if inParams.param == nil { + return nil, invalid_input_err + } + + keyType, ok := inParams.param.(ocbinds.E_OpenconfigSystem_NTP_AUTH_TYPE) + if !ok { + return nil, invalid_input_err + } + if keyType == ocbinds.OpenconfigSystem_NTP_AUTH_TYPE_NTP_AUTH_MD5 { + typeStr = "md5" + } else { + return nil, invalid_input_err + } + res_map["type"] = typeStr + + return res_map, nil +} + +var DbToYang_sys_ntp_key_type_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + tbl := data["NTP_KEY"] + if _, ok := tbl[inParams.key]; !ok { + return nil, nil + } + + tblData := tbl[inParams.key] + dbData, ok := tblData.Field["type"] + if ok { + if dbData == "md5" { + result["key-type"] = "NTP_AUTH_MD5" + } else { + return nil, errors.New("Invalid input, only MD5 is supported") + } + } else { + log.Info("Key type field not found in DB") + } + return result, nil +} + +var YangToDb_sys_ntp_server_key_xfmr KeyXfmrYangToDb = func(inParams XfmrParams) (string, error) { + pathInfo := NewPathInfo(inParams.uri) + ockey := pathInfo.Var("address") + return ockey, nil +} + +var DbToYang_sys_ntp_server_key_xfmr KeyXfmrDbToYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}, 1) + + rmap["address"] = inParams.key + return rmap, nil +} + +var YangToDb_sys_ntp_server_association_type_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + var typeStr string + + if inParams.param == nil { + return nil, invalid_input_err + } + + assocType, ok := inParams.param.(ocbinds.E_OpenconfigSystem_System_Ntp_Servers_Server_Config_AssociationType) + if !ok { + return nil, invalid_input_err + } + if assocType == ocbinds.OpenconfigSystem_System_Ntp_Servers_Server_Config_AssociationType_SERVER { + typeStr = "server" + } else if assocType == ocbinds.OpenconfigSystem_System_Ntp_Servers_Server_Config_AssociationType_POOL { + typeStr = "pool" + } else if assocType == ocbinds.OpenconfigSystem_System_Ntp_Servers_Server_Config_AssociationType_UNSET { + return nil, nil + } else { + log.Infof("Invalid input %d, only SERVER & POOL are supported", assocType) + return nil, errors.New("Invalid input, only SERVER & POOL are supported") + } + res_map["association_type"] = typeStr + + return res_map, nil +} + +var DbToYang_sys_ntp_server_association_type_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + tbl := data["NTP_SERVER"] + if _, ok := tbl[inParams.key]; !ok { + return nil, nil + } + + tblData := tbl[inParams.key] + dbData, ok := tblData.Field["association_type"] + if ok { + if dbData == "server" { + result["association-type"] = "SERVER" + } else if dbData == "pool" { + result["association-type"] = "POOL" + } + } else { + log.Info("Authentication field not found in DB") + } + return result, nil +} + +var YangToDb_sys_ntp_server_iburst_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + var enStr string + + if inParams.param == nil { + return nil, invalid_input_err + } + + enabled, ok := inParams.param.(*bool) + if !ok { + return nil, invalid_input_err + } + if *enabled { + enStr = "on" + } else { + enStr = "off" + } + res_map["iburst"] = enStr + + return res_map, nil +} + +var DbToYang_sys_ntp_server_iburst_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + tbl := data["NTP_SERVER"] + if _, ok := tbl[inParams.key]; !ok { + return nil, nil + } + + tblData := tbl[inParams.key] + dbData, ok := tblData.Field["iburst"] + if ok { + if dbData == "on" { + result["iburst"] = true + } else { + result["iburst"] = false + } + } else { + log.Info("iburst field not found in DB") + } + return result, nil +} + +/* Delete will be handled in postXfmr action + * If user passed vrf -> If should be same as global (if exist) + */ +var YangToDb_sys_ntp_server_vrf_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + + if inParams.oper == DELETE { + return nil, errors.New("Delete server instead of network-instance removal") + } + + if inParams.param == nil { + return nil, invalid_input_err + } + + vrf, ok := inParams.param.(*string) + if !ok { + return nil, invalid_input_err + } + vrfName := *vrf + + if vrfName == "mgmt" { + mgmtVrfCfgT := &db.TableSpec{Name: "MGMT_VRF_CONFIG"} + mgmtVrfCfgE, err := inParams.d.GetEntry(mgmtVrfCfgT, db.Key{Comp: []string{"vrf_global"}}) + if err == nil { + mgmtVrfEnabled, ok := mgmtVrfCfgE.Field["mgmtVrfEnabled"] + if ok && mgmtVrfEnabled == "false" { + return nil, errors.New("Mgmt VRF config is not enabled") + } + } + } + + ntpTbl := &db.TableSpec{Name: "NTP"} + ntpEntry, err := inParams.d.GetEntry(ntpTbl, db.Key{Comp: []string{"global"}}) + if err == nil { + dbData, ok := ntpEntry.Field["vrf"] + if ok { + if dbData != vrfName { + return nil, errors.New("Given network-instance name is different from already configured one for this/any other server") + } + } + } + log.Info("vrf field not found in DB") + res_map["vrf"] = vrfName + + return res_map, nil +} + +var DbToYang_sys_ntp_server_vrf_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + tbl := data["NTP"] + if _, ok := tbl["global"]; !ok { + return nil, nil + } + + tblData := tbl["global"] + dbData, ok := tblData.Field["vrf"] + if ok && len(dbData) > 0 { + result["network-instance"] = dbData + } else { + log.Info("vrf field not found in DB") + return nil, nil + } + return result, nil +} + +// YangToDb - Function to fetch Interface for given source address +func get_src_intf_for_given_addr(src_ip string, inParams XfmrParams) string { + var ifName string + var vrfName string + def_vrf := false + tblList := make([]string, len(intfTblList)+1) + + // Fetch VRF -> 1) In current inParams 2) In DB + pathInfo := NewPathInfo(inParams.uri) + currServer := pathInfo.Var("address") + obj := (*inParams.ygRoot).(*ocbinds.Device) + sobj := obj.System + if sobj != nil && sobj.Ntp != nil && sobj.Ntp.Servers != nil { + for _, server := range sobj.Ntp.Servers.Server { + if server.Address != nil && *server.Address == currServer { + if server.Config.NetworkInstance != nil { + vrfName = *server.Config.NetworkInstance + } + break + } + } + } + + if len(vrfName) == 0 { + ntpTbl := &db.TableSpec{Name: "NTP"} + ntpEntry, err := inParams.d.GetEntry(ntpTbl, db.Key{Comp: []string{"global"}}) + if err == nil { + vrfName, _ = ntpEntry.Field["vrf"] + } + } + + log.Infof("Start fetching interface for given ip %s and vrf %s..", src_ip, vrfName) + if len(vrfName) > 0 { + if vrfName == "mgmt" { + tblList = append(tblList, "MGMT_INTERFACE") + } else if vrfName == "default" { + def_vrf = true + copy(tblList, intfTblList) + } + } else { + copy(tblList, intfTblList) + def_vrf = true + } + + if def_vrf == true { + mgmtVrfCfgT := &db.TableSpec{Name: "MGMT_VRF_CONFIG"} + mgmtVrfCfgE, err := inParams.d.GetEntry(mgmtVrfCfgT, db.Key{Comp: []string{"vrf_global"}}) + if err == nil { + mgmtVrfEnabled, ok := mgmtVrfCfgE.Field["mgmtVrfEnabled"] + if ok && mgmtVrfEnabled == "false" { + log.Info("Fetch Interface, Mgmt VRF config is not enabled") + tblList = append(tblList, "MGMT_INTERFACE") + } + } else { + log.Info("Fetch Interface, Mgmt VRF config is not enabled") + tblList = append(tblList, "MGMT_INTERFACE") + } + } + + log.Infof("Fetch Interface, table list to be looked into %v", tblList) + for _, tblName := range tblList { + intfTable := &db.TableSpec{Name: tblName} + + intfKeys, err := inParams.d.GetKeysPattern(intfTable, db.Key{Comp: []string{"*", src_ip}}) + if (err != nil) || len(intfKeys) == 0 { + src_ip_w_mask := src_ip + "/*" + intfKeys, err = inParams.d.GetKeysPattern(intfTable, db.Key{Comp: []string{"*", src_ip_w_mask}}) + } + + if (err == nil) && len(intfKeys) > 0 { + + for _, intfKey := range intfKeys { + + if len(intfKey.Comp) != 2 && len(intfKey.Comp[0]) == 0 { + continue + } + + ifName = intfKey.Comp[0] + /* Validate VRF */ + if def_vrf && tblName != "MGMT_INTERFACE" { + if intfEntry, err := inParams.d.GetEntry(intfTable, db.Key{Comp: []string{ifName}}); err == nil { + vrfName := (&intfEntry).Get("vrf_name") + if len(vrfName) > 0 { + log.Infof("Fetch Interface, fetched vrf for interface %s is %s", ifName, vrfName) + ifName = "" + continue + } + } + } + break + } + } + if len(ifName) > 0 { + break + } + } + return ifName +} + +// DbToYang - Function to fetch IP prefix for given interface and vrf pair +func get_src_addr_for_interface(ifName string, vrfName string, inParams XfmrParams) string { + var src_addr string + def_vrf := false + tblList := make([]string, len(intfTblList)+1) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return src_addr + } + + data := (*inParams.dbDataMap)[inParams.curDb] + + log.Infof("Start fetching ip prefix for interface %s and vrf %s..", ifName, vrfName) + if len(vrfName) > 0 { + if vrfName == "mgmt" { + tblList = append(tblList, "MGMT_INTERFACE") + } else if vrfName == "default" { + def_vrf = true + copy(tblList, intfTblList) + } + } else { + copy(tblList, intfTblList) + def_vrf = true + } + + if def_vrf == true { + tbl := data["MGMT_VRF_CONFIG"] + if tblData, ok := tbl["vrf_global"]; ok { + mgmtVrfEnabled, ok := tblData.Field["mgmtVrfEnabled"] + if ok && mgmtVrfEnabled == "false" { + log.Info("Fetch IP Prefix, Mgmt VRF config is not enabled") + tblList = append(tblList, "MGMT_INTERFACE") + } + } else { + log.Info("Fetch IP Prefix, Mgmt VRF config is not enabled") + tblList = append(tblList, "MGMT_INTERFACE") + } + } + + log.Infof("Fetch IP Prefix, table list to be looked into %v", tblList) + for _, tblName := range tblList { + intfTable := &db.TableSpec{Name: tblName} + + /* Validate VRF */ + if def_vrf && tblName != "MGMT_INTERFACE" { + if intfEntry, err := inParams.d.GetEntry(intfTable, db.Key{Comp: []string{ifName}}); err == nil { + vrfName := (&intfEntry).Get("vrf_name") + if len(vrfName) > 0 { + log.Infof("Fetch IP Prefix, fetched vrf for interface %s is %s", ifName, vrfName) + return src_addr + } + } + } + + /* Get first ip configured on the given port */ + ipKeys, err := inParams.d.GetKeysPattern(intfTable, db.Key{Comp: []string{ifName, "*"}}) + if err == nil && len(ipKeys) > 0 && len(ipKeys[0].Comp) == 2 { + idx := strings.Index(ipKeys[0].Comp[1], "/") + if idx != -1 { + return ipKeys[0].Comp[1][:idx] + } + return ipKeys[0].Comp[1] + } + } + return src_addr +} + +var YangToDb_sys_ntp_server_source_address_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + + if inParams.param == nil { + return nil, invalid_input_err + } + + src_ip, ok := inParams.param.(*string) + if !ok { + return nil, invalid_input_err + } + if len(*src_ip) > 6 { + ifName := get_src_intf_for_given_addr(*src_ip, inParams) + if len(ifName) > 0 { + + ntpTbl := &db.TableSpec{Name: "NTP"} + ntpEntry, err := inParams.d.GetEntry(ntpTbl, db.Key{Comp: []string{"global"}}) + if err == nil { + dbData, ok := ntpEntry.Field["src_intf"] + if ok { + if dbData != ifName { + return nil, errors.New("Given source address's port doesn't match with already configured src_intf") + } + } + } + res_map["src_intf"] = ifName + } else { + return nil, errors.New("Failed to get source interface for given source address") + } + } else { + return nil, invalid_input_err + } + return res_map, nil +} + +var DbToYang_sys_ntp_server_source_address_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + tbl := data["NTP"] + if _, ok := tbl["global"]; !ok { + return nil, nil + } + + tblData := tbl["global"] + intfName, ok := tblData.Field["src_intf"] + if ok { + vrfName, _ := tblData.Field["vrf"] + addr := get_src_addr_for_interface(intfName, vrfName, inParams) + if len(addr) > 0 { + result["source-address"] = addr + } else { + return nil, errors.New("Source address not configured properly for src_intf " + intfName) + } + } else { + log.Info("src_intf field not found in DB") + } + return result, nil +} + +var YangToDb_sys_dns_config_xfmr SubTreeXfmrYangToDb = func(inParams XfmrParams) (map[string]map[string]db.Value, error) { + dnsNsTableMap := make(map[string]map[string]db.Value) + var nsList []string + var nsListDb []string + + if inParams.ygRoot == nil { + return nil, invalid_input_err + } + + /* Set invokeCRUSubtreeOnce flag to invoke subtree once */ + if inParams.invokeCRUSubtreeOnce != nil { + *inParams.invokeCRUSubtreeOnce = true + } + dnsTbl := &db.TableSpec{Name: "DNS_NAMESERVER"} + + switch inParams.oper { + case DELETE: + { + // Note : Value specific delete not supported + // Get db data + dnsKeys, err := inParams.d.GetKeysPattern(dnsTbl, db.Key{Comp: []string{"*"}}) + if err == nil && len(dnsKeys) > 0 { + for _, key := range dnsKeys { + nsList = append(nsList, key.Comp[0]) + } + } else { + // No Data in DB + return nil, nil + } + } + case REPLACE: + { + // Get db data + dnsKeys, err := inParams.d.GetKeysPattern(dnsTbl, db.Key{Comp: []string{"*"}}) + if err == nil && len(dnsKeys) > 0 { + for _, key := range dnsKeys { + nsListDb = append(nsListDb, key.Comp[0]) + } + } + } + fallthrough + case CREATE: + fallthrough + case UPDATE: + { + // Get ygRoot + obj := (*inParams.ygRoot).(*ocbinds.Device) + dnsObj := obj.System.Dns + dnsConfigObj := dnsObj.Config + if dnsConfigObj == nil { + return nil, invalid_input_err + } + + nsList = dnsConfigObj.Search + if len(nsList) == 0 { + return nil, invalid_input_err + } + } + default: + return nil, not_implemented_err + } + + // Dummy db field value for return map + fVal := make(map[string]string) + //dbVal["NULL"] = "NULL" + newVal := db.Value{Field: fVal} + tblName := "DNS_NAMESERVER" + + // Delete old entries for Replace + if inParams.oper == REPLACE { + for _, oldNs := range nsListDb { + if !contains(nsList, oldNs) { + dbErr := inParams.d.DeleteEntry(dnsTbl, db.Key{Comp: []string{oldNs}}) + if dbErr != nil { + return nil, errors.New("Error!!! Failed to remove entry from CONFIG_DB") + } + log.Infof("DNS removed %v entry from CONFIG_DB", oldNs) + } + } + } + + for _, ns := range nsList { + if _, ok := dnsNsTableMap[tblName]; !ok { + dnsNsTableMap[tblName] = make(map[string]db.Value) + } + dnsNsTableMap[tblName][ns] = newVal + + } + + return dnsNsTableMap, nil +} + +var DbToYang_sys_dns_config_xfmr SubTreeXfmrDbToYang = func(inParams XfmrParams) error { + var nameServers []string + + if inParams.ygRoot == nil { + return nil + } + + // Get db data + dnsTbl := &db.TableSpec{Name: "DNS_NAMESERVER"} + dnsKeys, err := inParams.d.GetKeysPattern(dnsTbl, db.Key{Comp: []string{"*"}}) + if err == nil && len(dnsKeys) > 0 { + for _, key := range dnsKeys { + nameServers = append(nameServers, key.Comp[0]) + } + } else { + return nil + } + + // Get ygRoot + obj := (*inParams.ygRoot).(*ocbinds.Device) + dnsObj := obj.System.Dns + dnsConfigObj := dnsObj.Config + ygot.BuildEmptyTree(dnsConfigObj) + + // Update DB data in ygRoot + dnsConfigObj.Search = nameServers + return nil +} + +var Subscribe_sys_dns_config_xfmr = func(inParams XfmrSubscInParams) (XfmrSubscOutParams, error) { + var result XfmrSubscOutParams + + if inParams.subscProc == TRANSLATE_SUBSCRIBE { + log.V(3).Info("Subscribe system/dns/config : inParams.subscProc: ", inParams.subscProc) + + pathInfo := NewPathInfo(inParams.uri) + targetUriPath := pathInfo.YangPath + + log.V(3).Infof("Subscribe system/dns/config :- URI:%s pathinfo:%s ", inParams.uri, pathInfo.Path) + log.V(3).Infof("Subscribe system/dns/config :- Target URI path:%s", targetUriPath) + + // to handle the TRANSLATE_SUBSCRIBE + result.nOpts = new(notificationOpts) + result.nOpts.pType = OnChange + result.nOpts.mInterval = 15 + result.isVirtualTbl = false + result.needCache = true + + result.dbDataMap = RedisDbSubscribeMap{db.ConfigDB: { + "DNS_NAMESERVER": {"*": {}}}} + + log.V(3).Info("Subscribe system/dns/config : result ", result) + } + return result, nil +} + +var DbToYang_sys_aaa_authentication_method_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry := data["AAA"]["authentication"] + loginStr, ok := entry.Field["login"] + + if !ok || len(loginStr) == 0 { + return nil, nil + } + + authMethods := strings.Split(loginStr, ",") + var authMethodsList []interface{} + + for _, method := range authMethods { + methodType, err := openconfig_aaa_translate_DBFormat_To_methodtype(method) + if err != nil { + return nil, err + } + authMethodsList = append(authMethodsList, methodType) + } + rmap["authentication-method"] = authMethodsList + return rmap, nil +} + +var YangToDb_sys_aaa_authentication_method_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + + if inParams.param == nil { + return nil, invalid_input_err + } + authRes, err := openconfig_aaa_process_method_ops(inParams, "authentication") + if err != nil { + return nil, err + } + + authMethods, ok := authRes["authentication-method"] + if !ok || (len(authMethods) == 0 && inParams.oper != DELETE) { + return nil, aaa_failed_no_method_err + } + + rmap["login"] = strings.Join(authMethods, ",") + return rmap, nil +} + +var DbToYang_sys_aaa_authorization_method_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry := data["AAA"]["authorization"] + loginStr, ok := entry.Field["login"] + + if !ok || len(loginStr) == 0 { + return nil, nil + } + + authMethods := strings.Split(loginStr, ",") + var authMethodsList []interface{} + + for _, method := range authMethods { + methodType, err := openconfig_aaa_translate_DBFormat_To_methodtype(method) + if err != nil { + return nil, err + } + authMethodsList = append(authMethodsList, methodType) + } + + rmap["authorization-method"] = authMethodsList + return rmap, nil +} + +var YangToDb_sys_aaa_authorization_method_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + + if inParams.param == nil { + return nil, invalid_input_err + } + authRes, err := openconfig_aaa_process_method_ops(inParams, "authorization") + if err != nil { + return nil, err + } + + authMethods, ok := authRes["authorization-method"] + if !ok || (len(authMethods) == 0 && inParams.oper != DELETE) { + return nil, aaa_failed_no_method_err + } + + rmap["login"] = strings.Join(authMethods, ",") + return rmap, nil +} + +var DbToYang_sys_aaa_accounting_method_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + data := (*inParams.dbDataMap)[inParams.curDb] + entry := data["AAA"]["accounting"] + loginStr, ok := entry.Field["login"] + + if !ok || len(loginStr) == 0 { + return nil, nil + } + + authMethods := strings.Split(loginStr, ",") + var authMethodsList []interface{} + + for _, method := range authMethods { + methodType, err := openconfig_aaa_translate_DBFormat_To_methodtype(method) + if err != nil { + return nil, err + } + authMethodsList = append(authMethodsList, methodType) + } + + rmap["accounting-method"] = authMethodsList + return rmap, nil +} + +var YangToDb_sys_aaa_accounting_method_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + + if inParams.param == nil { + return nil, invalid_input_err + } + + authRes, err := openconfig_aaa_process_method_ops(inParams, "accounting") + if err != nil { + return nil, err + } + + authMethods, ok := authRes["accounting-method"] + if !ok || (len(authMethods) == 0 && inParams.oper != DELETE) { + return nil, aaa_failed_no_method_err + } + + rmap["login"] = strings.Join(authMethods, ",") + return rmap, nil +} + +// openconfig_aaa_process_method_ops manages methods for the openconfig-system module for the AAA and transforms methods (authentication, authorization, accounting) +// based on the type of operation (CREATE, UPDATE, REPLACE). It interacts with the database to fetch existing methods, +// processes the provided parameters, and returns a map of the transformed methods. + +func openconfig_aaa_process_method_ops(inParams XfmrParams, key string) (map[string][]string, error) { + rmap := make(map[string][]string) + + if inParams.oper == DELETE { + rmap[openconfig_aaa_get_Method_Key(key)] = []string{} + return rmap, nil + } + + var methods []string + syst := &db.TableSpec{Name: "AAA"} + entry, _ := inParams.d.GetEntry(syst, db.Key{Comp: []string{key}}) + methodsStr, ok := entry.Field["login"] + var existingMethods []string + + if ok && len(methodsStr) > 0 { + methods = strings.Split(methodsStr, ",") + for _, method := range methods { + if len(method) > 0 { + existingMethods = append(existingMethods, method) + } + } + } + + var methodsToAdd []string + switch key { + case "authentication": + if v, ok := inParams.param.([]ocbinds.OpenconfigSystem_System_Aaa_Authentication_Config_AuthenticationMethod_Union); ok { + for _, method := range v { + methodStr, err := openconfig_aaa_extract_method_string_enum(method) + if err != nil { + return nil, err + } + methodsToAdd = append(methodsToAdd, methodStr) + } + } else { + return nil, invalid_input_err + } + case "authorization": + if v, ok := inParams.param.([]ocbinds.OpenconfigSystem_System_Aaa_Authorization_Config_AuthorizationMethod_Union); ok { + for _, method := range v { + methodStr, err := openconfig_aaa_extract_method_string_enum(method) + if err != nil { + return nil, err + } + methodsToAdd = append(methodsToAdd, methodStr) + } + } else { + return nil, invalid_input_err + } + case "accounting": + if v, ok := inParams.param.([]ocbinds.OpenconfigSystem_System_Aaa_Accounting_Config_AccountingMethod_Union); ok { + for _, method := range v { + methodStr, err := openconfig_aaa_extract_method_string_enum(method) + if err != nil { + return nil, err + } + methodsToAdd = append(methodsToAdd, methodStr) + } + } else { + return nil, invalid_input_err + } + default: + return nil, fmt.Errorf("Only authentication,authorization and accounting are supported but received %s", key) + } + + switch inParams.oper { + case CREATE, UPDATE: + if len(existingMethods) == 0 { + rmap[openconfig_aaa_get_Method_Key(key)] = methodsToAdd + } else { + for _, method := range methodsToAdd { + exists := false + for _, existingMethod := range existingMethods { + if method == existingMethod { + exists = true + break + } + } + if !exists { + existingMethods = append(existingMethods, method) + } + } + rmap[openconfig_aaa_get_Method_Key(key)] = existingMethods + } + + case REPLACE: + rmap[openconfig_aaa_get_Method_Key(key)] = methodsToAdd + default: + return nil, fmt.Errorf("Operation type %s is not supported", inParams.oper) + } + return rmap, nil +} + +// helper function to map openconfig type(Method type) with sonic type +func openconfig_aaa_translate_methodtype_To_dBFormat(methodType ocbinds.E_OpenconfigAaaTypes_AAA_METHOD_TYPE) (string, error) { + switch methodType { + case ocbinds.OpenconfigAaaTypes_AAA_METHOD_TYPE_LOCAL: + return "local", nil + case ocbinds.OpenconfigAaaTypes_AAA_METHOD_TYPE_RADIUS_ALL: + return "radius", nil + case ocbinds.OpenconfigAaaTypes_AAA_METHOD_TYPE_TACACS_ALL: + return "tacacs+", nil + default: + return "", fmt.Errorf("This method type is not allowed,only LOCAL,RADIUS and TACACS method type is allowed but received %v", methodType) + } +} + +// helper function to map sonic type with openconfig type +func openconfig_aaa_translate_DBFormat_To_methodtype(methodStr string) (string, error) { + switch methodStr { + case "local": + return "LOCAL", nil + case "radius": + return "RADIUS_ALL", nil + case "tacacs+": + return "TACACS_ALL", nil + case "ldap": + return "ldap", nil + case "default": + return "default", nil + default: + return "", fmt.Errorf("Strings apart from local,radius,tacacs+,ldap and default are not allowed but received %s", methodStr) + } +} + +// Helper function to extract method string and identity ref from method type +// mapping oc values identity ref to sonic +func openconfig_aaa_extract_method_string_enum(method interface{}) (string, error) { + switch m := method.(type) { + case *ocbinds.OpenconfigSystem_System_Aaa_Authentication_Config_AuthenticationMethod_Union_E_OpenconfigAaaTypes_AAA_METHOD_TYPE: + methodStr, err := openconfig_aaa_translate_methodtype_To_dBFormat(m.E_OpenconfigAaaTypes_AAA_METHOD_TYPE) // No dereference needed + if err != nil { + return "", err + } + return methodStr, nil + + case *ocbinds.OpenconfigSystem_System_Aaa_Authorization_Config_AuthorizationMethod_Union_E_OpenconfigAaaTypes_AAA_METHOD_TYPE: + methodStr, err := openconfig_aaa_translate_methodtype_To_dBFormat(m.E_OpenconfigAaaTypes_AAA_METHOD_TYPE) // No dereference needed + if err != nil { + return "", err + } + return methodStr, nil + + case *ocbinds.OpenconfigSystem_System_Aaa_Accounting_Config_AccountingMethod_Union_E_OpenconfigAaaTypes_AAA_METHOD_TYPE: + methodStr, err := openconfig_aaa_translate_methodtype_To_dBFormat(m.E_OpenconfigAaaTypes_AAA_METHOD_TYPE) // No dereference needed + if err != nil { + return "", err + } + return methodStr, nil + + case *ocbinds.OpenconfigSystem_System_Aaa_Authentication_Config_AuthenticationMethod_Union_String: + if m.String != "ldap" && m.String != "default" { + return "", fmt.Errorf("Invalid method string: %s; only 'ldap' and 'default' are allowed", m.String) + } + return m.String, nil + case *ocbinds.OpenconfigSystem_System_Aaa_Authorization_Config_AuthorizationMethod_Union_String: + if m.String != "ldap" && m.String != "default" { + return "", fmt.Errorf("Invalid method string: %s; only 'ldap' and 'default' are allowed", m.String) + } + return m.String, nil + case *ocbinds.OpenconfigSystem_System_Aaa_Accounting_Config_AccountingMethod_Union_String: + if m.String != "ldap" && m.String != "default" { + return "", fmt.Errorf("Invalid method string: %s; only 'ldap' and 'default' are allowed", m.String) + } + return m.String, nil + } + return "", nil +} + +// helper function to get key for processing the function openconfig_aaa_process_method_ops +func openconfig_aaa_get_Method_Key(key string) string { + switch key { + case "authentication": + return "authentication-method" + case "authorization": + return "authorization-method" + case "accounting": + return "accounting-method" + default: + return key + } +} + +var YangToDb_sys_aaa_server_group_name_key_xfmr KeyXfmrYangToDb = func(inParams XfmrParams) (string, error) { + pathInfo := NewPathInfo(inParams.uri) + name := pathInfo.Var("name") + if name == "" { + return name, nil + } + if name != "tacacs+" && name != "radius" { + log.Error("Invalid server group name:", name) + return "", fmt.Errorf("Invalid server group name: %s; must be either 'tacacs+' or 'radius'", name) + } + + return name, nil +} + +var DbToYang_sys_aaa_server_group_name_key_xfmr KeyXfmrDbToYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + pathInfo := NewPathInfo(inParams.uri) + reqpathInfo := NewPathInfo(inParams.requestUri) + requestUriPath := reqpathInfo.YangPath + + log.Infof("DbToYang_sys_aaa_server_group_name_key_xfmr: inParams.uri: %s, pathInfo: %s, inParams.requestUri: %s", inParams.uri, pathInfo, requestUriPath) + srvGrpName := reqpathInfo.Var("name") + + if srvGrpName == "" { + log.Infof("DbToYang_sys_aaa_server_group_name_key_xfmr: inParams.table: %s", inParams.table) + if inParams.table == "TACPLUS_SERVER" { + rmap["name"] = "tacacs+" + log.Info("DbToYang_sys_aaa_server_group_name_key_xfmr - Mapped TACPLUS_SERVER to name: tacacs") + return rmap, nil + } else if inParams.table == "RADIUS_SERVER" { + rmap["name"] = "radius" + log.Info("DbToYang_sys_aaa_server_group_name_key_xfmr - Mapped RADIUS_SERVER to name: radius") + return rmap, nil + } + } + + // Use inParams.key directly for mapping + serverName := inParams.key + log.Info("DbToYang_sys_aaa_server_group_name_key_xfmr - Received server group name: ", serverName) + if serverName != "tacacs+" && serverName != "radius" { + log.Error("DbToYang_sys_aaa_server_group_name_key_xfmr - Unknown server group name: ", serverName) + return nil, fmt.Errorf("unknown server group name: %s", serverName) + } + rmap["name"] = serverName + log.Info("DbToYang_sys_aaa_server_group_name_key_xfmr returns: ", rmap) + return rmap, nil +} + +var YangToDb_sys_aaa_server_group_name_field_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + var err error + + if inParams.param == nil { + return nil, invalid_input_err + } + + log.Info("YangToDb_sys_aaa_server_group_name_field_xfmr - Received input parameter:", inParams.param) + + // Attempt to cast inParams.param to a string + name, ok := inParams.param.(*string) + if !ok { + return rmap, fmt.Errorf("Expected a string, got %T", inParams.param) + } + log.Info("YangToDb_sys_aaa_server_group_name_field_xfmr - Validating server group name:", *name) + // Validate the server group name + if *name != "tacacs+" && *name != "radius" { + log.Error("Invalid server group name:", *name) + return rmap, fmt.Errorf("Invalid server group name: %s; must be either 'tacacs' or 'radius'", name) + } + return rmap, err +} + +var DbToYang_sys_aaa_server_group_name_field_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + pathInfo := NewPathInfo(inParams.uri) + serverName := pathInfo.Var("name") + + log.Info("DbToYang_sys_aaa_server_group_name_field_xfmr - inParams.uri ", inParams.uri) + + log.Info("DbToYang_sys_aaa_server_group_name_field_xfmr - Received server group name:", serverName) + // Check if the server group name is empty + if serverName == "" { + log.Error("Error: server group name is empty") + return nil, fmt.Errorf("server group name is empty") + } + + rmap["name"] = serverName + + log.Info("DbToYang_sys_aaa_server_group_name_field_xfmr returns ", rmap) + return rmap, nil // Return nil for error if everything is fine +} + +var YangToDb_sys_aaa_server_name_field_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + var err error + // Do nothing for server name as it is not stored in DB. + return rmap, err +} + +var DbToYang_sys_aaa_server_name_field_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + //Server name is not stored in DB. So, it is not possible to get the server name, retun nil + log.Info("DbToYang_sys_aaa_server_name_field_xfmr - inParams.uri ", inParams.uri) + + return rmap, nil // Return nil for error if everything is fine +} + +// modified but where should the name come frome?? +var YangToDb_sys_aaa_server_group_type_field_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + var err error + + if inParams.param == nil { + return nil, invalid_input_err + } + + serverType, ok := inParams.param.(*ocbinds.E_OpenconfigAaaTypes_AAA_SERVER_TYPE) + if !ok { + return nil, fmt.Errorf("expected string pointer for server type, got %T", inParams.param) + } + + name := inParams.key + if (name == "tacacs+" && *serverType != ocbinds.OpenconfigAaaTypes_AAA_SERVER_TYPE_TACACS) || + (name == "radius" && *serverType != ocbinds.OpenconfigAaaTypes_AAA_SERVER_TYPE_RADIUS) { + return nil, fmt.Errorf("invalid combination: name '%s' cannot be paired with type '%s'", name, *serverType) + } + return rmap, err +} + +var DbToYang_sys_aaa_server_group_type_field_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + log.Info("DbToYang_sys_aaa_server_group_type_field_xfmr - inParams.uri ", inParams.uri) + + // Extracting path information + pathInfo := NewPathInfo(inParams.uri) + serverType := pathInfo.Var("type") + + if serverType == "" { + return rmap, fmt.Errorf("server type is required") + } + + // Use the mapping to find the corresponding OpenConfig type + openConfigType, exists := aaa_sonicToOc_serverType[serverType] + if !exists { + return nil, fmt.Errorf("unknown server configuration for key: %s", serverType) + } + + rmap["type"] = openConfigType + log.Info("DbToYang_sys_aaa_server_group_type_field_xfmr returns ", rmap) + + return rmap, nil +} + +var YangToDb_sys_aaa_server_groups_address_key_xfmr KeyXfmrYangToDb = func(inParams XfmrParams) (string, error) { + pathInfo := NewPathInfo(inParams.uri) + + log.Info("YangToDb_sys_aaa_server_groups_address_key_xfmr, inParams.uri ", inParams.uri) + + address := pathInfo.Var("address") + srvGrpName := pathInfo.Var("name") + if inParams.oper == DELETE { + tblName := "" + if srvGrpName == "tacacs+" { + tblName = "TACPLUS_SERVER" + } else if srvGrpName == "radius" { + tblName = "RADIUS_SERVER" + } + if address != "" { + log.Info("YangToDb_sys_aaa_server_groups_address_key_xfmr, table, address ", tblName, address) + Tbl := &db.TableSpec{Name: tblName} + entry, dbErr := inParams.d.GetEntry(Tbl, db.Key{Comp: []string{address}}) + if dbErr != nil || !entry.IsPopulated() { + // Not returning error from here since mgmt infra will return "Resource not found" error in case of non-existence entries + return "", tlerr.InvalidArgsError{Format: "Entry not found in table " + tblName + " with key " + address} + } + if inParams.subOpDataMap[DELETE] == nil { + subOpMap := make(map[db.DBNum]map[string]map[string]db.Value) + subIntfmap_del := make(map[string]map[string]db.Value) + subIntfmap_del[tblName] = make(map[string]db.Value) + subIntfmap_del[tblName][address] = db.Value{Field: map[string]string{}} + subOpMap[db.ConfigDB] = subIntfmap_del + inParams.subOpDataMap[DELETE] = &subOpMap + } else { + subOpMap := *(inParams.subOpDataMap[DELETE]) + _, ok := subOpMap[db.ConfigDB] + if !ok { + subIntfmap_del := make(map[string]map[string]db.Value) + subOpMap[db.ConfigDB] = subIntfmap_del + } + subIntfmap_del := subOpMap[db.ConfigDB] + //Check if the the table entry is present in subIntfmap_del + _, ok2 := subIntfmap_del[tblName] + if !ok2 { + subIntfmap_del[tblName] = make(map[string]db.Value) + } + subIntfmap_del[tblName][address] = db.Value{Field: map[string]string{}} + } + } + } + + log.Info("YangToDb_sys_aaa_server_groups_address_key_xfmr ", address) + + return address, nil +} + +var DbToYang_sys_aaa_server_groups_address_key_xfmr KeyXfmrDbToYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + + serverAddress := inParams.key + log.Info("DbToYang_sys_aaa_server_groups_address_key_xfmr ", serverAddress) + if serverAddress == "" { + return nil, fmt.Errorf("Ipaddress field is missing or not a string in DB data") + } + + rmap["address"] = serverAddress + return rmap, nil +} + +var YangToDb_aaa_sys_source_address_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + res_map := make(map[string]string) + + if inParams.param == nil && inParams.oper == DELETE { + pathInfo := NewPathInfo(inParams.uri) + address := pathInfo.Var("address") + name := pathInfo.Var("name") + table := "" + key := "" + if name == "tacacs+" { + table = "TACPLUS" + key = "global" + } else if name == "radius" { + table = "RADIUS_SERVER" + key = address + } + ServerObj, err := inParams.d.GetEntry(&db.TableSpec{Name: table}, db.Key{Comp: []string{key}}) + log.Infof("YangToDb_aaa_sys_source_address_xfmr, key, table", key, table) + if err == nil || ServerObj.IsPopulated() { + ServerMap := ServerObj.Field + val, fieldExists := ServerMap["src_intf"] + if fieldExists { + log.Info("YangToDb_aaa_sys_source_address_xfmr, src_intf exists") + res_map["src_intf"] = val + return res_map, nil + } + } + return nil, nil + } + + if inParams.param == nil { + return nil, invalid_input_err + } + + pathInfo := NewPathInfo(inParams.uri) + name := pathInfo.Var("name") + src_ip, ok := inParams.param.(*string) + if !ok { + return nil, invalid_input_err + } + // IP address as string should have length greater than 6. + // For ex: 1.1.1.1, the length of the string is greater than 6. + if len(*src_ip) > 6 { + ifName, vrfName := aaa_server_fetchVrfName_InterfaceName_From_SrcIP(*src_ip, inParams) + if len(ifName) > 0 { + res_map["vrf"] = vrfName + if name == "radius" { + res_map["src_intf"] = ifName + } else if name == "tacacs+" { + tacPlusTbl := &db.TableSpec{Name: "TACPLUS"} + tacplusEntry, err := inParams.d.GetEntry(tacPlusTbl, db.Key{Comp: []string{"global"}}) + if err == nil { + src_intf := (&tacplusEntry).Get("src_intf") + if len(src_intf) != 0 { + if ifName != src_intf { + return nil, errors.New("The Entry src_intf is already set in TACPLUS for another ipaddress") + } else { // Existing interface name is same as ifName + return nil, nil + } + } + } + /* Save the src_intf to TACPLUS Table */ + key := db.Key{Comp: []string{"global"}} + value := db.Value{map[string]string{"src_intf": ifName}} + e := inParams.d.SetEntry(tacPlusTbl, key, value) + if e != nil { + log.Infof("The Entry src_intf is not set in TACPLUS") + return nil, errors.New("The Entry src_intf is not set in TACPLUS") + } + } + } + } else { + return nil, invalid_input_err + } + + return res_map, nil +} + +var DbToYang_aaa_sys_source_address_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + result := make(map[string]interface{}) + pathInfo := NewPathInfo(inParams.uri) + targetUriPath := pathInfo.YangPath + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + + name := pathInfo.Var("name") + address := pathInfo.Var("address") + data := (*inParams.dbDataMap)[inParams.curDb] + + log.Infof("DbToYang_aaa_sys_source_address_xfmr, name, inParams.table, targetUriPath", name, inParams.table, targetUriPath) + + if name == "tacacs+" && strings.HasPrefix(targetUriPath, "/openconfig-system:system/aaa/server-groups/server-group/servers/server/tacacs/config/source-address") { + tacPlusTable := &db.TableSpec{Name: "TACPLUS"} + tacPlusEntry, _ := inParams.d.GetEntry(tacPlusTable, db.Key{Comp: []string{"global"}}) + intfName := (&tacPlusEntry).Get("src_intf") + if len(intfName) > 0 { + tacplusTbl := data["TACPLUS_SERVER"] + intfData := tacplusTbl[address] + vrfName, _ := intfData.Field["vrf"] + if len(vrfName) == 0 { + vrfName = "default" + } + src_ip := get_src_addr_for_interface(intfName, vrfName, inParams) + if len(src_ip) > 0 { + result["source-address"] = src_ip + } else { + return nil, errors.New("Source address not configured properly for src_intf " + intfName) + } + } else { + return nil, errors.New("Interface is not configured " + intfName) + } + } else if name == "radius" && strings.HasPrefix(targetUriPath, "/openconfig-system:system/aaa/server-groups/server-group/servers/server/radius/config/source-address") { + tbl := data["RADIUS_SERVER"] + intfData := tbl[address] + intfName, ok := intfData.Field["src_intf"] + if ok && len(intfName) > 0 { + vrfName, _ := intfData.Field["vrf"] + if len(vrfName) == 0 { + vrfName = "default" + } + src_ip := get_src_addr_for_interface(intfName, vrfName, inParams) + if len(src_ip) > 0 { + result["source-address"] = src_ip + } else { + return nil, errors.New("Source address not configured properly for src_intf " + intfName) + } + } else { + return nil, errors.New("Interface is not configured " + intfName) + } + } + return result, nil +} + +var sys_aaa_server_groups_table_xfmr TableXfmrFunc = func(inParams XfmrParams) ([]string, error) { + var tblList []string + pathInfo := NewPathInfo(inParams.uri) + + srvGrpName := pathInfo.Var("name") + log.Info("sys_aaa_server_groups_table_xfmr srvGrpName ", srvGrpName) + tacsPlusServEntries, err1 := areEntriesPresntInTable("TACPLUS_SERVER", inParams) + radServEntries, err2 := areEntriesPresntInTable("RADIUS_SERVER", inParams) + + if srvGrpName == "" { + if inParams.oper == GET || inParams.oper == DELETE { + if inParams.dbDataMap != nil { + // Traverse server-groups tacacs+ only when TACPLUS_SERVER table has entries + // created TACPLUS_TBL temporary holder table to traverse through server-groups yang tree. + if tacsPlusServEntries && err1 == nil { + (*inParams.dbDataMap)[db.ConfigDB]["TACPLUS_TBL"] = make(map[string]db.Value) + (*inParams.dbDataMap)[db.ConfigDB]["TACPLUS_TBL"]["tacacs+"] = db.Value{Field: make(map[string]string)} + tblList = append(tblList, "TACPLUS_TBL") + } + // Traverse server-groups radius only when RADIUS_SERVER table has entries + // created RADIUS_TBL temporary holder table to traverse through server-groups yang tree. + if radServEntries && err2 == nil { + (*inParams.dbDataMap)[db.ConfigDB]["RADIUS_TBL"] = make(map[string]db.Value) + (*inParams.dbDataMap)[db.ConfigDB]["RADIUS_TBL"]["radius"] = db.Value{Field: make(map[string]string)} + tblList = append(tblList, "RADIUS_TBL") + } + } + } + log.Info("sys_aaa_server_groups_table_xfmr - Server groups get operation ") + return tblList, nil + } + + if srvGrpName == "tacacs+" { + if inParams.dbDataMap != nil { + // created TACPLUS_TBL temporary holder table to traverse through server-groups yang tree. + (*inParams.dbDataMap)[db.ConfigDB]["TACPLUS_TBL"] = make(map[string]db.Value) + (*inParams.dbDataMap)[db.ConfigDB]["TACPLUS_TBL"]["tacacs+"] = db.Value{Field: make(map[string]string)} + if inParams.oper != DELETE { + (*inParams.dbDataMap)[db.ConfigDB]["TACPLUS_TBL"]["tacacs+"].Field["NULL"] = "NULL" + } + } + tblList = append(tblList, "TACPLUS_TBL") + } else if srvGrpName == "radius" { + if inParams.dbDataMap != nil { + // created RADIUS_TBL temporary holder table to traverse through server-groups yang tree. + (*inParams.dbDataMap)[db.ConfigDB]["RADIUS_TBL"] = make(map[string]db.Value) + (*inParams.dbDataMap)[db.ConfigDB]["RADIUS_TBL"]["radius"] = db.Value{Field: make(map[string]string)} + if inParams.oper != DELETE { + (*inParams.dbDataMap)[db.ConfigDB]["RADIUS_TBL"]["radius"].Field["NULL"] = "NULL" + } + } + tblList = append(tblList, "RADIUS_TBL") + } else { + return tblList, fmt.Errorf("Invalid server group name: %s; must be either 'tacacs+' or 'radius'", srvGrpName) + } + // } + log.Info("sys_aaa_server_groups_table_xfmr Table ", tblList) + return tblList, nil +} + +func aaa_server_fetchVrfName_InterfaceName_From_SrcIP(src_ip string, inParams XfmrParams) (string, string) { + var ifName string + var vrfName string + tblList := make([]string, len(intfTblList)+1) + + tblList = append(tblList, "MGMT_INTERFACE") + copy(tblList, intfTblList) + + log.Infof("Start fetching interface for given radius/tacacs source-address ip %s ...", src_ip) + log.Infof("Fetch Interface, table list to be looked into %v", tblList) + for _, tblName := range tblList { + intfTable := &db.TableSpec{Name: tblName} + + intfKeys, err := inParams.d.GetKeysPattern(intfTable, db.Key{Comp: []string{"*", src_ip}}) + if (err != nil) || len(intfKeys) == 0 { + src_ip_w_mask := src_ip + "/*" + intfKeys, err = inParams.d.GetKeysPattern(intfTable, + db.Key{Comp: []string{"*", src_ip_w_mask}}) + } + if err == nil && len(intfKeys) > 0 { + for _, intfKey := range intfKeys { + if len(intfKey.Comp) != 2 && len(intfKey.Comp[0]) == 0 { + continue + } + ifName = intfKey.Comp[0] + ipPrefix := intfKey.Comp[1] + ipAddress := strings.Split(ipPrefix, "/") + ip := strings.Split(src_ip, "/") + if ipAddress[0] == ip[0] { + intfEntry, err := inParams.d.GetEntry(intfTable, db.Key{Comp: []string{ifName}}) + + if tblName != "MGMT_INTERFACE" { + if err == nil { + vrfName = (&intfEntry).Get("vrf_name") + log.Infof("Fetch Interface, fetched vrf for interface %s is %s", ifName, vrfName) + if vrfName == "" { + vrfName = "default" + break + } else { + /* SONiC radius and tacacs Yang models expects interface name with VRF either mgmt or default */ + vrfName = "" + ifName = "" + } + + } + } else { + mgmtVrfCfgT := &db.TableSpec{Name: "MGMT_VRF_CONFIG"} + mgmtVrfCfgE, err := inParams.d.GetEntry(mgmtVrfCfgT, db.Key{Comp: []string{"vrf_global"}}) + vrfName = "default" + if err == nil { + mgmtVrfEnabled, ok := mgmtVrfCfgE.Field["mgmtVrfEnabled"] + if ok && mgmtVrfEnabled == "true" { + vrfName = "mgmt" + } + } + break + } + } + } + } + if ifName != "" { + break + } + } + if ifName == "" { + log.Infof("Interface for the source-address %T not configured", inParams.param) + return "", "" + } + log.Infof("Interface for the source-address %T is %s, and vrf: %s", inParams.param, ifName, vrfName) + return ifName, vrfName +} + +var sys_aaa_server_table_xfmr TableXfmrFunc = func(inParams XfmrParams) ([]string, error) { + var tblList []string + pathInfo := NewPathInfo(inParams.uri) + + srvGrpName := pathInfo.Var("name") + log.Info("sys_aaa_server_table_xfmr srvGrpName ", srvGrpName) + if srvGrpName == "" { + tblList = append(tblList, "TACPLUS_SERVER") + tblList = append(tblList, "RADIUS_SERVER") + return tblList, nil + } + + if srvGrpName == "tacacs+" { + tblList = append(tblList, "TACPLUS_SERVER") + } else if srvGrpName == "radius" { + tblList = append(tblList, "RADIUS_SERVER") + } else { + return tblList, fmt.Errorf("Invalid server group name: %s; must be either 'tacacs+' or 'radius'", srvGrpName) + } + log.Info("sys_aaa_server_table_xfmr Table ", tblList) + return tblList, nil +} + +var YangToDb_aaa_server_secret_key_xfmr FieldXfmrYangToDb = func(inParams XfmrParams) (map[string]string, error) { + rmap := make(map[string]string) + var err error + + if inParams.param == nil && inParams.oper == DELETE { + pathInfo := NewPathInfo(inParams.uri) + address := pathInfo.Var("address") + name := pathInfo.Var("name") + table := "" + if name == "tacacs+" { + table = "TACPLUS_SERVER" + } else if name == "radius" { + table = "RADIUS_SERVER" + } + ServerObj, err := inParams.d.GetEntry(&db.TableSpec{Name: table}, db.Key{Comp: []string{address}}) + log.Infof("YangToDb_aaa_server_secret_key_xfmr, address, table", address, table) + if err == nil || ServerObj.IsPopulated() { + ServerMap := ServerObj.Field + val, fieldExists := ServerMap["passkey"] + if fieldExists { + log.Info("YangToDb_aaa_server_secret_key_xfmr, secret key exists") + rmap["passkey"] = val + return rmap, nil + } + } + return nil, nil + } + + if inParams.param == nil { + log.Info("YangToDb_aaa_server_secret_key_xfmr, inParams.param nil") + return nil, invalid_input_err + } + + secretkey, ok := inParams.param.(*string) + if !ok { + log.Info("YangToDb_aaa_server_secret_key_xfmr, secretkey nil") + return nil, invalid_input_err + } + rmap["passkey"] = *secretkey + return rmap, err +} + +var DbToYang_aaa_server_secret_key_xfmr FieldXfmrDbtoYang = func(inParams XfmrParams) (map[string]interface{}, error) { + rmap := make(map[string]interface{}) + pathInfo := NewPathInfo(inParams.uri) + targetUriPath := pathInfo.YangPath + + if inParams.dbDataMap == nil || (*inParams.dbDataMap)[inParams.curDb] == nil { + return nil, invalid_db_err + } + name := pathInfo.Var("name") + address := pathInfo.Var("address") + data := (*inParams.dbDataMap)[inParams.curDb] + log.Infof("DbToYang_aaa_server_secret_key_xfmr, name, inParams.table, targetUriPath", name, inParams.table, targetUriPath) + + if name == "tacacs+" && strings.HasPrefix(targetUriPath, "/openconfig-system:system/aaa/server-groups/server-group/servers/server/tacacs/config/secret-key") { + TacServerTbl := data["TACPLUS_SERVER"] + entry := TacServerTbl[address] + secretkey, ok := entry.Field["passkey"] + if !ok { + return nil, nil + } + rmap["secret-key"] = secretkey + return rmap, nil + } + + if name == "radius" && strings.HasPrefix(targetUriPath, "/openconfig-system:system/aaa/server-groups/server-group/servers/server/radius/config/secret-key") { + RadiusServerTbl := data["RADIUS_SERVER"] + entry := RadiusServerTbl[address] + secretkey, ok := entry.Field["passkey"] + if !ok { + return nil, nil + } + rmap["secret-key"] = secretkey + return rmap, nil + } + return rmap, nil +} + +func areEntriesPresntInTable(tableName string, inParams XfmrParams) (bool, error) { + tblTs := db.TableSpec{Name: tableName} + table, err := inParams.d.GetTable(&tblTs) + if err == nil { + keys, err2 := table.GetKeys() + if err2 == nil { + if len(keys) == 0 { + return false, nil + } else { // Keys are present in the table + return true, nil + } + } else { + return false, err2 + } + } + return false, err +} diff --git a/translib/transformer/xfmr_system_test.go b/translib/transformer/xfmr_system_test.go new file mode 100644 index 000000000..869e93c38 --- /dev/null +++ b/translib/transformer/xfmr_system_test.go @@ -0,0 +1,4308 @@ +////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2024 Cisco Systems, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +////////////////////////////////////////////////////////////////////////// + +//go:build testapp +// +build testapp + +package transformer_test + +import ( + "errors" + + "github.com/Azure/sonic-mgmt-common/translib/db" + + //"github.com/Azure/sonic-mgmt-common/translib/tlerr" + //"os" + "testing" + "time" +) + +var not_implemented_err error = errors.New("Not implemented") + +func Test_oc_system_config(t *testing.T) { + var pre_req_map, pre_req_map_empty, expected_map, cleanuptbl map[string]interface{} + var url, url_body_json string + + t.Log("\n\n+++++++++++++ Performing unit tests on system/config container nodes ++++++++++++") + + /* hostname */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/config/hostname node ++++++++++++") + url = "/openconfig-system:system/config" + url_body_json = "{ \"openconfig-system:hostname\": \"unittest-hostname\"}" + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname"}}} + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/config/hostname node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/config/hostname node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/config/hostname node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/config/hostname node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-2"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json := "{\"openconfig-system:hostname\":\"unittest-hostname-2\"}" + url = "/openconfig-system:system/config/hostname" + t.Run("Test get on system/config/hostname node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/config/hostname node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Delete on system/config/hostname node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-3"}}} + url = "/openconfig-system:system/config/hostname" + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"NULL": "NULL"}}} + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test delete on system/config/hostname node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on system/config/hostname node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Delete on system/config/hostname node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/config/hostname node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-old"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/config/hostname" + url_body_json = "{ \"openconfig-system:hostname\": \"unittest-hostname-new\"}" + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-new"}}} + t.Run("Test PATCH(Update) on system/config/hostname node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/config/hostname node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/config/hostname node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/config/hostname node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-old"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/config/hostname" + url_body_json = "{ \"openconfig-system:hostname\": \"unittest-hostname-new\"}" + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-new"}}} + t.Run("Test PUT(Replace) on system/config/hostname node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/config/hostname node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/config/hostname node ++++++++++++") + + /* login-banner */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/config/login-banner node ++++++++++++") + url = "/openconfig-system:system/config" + url_body_json = "{ \"openconfig-system:login-banner\": \"unittest login banner\"}" + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/config/login-banner node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/config/login-banner node", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/config/login-banner node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/config/login-banner node ++++++++++++") + pre_req_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 2"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:login-banner\":\"unittest login banner 2\"}" + url = "/openconfig-system:system/config/login-banner" + t.Run("Test get on system/config/login-banner node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{}}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/config/login-banner node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Delete on system/config/login-banner node ++++++++++++") + pre_req_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 2"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/config/login-banner" + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"NULL": "NULL"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + time.Sleep(1 * time.Second) + t.Run("Test Delete on system/config/login-banner node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify Delete on system/config/login-banner node", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Delete on system/config/login-banner node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/config/login-banner node ++++++++++++") + pre_req_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner old"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/config/login-banner" + url_body_json = "{ \"openconfig-system:login-banner\": \"unittest login banner new\"}" + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner new"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/config/login-banner node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/config/login-banner node", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/config/login-banner node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/config/login-banner node ++++++++++++") + pre_req_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner old"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/config/login-banner" + url_body_json = "{ \"openconfig-system:login-banner\": \"unittest login banner new\"}" + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner new"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/config/login-banner node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/config/login-banner node", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/config/login-banner node ++++++++++++") + + /* motd-banner */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/config/motd-banner node ++++++++++++") + url = "/openconfig-system:system/config" + url_body_json = "{ \"openconfig-system:motd-banner\": \"unittest motd banner\"}" + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"motd": "unittest motd banner"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/config/motd-banner node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/config/motd-banner node", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/config/motd-banner node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/config/motd-banner node ++++++++++++") + pre_req_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"motd": "unittest motd banner 2"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:motd-banner\":\"unittest motd banner 2\"}" + url = "/openconfig-system:system/config/motd-banner" + t.Run("Test get on system/config/motd-banner node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/config/motd-banner node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Delete on system/config/motd-banner node ++++++++++++") + pre_req_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"motd": "unittest motd banner 2"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/config/motd-banner" + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"NULL": "NULL"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + time.Sleep(1 * time.Second) + t.Run("Test Delete on system/config/motd-banner node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify Delete on system/config/motd-banner node", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Delete on system/config/motd-banner node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/config/motd-banner node ++++++++++++") + pre_req_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"motd": "unittest motd banner old"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/config/motd-banner" + url_body_json = "{ \"openconfig-system:motd-banner\": \"unittest motd banner new\"}" + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"motd": "unittest motd banner new"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/config/motd-banner node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/config/motd-banner node", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/config/motd-banner node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/config/motd-banner node ++++++++++++") + pre_req_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"motd": "unittest motd banner old"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/config/motd-banner" + url_body_json = "{ \"openconfig-system:motd-banner\": \"unittest motd banner new\"}" + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"motd": "unittest motd banner new"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/config/motd-banner node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/config/motd-banner node", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/config/motd-banner node ++++++++++++") + + /* config container */ + t.Log("\n\n+++++++++++++ Performing Get on system/config node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-3"}}, "BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 3", "motd": "unittest motd banner 3"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:config\":{\"hostname\":\"unittest-hostname-3\", \"login-banner\":\"unittest login banner 3\", \"motd-banner\":\"unittest motd banner 3\"}}" + url = "/openconfig-system:system/config" + t.Run("Test get on system/config node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + /* + expected_get_json = "{\"openconfig-system:system\": {\"config\":{\"hostname\":\"unittest-hostname-3\", \"login-banner\":\"unittest login banner 3\", \"motd-banner\":\"unittest motd banner 3\"}}}" + url = "/openconfig-system:system" + t.Run("Test get on system node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + */ + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}, "BANNER_MESSAGE": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/config node ++++++++++++") + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system" + url_body_json = "{ \"openconfig-system:config\": {\"hostname\": \"unittest-hostname-4\", \"login-banner\":\"unittest login banner 4\", \"motd-banner\":\"unittest motd banner 4\"}}" + t.Run("Test POST(Create) on system/config node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-4"}}} + t.Run("Verify POST(Create) on system/config node DEV_META", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 4", "motd": "unittest motd banner 4"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + t.Run("Verify POST(Create) on system/config node BANNERS", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Delete on system/config node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-3"}}, "BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 3", "motd": "unittest motd banner 3"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/config" + t.Run("Test Delete on system/config node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify Delete on system/config node DEV_META", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"NULL": "NULL"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + t.Run("Verify Delete on system/config node BANNERS", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Delete on system/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/config node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-3"}}, "BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 3", "motd": "unittest motd banner 3"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/config" + url_body_json = "{ \"openconfig-system:config\": {\"hostname\": \"unittest-hostname-4\", \"login-banner\":\"unittest login banner 4\", \"motd-banner\":\"unittest motd banner 4\"}}" + t.Run("Test PATCH(Update) on system/config node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-4"}}} + t.Run("Verify PATCH(Update) on system/config node DEV_META", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 4", "motd": "unittest motd banner 4"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + t.Run("Verify PATCH(Update) on system/config node BANNERS", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/config node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-3"}}, "BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 3", "motd": "unittest motd banner 3"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/config" + url_body_json = "{ \"openconfig-system:config\": {\"hostname\": \"unittest-hostname-4\", \"login-banner\":\"unittest login banner 4\", \"motd-banner\":\"unittest motd banner 4\"}}" + t.Run("Test PUT(Replace) on system/config node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"hostname": "unittest-hostname-4"}}} + t.Run("Verify PUT(Replace) on system/config node DEV_META", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": map[string]interface{}{"login": "unittest login banner 4", "motd": "unittest motd banner 4"}}} + cleanuptbl = map[string]interface{}{"BANNER_MESSAGE": map[string]interface{}{"global": ""}} + t.Run("Verify PUT(Replace) on system/config node BANNERS", verifyDbResult(rclient, "BANNER_MESSAGE|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Done Performing unit tests on system/config container nodes ++++++++++++") +} + +func Test_oc_system_state(t *testing.T) { + var url string + //var expected_get_json string + + t.Log("\n\n+++++++++++++ Performing unit tests on system/state container nodes ++++++++++++") + + /* hostname */ + t.Log("\n\n+++++++++++++ Performing Get on system/state/hostname node ++++++++++++") + url = "/openconfig-system:system/state/hostname" + t.Run("Test get on system/state/hostname node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/state/hostname node ++++++++++++") + + /* login-banner */ + t.Log("\n\n+++++++++++++ Performing Get on system/state/login-banner node ++++++++++++") + url = "/openconfig-system:system/state/login-banner" + t.Run("Test get on system/state/login-banner node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/state/login-banner node ++++++++++++") + + /* motd-banner */ + t.Log("\n\n+++++++++++++ Performing Get on system/state/motd-banner node ++++++++++++") + url = "/openconfig-system:system/state/motd-banner" + t.Run("Test get on system/state/motd-banner node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/state/motd-banner node ++++++++++++") + + /* current-datetime */ + /* + t.Log("\n\n+++++++++++++ Performing Get on system/state/current-datetime node ++++++++++++") + expected_get_json = "{\"openconfig-system:current-datetime\":\"2024-08-15T10:11:41Z+00:00\"}" + url = "/openconfig-system:system/state/current-datetime" + t.Run("Test get on system/state/current-datetime node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing Get on system/state/current-datetime node ++++++++++++") + */ + + /* up-time */ + /* + t.Log("\n\n+++++++++++++ Performing Get on system/state/up-time node ++++++++++++") + expected_get_json = "{\"openconfig-system:up-time\":\"13627000000000\"}" + url = "/openconfig-system:system/state/up-time" + t.Run("Test get on system/state/up-time node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/state/up-time node ++++++++++++") + */ + + /* boot-time */ + /* + t.Log("\n\n+++++++++++++ Performing Get on system/state/boot-time node ++++++++++++") + expected_get_json = "{\"openconfig-system:boot-time\":\"1698025723767651793\"}" + url = "/openconfig-system:system/state/boot-time" + t.Run("Test get on system/state/boot-time node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/state/boot-time node ++++++++++++") + */ + + /* software-version */ + //On Azure pipeline, /etc/ access is not there + /*t.Log("\n\n+++++++++++++ Performing Get on system/state/software-version node ++++++++++++") + os.MkdirAll("/etc/sonic", 0755) + yamlContent := []byte("build_version: sonic-version\n") + if err := os.WriteFile("/etc/sonic/sonic_version.yml", yamlContent, 0644); err != nil { + t.Fatalf("failed to write sonic_version.yml: %v", err) + } + expected_get_json = "{\"openconfig-system:software-version\":\"sonic-version\"}" + url = "/openconfig-system:system/state/software-version" + t.Run("Test get on system/state/software-version node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + os.Remove("/etc/sonic/sonic_version.yml") + t.Log("\n\n+++++++++++++ Done Performing Get on system/state/software-version node ++++++++++++") + */ + + /* state container */ + /* + t.Log("\n\n+++++++++++++ Performing Get on system/state node ++++++++++++") + pre_req_map = map[string]interface{}{"VERSIONS": map[string]interface{}{"SOFTWARE": map[string]interface{}{"VERSION": "unittest sonic version"}, "DATABASE": map[string]interface{}{"VERSION": "unittest database version"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:state\":{\"boot-time\":\"1698025723717492667\", \"current-datetime\":\"2024-08-15T11:10:46Z+00:00\", \"up-time\":\"25694523000000000\", \"software-version\":\"unittest sonic version\"}}" + url = "/openconfig-system:system/state" + t.Run("Test get on system/state node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + expected_get_json = "{\"openconfig-system:system\":{\"state\":{\"boot-time\":\"1698025723717492667\", \"current-datetime\":\"2024-08-15T11:10:46Z+00:00\", \"up-time\":\"25694523000000000\", \"software-version\":\"unittest sonic version\"}}}" + url = "/openconfig-system:system" + t.Run("Test get on system node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"VERSIONS": map[string]interface{}{"SOFTWARE": "", "DATABASE": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/state node ++++++++++++") + */ + + t.Log("\n\n+++++++++++++ Done Performing unit tests on system/state container nodes ++++++++++++") +} + +func Test_oc_system_processes(t *testing.T) { + var pre_req_map, cleanuptbl map[string]interface{} + var url string + + t.Log("\n\n+++++++++++++ Performing Get on system/processes node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/processes supported nodes ++++++++++++") + pre_req_map = map[string]interface{}{"PROCESS_STATS": map[string]interface{}{"60000": map[string]interface{}{"%CPU": "5.3", "%MEM": "20.4", "CMD": "ut-proc-name --ut-arg1 --ut-arg2"}}} + loadDB(db.StateDB, pre_req_map) + expected_get_json := "{\"openconfig-system:process\":[{\"pid\":\"60000\",\"state\":{\"args\":[\"--ut-arg1\",\"--ut-arg2\"],\"cpu-utilization\":5,\"memory-utilization\":20,\"name\":\"ut-proc-name\",\"pid\":\"60000\"}}]}" + url = "/openconfig-system:system/processes/process" + t.Run("Test get on system/processes node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/processes supported nodes ++++++++++++") + + t.Log("\n\n+++++++++++++ Done Performing Get on system/processes node ++++++++++++") +} + +func Test_oc_system_clock(t *testing.T) { + var pre_req_map, pre_req_map_empty, expected_map, cleanuptbl map[string]interface{} + var url, url_body_json string + + t.Log("\n\n+++++++++++++ Performing unit tests on system/clock container nodes ++++++++++++") + + /* timezone-name */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/clock/config node ++++++++++++") + url = "/openconfig-system:system/clock/config" + url_body_json = "{ \"openconfig-system:timezone-name\": \"Cuba\"}" + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "Cuba"}}} + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/clock/config/timezone-name node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/clock/config/timezone-name node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/clock/config/timezone-name node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/clock/config node (Wrong input) ++++++++++++") + url = "/openconfig-system:system/clock/config" + url_body_json = "{ \"openconfig-system:timezone-name\": \"India\"}" + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + expected_err := errors.New("Timezone India does not conform format") + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/clock/config/timezone-name node", processSetRequest(url, url_body_json, "POST", true, expected_err)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/clock/config/timezone-name node (Wrong input) ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Delete on system/clock/config/timezone-name node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "Indian/Mauritius"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/clock/config/timezone-name" + t.Run("Test delete on system/clock/config/timezone-name node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify POST(Create) on system/clock/config/timezone-name node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Delete on system/clock/config/timezone-name node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/clock/config/timezone-name node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "Indian/Mauritius"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json := "{\"openconfig-system:timezone-name\":\"Indian/Mauritius\"}" + url = "/openconfig-system:system/clock/config/timezone-name" + t.Run("Test get on system/clock/config/timezone-name node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + expected_get_json = "{\"openconfig-system:clock\":{\"config\":{\"timezone-name\":\"Indian/Mauritius\"}}}" + url = "/openconfig-system:system/clock" + t.Run("Test get on system/clock node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/clock/config/timezone-name node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/clock/config node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "Indian/Mauritius"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/clock/config" + url_body_json = "{ \"openconfig-system:config\": { \"timezone-name\": \"Cuba\"}}" + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "Cuba"}}} + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/clock/config/timezone-name node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/clock/config/timezone-name node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/clock/config/timezone-name node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/clock/config node ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "Indian/Mauritius"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system" + url_body_json = "{ \"openconfig-system:system\": {\"clock\": {\"config\": { \"timezone-name\": \"Cuba\"}}}}" + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "Cuba"}}} + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/clock/config/timezone-name node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/clock/config/timezone-name node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/clock/config/timezone-name node ++++++++++++") + + // config post + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/clock/config node ++++++++++++") + url = "/openconfig-system:system/clock/config" + url_body_json = "{ \"openconfig-system:timezone-name\": \"UTC\"}" + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "UTC"}}} + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/clock/config node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/clock/config node", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/clock/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Delete on system/clock/config ++++++++++++") + pre_req_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"timezone": "UTC"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/clock/config" + t.Run("Test delete on system/clock/config node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + expected_map = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify POST(Create) on system/clock/config", verifyDbResult(rclient, "DEVICE_METADATA|localhost", expected_map, false)) + + cleanuptbl = map[string]interface{}{"DEVICE_METADATA": map[string]interface{}{"localhost": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Delete on system/clock/config node ++++++++++++") + + /* clock/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/clock/state node ++++++++++++") + url = "/openconfig-system:system/clock/state" + t.Run("Test get on system/clock/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/clock/state node ++++++++++++") +} + +func Test_oc_system_ssh_server(t *testing.T) { + var pre_req_map, pre_req_map_empty, expected_map, cleanuptbl map[string]interface{} + var url, url_body_json string + + t.Log("\n\n+++++++++++++ Performing unit tests on system/ssh-server container nodes ++++++++++++") + + /* timeout */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/ssh-server/config node ++++++++++++") + url = "/openconfig-system:system/ssh-server/config" + url_body_json = "{ \"openconfig-system:timeout\": 500}" + expected_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"login_timeout": "500"}}} + cleanuptbl = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/ssh-server/config/timeout node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/ssh-server/config/timeout node", verifyDbResult(rclient, "SSH_SERVER|POLICIES", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/ssh-server/config/timeout node ++++++++++++") + + /* + t.Log("\n\n+++++++++++++ Performing Invalid Set on system/ssh-server/config node (Wrong input) ++++++++++++") + url = "/openconfig-system:system/ssh-server/config" + url_body_json = "{ \"openconfig-system:timeout\": 700}" + cleanuptbl = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + expected_err = tlerr.InvalidArgsError{Format: "Field \"login_timeout\" has invalid value \"700\""} + time.Sleep(1 * time.Second) + t.Run("Test invalid set on system/ssh-server/config/timeout node", processSetRequest(url, url_body_json, "POST", true, expected_err)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Invalid Set on system/ssh-server/config/timeout node (Wrong input) ++++++++++++") + */ + + t.Log("\n\n+++++++++++++ Performing Get on system/ssh-server/config/timeout node ++++++++++++") + pre_req_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"login_timeout": "300"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json := "{\"openconfig-system:timeout\":300}" + url = "/openconfig-system:system/ssh-server/config/timeout" + t.Run("Test get on system/ssh-server/config/timeout node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ssh-server/config/timeout node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/ssh-server/config node ++++++++++++") + pre_req_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"login_timeout": "300"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system" + expected_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{}}} + cleanuptbl = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": ""}} + time.Sleep(1 * time.Second) + t.Run("Test DELETE on system/ssh-server/config/timeout node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify DELETE on system/ssh-server/config/timeout node", verifyDbResult(rclient, "SSH_SERVER|POLICIES", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing DELETE on system/ssh-server/config/timeout node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/ssh-server/config top level node ++++++++++++") + pre_req_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"login_timeout": "300"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ssh-server/config" + expected_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"NULL": "NULL"}}} + cleanuptbl = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": ""}} + time.Sleep(1 * time.Second) + t.Run("Test DELETE on system/ssh-server/config/ node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify DELETE on system/ssh-server/config/timeout node", verifyDbResult(rclient, "SSH_SERVER|POLICIES", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing DELETE on system/ssh-server/config/ top level node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/ssh-server/config node ++++++++++++") + pre_req_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"login_timeout": "300"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ssh-server/config/timeout" + url_body_json = "{ \"openconfig-system:timeout\": 500}" + expected_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"login_timeout": "500"}}} + cleanuptbl = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/ssh-server/config/timeout node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/ssh-server/config/timeout node", verifyDbResult(rclient, "SSH_SERVER|POLICIES", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/ssh-server/config/timeout node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/ssh-server/config node ++++++++++++") + pre_req_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"login_timeout": "300"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ssh-server/config/timeout" + url_body_json = "{ \"openconfig-system:timeout\": 500}" + expected_map = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": map[string]interface{}{"login_timeout": "500"}}} + cleanuptbl = map[string]interface{}{"SSH_SERVER": map[string]interface{}{"POLICIES": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/ssh-server/config/timeout node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/ssh-server/config/timeout node", verifyDbResult(rclient, "SSH_SERVER|POLICIES", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/ssh-server/config/timeout node ++++++++++++") + + /* ssh-server/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/ssh-server/state node ++++++++++++") + url = "/openconfig-system:system/ssh-server/state" + t.Run("Test get on system/ssh-server/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ssh-server/state node ++++++++++++") + + /* ssh-server/state/timeout */ + t.Log("\n\n+++++++++++++ Performing Get on system/ssh-server/state/timeout node ++++++++++++") + url = "/openconfig-system:system/ssh-server/state/timeout" + t.Run("Test get on system/ssh-server/state/timeout node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ssh-server/state/timeout node ++++++++++++") + + t.Log("\n\n+++++++++++++ Done Performing unit tests on system/ssh-server container nodes ++++++++++++") +} + +func Test_oc_system_messages(t *testing.T) { + var pre_req_map, pre_req_map_empty, expected_map, cleanuptbl map[string]interface{} + var url, url_body_json string + + t.Log("\n\n+++++++++++++ Performing unit tests on system/messages container nodes ++++++++++++") + + /* severity */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/messages/config/severity node ++++++++++++") + url = "/openconfig-system:system/messages/config" + url_body_json = "{ \"openconfig-system:severity\": \"ERROR\"}" + expected_map = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": map[string]interface{}{"severity": "error"}}} + cleanuptbl = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/messages/config/severity node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/messages/config/severity node", verifyDbResult(rclient, "SYSLOG_CONFIG|GLOBAL", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/messages/config/severity node ++++++++++++") + // Final cleanup for SYSLOG_CONFIG + cleanuptbl = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + /* + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/messages/config/severity node (Wrong input) ++++++++++++") + url = "/openconfig-system:system/messages/config" + url_body_json = "{ \"openconfig-system:severity\": \"WRONG-SEV\"}" + cleanuptbl = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + expected_err = errors.New("Invalid input") + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/messages/config/severity node", processSetRequest(url, url_body_json, "POST", true, expected_err)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/messages/config/severity node (Wrong input) ++++++++++++") + */ + + t.Log("\n\n+++++++++++++ Performing Get on system/messages/config/severity node ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": map[string]interface{}{"severity": "crit"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json := "{\"openconfig-system:severity\":\"CRITICAL\"}" + url = "/openconfig-system:system/messages/config/severity" + t.Run("Test get on system/messages/config/severity node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + expected_get_json = "{\"openconfig-system:messages\":{\"config\":{\"severity\":\"CRITICAL\"}}}" + url = "/openconfig-system:system/messages" + t.Run("Test get on system/messages node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/messages/config/severity node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Delete on system/messages/config/severity node ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": map[string]interface{}{"severity": "crit"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/messages/config" + expected_map = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": map[string]interface{}{}}} + cleanuptbl = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": ""}} + time.Sleep(1 * time.Second) + t.Run("Test Delete on system/messages/config/severity node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify Delete on system/messages/config/severity node", verifyDbResult(rclient, "SYSLOG_CONFIG|GLOBAL", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Delete on system/messages/config/severity node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/messages/config/severity node ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": map[string]interface{}{"severity": "crit"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/messages/config/severity" + url_body_json = "{ \"openconfig-system:severity\": \"ERROR\"}" + expected_map = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": map[string]interface{}{"severity": "error"}}} + cleanuptbl = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/messages/config/severity node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/messages/config/severity node", verifyDbResult(rclient, "SYSLOG_CONFIG|GLOBAL", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/messages/config/severity node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/messages/config/severity node ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": map[string]interface{}{"severity": "crit"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/messages/config/severity" + url_body_json = "{ \"openconfig-system:severity\": \"ERROR\"}" + expected_map = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": map[string]interface{}{"severity": "error"}}} + cleanuptbl = map[string]interface{}{"SYSLOG_CONFIG": map[string]interface{}{"GLOBAL": ""}} + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/messages/config/severity node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/messages/config/severity node", verifyDbResult(rclient, "SYSLOG_CONFIG|GLOBAL", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/messages/config/severity node ++++++++++++") + + /* messages/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/messages/state node ++++++++++++") + url = "/openconfig-system:system/messages/state" + t.Run("Test get on system/messages/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/messages/state node ++++++++++++") + + t.Log("\n\n+++++++++++++ Done Performing unit tests on system/messages container nodes ++++++++++++") +} + +func Test_oc_system_logging(t *testing.T) { + var pre_req_map, expected_map, cleanuptbl map[string]interface{} + var url, url_body_json, expected_get_json string + + t.Log("\n\n+++++++++++++ Performing unit tests on system/logging container nodes ++++++++++++") + + /* remote-servers/remote-server */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/logging/remote-servers/remote-server node ++++++++++++") + url = "/openconfig-system:system/logging/remote-servers" + url_body_json = "{\"openconfig-system:remote-server\": [{\"host\": \"1.1.1.1\", \"config\": { \"host\": \"1.1.1.1\", \"source-address\": \"10.10.10.10\", \"network-instance\": \"Vrf1\", \"remote-port\": 10000 } } ]}" + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"source": "10.10.10.10", "vrf": "Vrf1", "port": "10000"}}} + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"1.1.1.1": ""}} + pre_req_map = map[string]interface{}{"VRF": map[string]interface{}{"Vrf1": map[string]interface{}{"vni": 100}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/logging/remote-servers/remote-server node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/logging/remote-servers/remote-server node", verifyDbResult(rclient, "SYSLOG_SERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/logging/remote-servers/remote-server node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/logging/remote-servers/remote-server node ++++++++++++") + pre_req_map = map[string]interface{}{"VRF": map[string]interface{}{"Vrf2": map[string]interface{}{"vni": 200}}, "SYSLOG_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"source": "20.20.20.20", "vrf": "Vrf2", "port": "20000"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:config\": { \"host\": \"2.2.2.2\", \"source-address\": \"20.20.20.20\", \"network-instance\": \"Vrf2\", \"remote-port\": 20000 } }" + url = "/openconfig-system:system/logging/remote-servers/remote-server[host=2.2.2.2]/config" + t.Run("Test get on system/logging/remote-servers/remote-server node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/logging/remote-servers/remote-server node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/logging node ++++++++++++") + expected_get_json = "{\"openconfig-system:logging\": {\"remote-servers\": { \"remote-server\": [{\"host\": \"2.2.2.2\", \"config\": { \"host\": \"2.2.2.2\", \"source-address\": \"20.20.20.20\", \"network-instance\": \"Vrf2\", \"remote-port\": 20000 } } ]}}}" + url = "/openconfig-system:system/logging" + t.Run("Test get on system/logging node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"2.2.2.2": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/logging node ++++++++++++") + + /* logging/remote-servers/remote-server/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/logging/remote-servers/remote-server/state node ++++++++++++") + url = "/openconfig-system:system/logging/remote-servers/remote-server/state" + t.Run("Test get on system/logging/remote-servers/remote-server/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/logging/remote-servers/remote-server/state node ++++++++++++") + + /* remote-servers/remote-server/selectors/selector */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/logging/remote-servers/remote-server/selectors/selector node ++++++++++++") + pre_req_map = map[string]interface{}{"VRF": map[string]interface{}{"Vrf3": map[string]interface{}{"vni": 300}, "Vrf4": map[string]interface{}{"vni": 400}}, "SYSLOG_SERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"source": "30.30.30.30", "vrf": "Vrf3", "port": "30000"}}} + url = "/openconfig-system:system/logging/remote-servers/remote-server[host=3.3.3.3]/selectors" + url_body_json = "{\"openconfig-system:selector\": [{\"facility\": \"ALL\", \"severity\": \"DEBUG\", \"config\": { \"facility\": \"ALL\", \"severity\": \"DEBUG\" } } ]}" + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"source": "30.30.30.30", "vrf": "Vrf3", "port": "30000", "severity": "debug"}}} + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"3.3.3.3": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/logging/remote-servers/remote-server/selectors/selector node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/logging/remote-servers/remote-server/selectors/selector node", verifyDbResult(rclient, "SYSLOG_SERVER|3.3.3.3", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/logging/remote-servers/remote-server/selectors/selector node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/logging/remote-servers/remote-server/selectors/selector node ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": map[string]interface{}{"source": "40.40.40.40", "vrf": "Vrf4", "port": "40000", "severity": "info"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:selector\": [{\"facility\": \"openconfig-system-logging:ALL\", \"severity\": \"INFORMATIONAL\", \"config\": { \"facility\": \"openconfig-system-logging:ALL\", \"severity\": \"INFORMATIONAL\" } } ]}" + url = "/openconfig-system:system/logging/remote-servers/remote-server[host=4.4.4.4]/selectors/selector" + t.Run("Test get on system/logging/remote-servers/remote-server/selectors/selector node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/logging/remote-servers/remote-server/selectors/selector node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/logging node ++++++++++++") + expected_get_json = "{\"openconfig-system:logging\": {\"remote-servers\": { \"remote-server\": [{\"host\": \"4.4.4.4\", \"config\": { \"host\": \"4.4.4.4\", \"source-address\": \"40.40.40.40\", \"network-instance\": \"Vrf4\", \"remote-port\": 40000 }, \"selectors\": { \"selector\": [{\"facility\": \"openconfig-system-logging:ALL\", \"severity\": \"INFORMATIONAL\", \"config\": { \"facility\": \"openconfig-system-logging:ALL\", \"severity\": \"INFORMATIONAL\" } } ] }}]}}}" + url = "/openconfig-system:system/logging" + t.Run("Test get on system/logging node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/logging node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/logging/remote-servers/remote-server node ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": map[string]interface{}{"source": "40.40.40.40", "vrf": "Vrf4", "port": "40000", "severity": "info"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/logging/remote-servers/remote-server[host=4.4.4.4]" + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{}} + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": ""}} + time.Sleep(1 * time.Second) + t.Run("Test DELETE on system/logging/remote-servers/remote-server[host=4.4.4.4] node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify DELETE on system/logging/remote-servers/remote-server[host=4.4.4.4] node", verifyDbResult(rclient, "SYSLOG_SERVER|3.3.3.3", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing DELETE on system/logging/remote-servers/remote-server node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/logging/remote-servers node ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": map[string]interface{}{"source": "40.40.40.40", "vrf": "Vrf4", "port": "40000", "severity": "info"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/logging/remote-servers" + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{}} + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": ""}} + time.Sleep(1 * time.Second) + t.Run("Test DELETE on system/logging/remote-servers node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify DELETE on system/logging/remote-servers node", verifyDbResult(rclient, "SYSLOG_SERVER|3.3.3.3", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing DELETE on system/logging/remote-servers node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/logging/remote-servers/remote-server ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": map[string]interface{}{"source": "40.40.40.40", "vrf": "Vrf4", "port": "40000", "severity": "info"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/logging/remote-servers/remote-server[host=4.4.4.4]" + url_body_json = "{\"openconfig-system:remote-server\": [{ \"host\": \"4.4.4.4\", \"config\": { \"host\": \"4.4.4.4\", \"source-address\": \"10.10.10.10\", \"network-instance\": \"Vrf1\", \"remote-port\": 10000}, \"selectors\": { \"selector\": [{\"facility\": \"ALL\", \"severity\": \"DEBUG\", \"config\": { \"facility\": \"ALL\", \"severity\": \"DEBUG\" } } ]}}]}" + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": map[string]interface{}{"source": "10.10.10.10", "vrf": "Vrf1", "port": "10000", "severity": "debug"}}} + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/logging/remote-servers/remote-server node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/logging/remote-servers/remote-server node", verifyDbResult(rclient, "SYSLOG_SERVER|4.4.4.4", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"4.4.4.4": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/logging/remote-servers/remote-server node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/logging ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"source": "10.10.10.10", "vrf": "Vrf1", "port": "10000", "severity": "info"}, "2.2.2.2": map[string]interface{}{"source": "20.20.20.20", "vrf": "Vrf2", "port": "20000", "severity": "debug"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/logging" + url_body_json = "{\"openconfig-system:logging\": { \"remote-servers\": { \"remote-server\": [{ \"host\": \"3.3.3.3\", \"config\": { \"host\": \"3.3.3.3\", \"source-address\": \"30.30.30.30\", \"network-instance\": \"Vrf3\", \"remote-port\": 30000}, \"selectors\": { \"selector\": [{\"facility\": \"ALL\", \"severity\": \"DEBUG\", \"config\": { \"facility\": \"ALL\", \"severity\": \"DEBUG\" } } ]}}, { \"host\": \"1.1.1.1\", \"config\": { \"host\": \"1.1.1.1\", \"source-address\": \"40.40.40.40\", \"network-instance\": \"Vrf4\", \"remote-port\": 40000}, \"selectors\": { \"selector\": [{\"facility\": \"ALL\", \"severity\": \"DEBUG\", \"config\": { \"facility\": \"ALL\", \"severity\": \"DEBUG\" } } ]}}]}}}" + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/logging node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"source": "30.30.30.30", "vrf": "Vrf3", "port": "30000", "severity": "debug"}}} + t.Run("Verify PUT(Replace) on system/logging node [create]", verifyDbResult(rclient, "SYSLOG_SERVER|3.3.3.3", expected_map, false)) + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"source": "40.40.40.40", "vrf": "Vrf4", "port": "40000", "severity": "debug"}}} + t.Run("Verify PUT(Replace) on system/logging node [update]", verifyDbResult(rclient, "SYSLOG_SERVER|1.1.1.1", expected_map, false)) + /*expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{}}} + t.Run("Verify PUT(Replace) on system/logging node [delete]", verifyDbResult(rclient, "SYSLOG_SERVER|2.2.2.2", expected_map, false))*/ + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"1.1.1.1": "", "2.2.2.2": "", "3.3.3.3": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/logging node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/logging/remote-servers ++++++++++++") + pre_req_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"source": "10.10.10.10", "vrf": "Vrf1", "port": "10000", "severity": "info"}, "2.2.2.2": map[string]interface{}{"source": "20.20.20.20", "vrf": "Vrf2", "port": "20000", "severity": "debug"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/logging/remote-servers" + url_body_json = "{\"openconfig-system:remote-servers\": { \"remote-server\": [{ \"host\": \"3.3.3.3\", \"config\": { \"host\": \"3.3.3.3\", \"source-address\": \"30.30.30.30\", \"network-instance\": \"Vrf3\", \"remote-port\": 30000}, \"selectors\": { \"selector\": [{\"facility\": \"ALL\", \"severity\": \"DEBUG\", \"config\": { \"facility\": \"ALL\", \"severity\": \"DEBUG\" } } ]}}, { \"host\": \"1.1.1.1\", \"config\": { \"host\": \"1.1.1.1\", \"source-address\": \"40.40.40.40\", \"network-instance\": \"Vrf4\", \"remote-port\": 40000}, \"selectors\": { \"selector\": [{\"facility\": \"ALL\", \"severity\": \"DEBUG\", \"config\": { \"facility\": \"ALL\", \"severity\": \"DEBUG\" } } ]}}]}}" + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/logging/remote-servers node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"source": "30.30.30.30", "vrf": "Vrf3", "port": "30000", "severity": "debug"}}} + t.Run("Verify PUT(Replace) on system/logging/remote-servers node [create]", verifyDbResult(rclient, "SYSLOG_SERVER|3.3.3.3", expected_map, false)) + expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"source": "40.40.40.40", "vrf": "Vrf4", "port": "40000", "severity": "debug"}}} + t.Run("Verify PUT(Replace) on system/logging/remote-servers node [update]", verifyDbResult(rclient, "SYSLOG_SERVER|1.1.1.1", expected_map, false)) + /*expected_map = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{}}} + t.Run("Verify PUT(Replace) on system/logging/remote-servers node [delete]", verifyDbResult(rclient, "SYSLOG_SERVER|2.2.2.2", expected_map, false))*/ + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"SYSLOG_SERVER": map[string]interface{}{"1.1.1.1": "", "2.2.2.2": "", "3.3.3.3": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/logging/remote-servers node ++++++++++++") + + /* logging/remote-servers/remote-server/selectors/selector/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/logging/remote-servers/remote-server/selectors/selector/state node ++++++++++++") + url = "/openconfig-system:system/logging/remote-servers/remote-server/selectors/selector/state" + t.Run("Test get on system/logging/remote-servers/remote-server/selectors/selector/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/logging/remote-servers/remote-server/selectors/selector/state node ++++++++++++") + + cleanuptbl = map[string]interface{}{"VRF": map[string]interface{}{"Vrf1": "", "Vrf2": "", "Vrf3": "", "Vrf4": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + t.Log("\n\n+++++++++++++ Done Performing unit tests on system/logging container nodes ++++++++++++") +} + +func Test_oc_system_ntp(t *testing.T) { + var pre_req_map, pre_req_map_empty, expected_map, cleanuptbl map[string]interface{} + var url, url_body_json string + + t.Log("\n\n+++++++++++++ Performing unit tests on system/ntp/config container nodes ++++++++++++") + + /* enabled */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/ntp/config/enabled node ++++++++++++") + url = "/openconfig-system:system/ntp/config" + url_body_json = "{ \"openconfig-system:enabled\": true}" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "authentication": "disabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/ntp/config/enabled node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/ntp/config/enabled node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/ntp/config/enabled node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/ntp/config/enabled node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "disabled"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json := "{\"openconfig-system:enabled\":false}" + url = "/openconfig-system:system/ntp/config/enabled" + t.Run("Test get on system/ntp/config/enabled node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp/config/enabled node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing delete on system/ntp/config/enabled node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + url = "/openconfig-system:system/ntp/config/enabled" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "disabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test delete on system/ntp/config/enabled node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on system/ntp/config/enabled node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing delete on system/ntp/config/enabled node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/ntp/config/enabled node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "disabled"}}} + url = "/openconfig-system:system/ntp/config/enabled" + url_body_json = "{ \"openconfig-system:enabled\": true}" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/ntp/config/enabled node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/ntp/config/enabled node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/ntp/config/enabled node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/ntp/config/enabled node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + url = "/openconfig-system:system/ntp/config/enabled" + url_body_json = "{ \"openconfig-system:enabled\": false}" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "disabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/ntp/config/enabled node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/ntp/config/enabled node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/ntp/config/enabled node ++++++++++++") + + /* enable-ntp-auth */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/ntp/config/enable-ntp-auth node ++++++++++++") + url = "/openconfig-system:system/ntp/config" + url_body_json = "{ \"openconfig-system:enable-ntp-auth\": true}" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"authentication": "enabled", "admin_state": "disabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/ntp/config/enable-ntp-auth node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/ntp/config/enable-ntp-auth node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/ntp/config/enable-ntp-auth node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/ntp/config/enable-ntp-auth node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"authentication": "disabled"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:enable-ntp-auth\":false}" + url = "/openconfig-system:system/ntp/config/enable-ntp-auth" + t.Run("Test get on system/ntp/config/enable-ntp-auth node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp/config/enable-ntp-auth node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/ntp/config/enable-ntp-auth node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"authentication": "disabled"}}} + url = "/openconfig-system:system/ntp/config/enable-ntp-auth" + url_body_json = "{ \"openconfig-system:enable-ntp-auth\": true}" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"authentication": "enabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/ntp/config/enable-ntp-auth node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/ntp/config/enable-ntp-auth node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/ntp/config/enable-ntp-auth node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/ntp/config/enable-ntp-auth node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"authentication": "enabled"}}} + url = "/openconfig-system:system/ntp/config/enable-ntp-auth" + url_body_json = "{ \"openconfig-system:enable-ntp-auth\": false}" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"authentication": "disabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/ntp/config/enable-ntp-auth node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/ntp/config/enable-ntp-auth node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/ntp/config/enable-ntp-auth node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing delete on system/ntp/config/enable-ntp-auth node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"authentication": "enabled"}}} + url = "/openconfig-system:system/ntp/config/enable-ntp-auth" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"authentication": "disabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test delete on system/ntp/config/enable-ntp-auth node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on system/ntp/config/enable-ntp-auth node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing delete on system/ntp/config/enable-ntp-auth node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/ntp/config node ++++++++++++") + url = "/openconfig-system:system/ntp/config" + url_body_json = "{ \"openconfig-system:enabled\": true, \"openconfig-system:enable-ntp-auth\": false}" + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "authentication": "disabled"}}} + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/ntp/config node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/ntp/config node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/ntp/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/ntp/config node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "disabled", "authentication": "enabled"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:config\":{\"enabled\":false, \"enable-ntp-auth\":true}}" + url = "/openconfig-system:system/ntp/config" + t.Run("Test get on system/ntp/config node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing unit tests on system/ntp/config container nodes ++++++++++++") + + /* ntp/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/ntp/state node ++++++++++++") + url = "/openconfig-system:system/ntp/state" + t.Run("Test get on system/ntp/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp/state node ++++++++++++") + + /* ntp-keys/ntp-key */ + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/ntp/ntp-keys/ntp-key node ++++++++++++") + url = "/openconfig-system:system/ntp/ntp-keys" + url_body_json = "{\"openconfig-system:ntp-key\": [{\"key-id\": 100, \"config\": { \"key-id\": 100, \"key-type\": \"NTP_AUTH_MD5\", \"key-value\": \"key-value-1\"} } ]}" + expected_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": map[string]interface{}{"type": "md5", "value": "key-value-1"}}} + cleanuptbl = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": ""}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test POST(Create) on system/ntp/ntp-keys/ntp-key node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST(Create) on system/ntp/ntp-keys/ntp-key node", verifyDbResult(rclient, "NTP_KEY|100", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/ntp/ntp-keys/ntp-key node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/ntp/ntp-keys/ntp-key node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{"200": map[string]interface{}{"type": "md5", "value": "key-value-2"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:config\": { \"key-id\": 200, \"key-type\": \"openconfig-system:NTP_AUTH_MD5\", \"key-value\": \"key-value-2\"} }" + url = "/openconfig-system:system/ntp/ntp-keys/ntp-key[key-id=200]/config" + t.Run("Test get on system/ntp/ntp-keys/ntp-key node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp/ntp-keys/ntp-key node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PUT(Replace) on system/ntp/ntp-keys/ntp-key node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": map[string]interface{}{"type": "md5", "value": "key-value-2"}}} + url = "/openconfig-system:system/ntp/ntp-keys/ntp-key[key-id=100]" + url_body_json = "{\"openconfig-system:ntp-key\": [{\"key-id\": 100, \"config\": { \"key-id\": 100, \"key-type\": \"NTP_AUTH_MD5\", \"key-value\": \"key-value-3\"} } ]}" + expected_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": map[string]interface{}{"type": "md5", "value": "key-value-3"}}} + cleanuptbl = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test PUT(Replace) on system/ntp/ntp-keys/ntp-key node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT(Replace) on system/ntp/ntp-keys/ntp-key node", verifyDbResult(rclient, "NTP_KEY|100", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PUT(Replace) on system/ntp/ntp-keys/ntp-key node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing PATCH(Update) on system/ntp/ntp-keys/ntp-key node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": map[string]interface{}{"type": "md5", "value": "key-value-1"}}} + url = "/openconfig-system:system/ntp/ntp-keys/ntp-key[key-id=100]" + url_body_json = "{\"openconfig-system:ntp-key\": [{\"key-id\": 100, \"config\": { \"key-id\": 100, \"key-type\": \"NTP_AUTH_MD5\", \"key-value\": \"key-value-2\"} } ]}" + expected_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": map[string]interface{}{"type": "md5", "value": "key-value-2"}}} + cleanuptbl = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test PATCH(Update) on system/ntp/ntp-keys/ntp-key node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH(Update) on system/ntp/ntp-keys/ntp-key node", verifyDbResult(rclient, "NTP_KEY|100", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing PATCH(Update) on system/ntp/ntp-keys/ntp-key node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DEL(Delete) on system/ntp/ntp-keys/ntp-key node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": map[string]interface{}{"type": "md5", "value": "key-value-1"}}} + url = "/openconfig-system:system/ntp/ntp-keys/ntp-key[key-id=100]" + expected_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{}} + cleanuptbl = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Run("Test DELETE on system/ntp/ntp-keys/ntp-key node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify DELETE on system/ntp/ntp-keys/ntp-key node", verifyDbResult(rclient, "NTP_KEY|100", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing DELETE on system/ntp/ntp-keys/ntp-key node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/ntp node ++++++++++++") + expected_get_json = "{\"openconfig-system:ntp\": {\"ntp-keys\": { \"ntp-key\": [{\"key-id\": 200, \"config\": { \"key-id\": 200, \"key-type\": \"openconfig-system:NTP_AUTH_MD5\", \"key-value\": \"key-value-2\"} } ]}}}" + url = "/openconfig-system:system/ntp" + t.Run("Test get on system/ntp node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + cleanuptbl = map[string]interface{}{"NTP_KEY": map[string]interface{}{"200": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp node ++++++++++++") + + /* ntp/ntp-keys/ntp-key/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/ntp/ntp-keys/ntp-key/state node ++++++++++++") + url = "/openconfig-system:system/ntp/ntp-keys/ntp-key/state" + t.Run("Test get on system/ntp/ntp-keys/ntp-key/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp/ntp-keys/ntp-key/state node ++++++++++++") + + /* servers/server */ + // Pre required configs + // Load mgmt vrf config + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load mgmt port + pre_req_map = map[string]interface{}{"MGMT_PORT": map[string]interface{}{"eth0": map[string]interface{}{"NULL": "NULL"}, "eth1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load mgmt interface prefix + pre_req_map = map[string]interface{}{"MGMT_INTERFACE": map[string]interface{}{"eth0|11.11.11.11/24": map[string]interface{}{"gwaddr": "11.11.11.1"}, "eth1|22.22.22.22/32": map[string]interface{}{"gwaddr": "22.22.22.1"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load VRF + pre_req_map = map[string]interface{}{"VRF": map[string]interface{}{"Vrf1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load Port + pre_req_map = map[string]interface{}{"PORT": map[string]interface{}{"Ethernet4": map[string]interface{}{"NULL": "NULL"}, "Ethernet8": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load Interface prefix + pre_req_map = map[string]interface{}{"INTERFACE": map[string]interface{}{"Ethernet4": map[string]interface{}{"vrf_name": "Vrf1"}, "Ethernet4|33.33.33.33": map[string]interface{}{"NULL": "NULL"}, "Ethernet8|33.33.33.33": map[string]interface{}{"NULL": "NULL"}, "Ethernet8|44.44.44.44/24": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load NTP Global + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load NTP Key + pre_req_map = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": map[string]interface{}{"type": "md5", "value": "key-value"}}} + loadDB(db.ConfigDB, pre_req_map) + + t.Log("\n\n+++++++++++++ Performing POST(Create) on system/ntp/servers/server node ++++++++++++") + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"default\", \"source-address\": \"44.44.44.44\", \"key-id\": 100}}]}" + t.Run("Test POST(Create) on system/ntp/servers/server node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"association_type": "server", "version": "4", "iburst": "on", "key": "100"}}} + t.Run("Verify POST(Create) on system/ntp/servers/server node", verifyDbResult(rclient, "NTP_SERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "vrf": "default", "src_intf": "Ethernet8"}}} + t.Run("Verify POST(Create) on system/ntp/server vrf-src_intf node", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"1.1.1.1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing POST(Create) on system/ntp/servers/server node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/ntp/servers/server node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"association_type": "pool", "version": "3", "iburst": "on", "key": "100"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"src_intf": "eth1", "vrf": "mgmt"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:config\": { \"address\": \"2.2.2.2\", \"association-type\": \"POOL\", \"version\": 3, \"iburst\": true, \"network-instance\": \"mgmt\", \"source-address\": \"22.22.22.22\", \"key-id\": 100}}" + url = "/openconfig-system:system/ntp/servers/server[address=2.2.2.2]/config" + t.Run("Test get on system/ntp/servers/server node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + cleanuptbl = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"2.2.2.2": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"association_type": "pool", "version": "3", "iburst": "on", "key": "100"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"src_intf": "eth0", "vrf": ""}}} + loadDB(db.ConfigDB, pre_req_map) + cleanuptbl = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + expected_get_json = "{\"openconfig-system:config\": { \"address\": \"2.2.2.2\", \"association-type\": \"POOL\", \"version\": 3, \"iburst\": true, \"source-address\": \"11.11.11.11\", \"key-id\": 100}}" + url = "/openconfig-system:system/ntp/servers/server[address=2.2.2.2]/config" + t.Run("Test get on system/ntp/servers/server default vrf node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp/servers/server node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/ntp node ++++++++++++") + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"src_intf": "eth0", "vrf": "mgmt"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:ntp\": {\"servers\": { \"server\": [{\"address\": \"2.2.2.2\", \"config\": { \"address\": \"2.2.2.2\", \"association-type\": \"POOL\", \"version\": 3, \"iburst\": true, \"network-instance\": \"mgmt\", \"source-address\": \"11.11.11.11\", \"key-id\": 100} } ]}, \"ntp-keys\": { \"ntp-key\": [{\"key-id\": 100, \"config\": { \"key-id\": 100, \"key-type\": \"openconfig-system:NTP_AUTH_MD5\", \"key-value\": \"key-value\"} } ]}, \"config\": { \"enabled\": true}}}" + url = "/openconfig-system:system/ntp" + t.Run("Test get on system/ntp node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp node ++++++++++++") + + /* + t.Log("\n\n+++++++++++++ Test mgmt vrf when mgmt_vrf_config not enabled ++++++++++++") + cleanuptbl = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"key-id\": 100}}]}" + mgmt_vrf_err := errors.New("Must condition not satisfied. Try enable Management VRF.") + t.Run("Test ntp/servers/server mgmt vrf when mgmt_vrf_config not enabled set", processSetRequest(url, url_body_json, "POST", true, mgmt_vrf_err)) + time.Sleep(1 * time.Second) + */ + + t.Log("\n\n+++++++++++++ Test multiple vrf case ++++++++++++") + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "vrf": "default", "src_intf": "eth1"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"key-id\": 100}}]}" + vrf_err := errors.New("Given network-instance name is different from already configured one for this/any other server") + t.Run("Test ntp/servers/server multiple vrf case", processSetRequest(url, url_body_json, "POST", true, vrf_err)) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Test multiple interface case ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "vrf": "mgmt", "src_intf": "eth0"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"source-address\": \"22.22.22.22\", \"key-id\": 100}}]}" + intf_err := errors.New("Given source address's port doesn't match with already configured src_intf") + t.Run("Test ntp/servers/server multiple src_intf case", processSetRequest(url, url_body_json, "POST", true, intf_err)) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Test NTP global table cleanup on last server deletion ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"source-address\": \"22.22.22.22\", \"key-id\": 100}}]}" + t.Run("Test ntp/servers/server vrf_intf_cleanup server-1 case", processSetRequest(url, url_body_json, "POST", false, nil)) + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"2.2.2.2\", \"config\": { \"address\": \"2.2.2.2\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"source-address\": \"22.22.22.22\", \"key-id\": 100}}]}" + t.Run("Test ntp/servers/server vrf_intf_cleanup server-2 case", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/ntp/servers/server[address=1.1.1.1]" + t.Run("Test delete ntp/servers/server vrf_intf_cleanup server-1 case", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup server-1 case", verifyDbResult(rclient, "NTP_SERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "src_intf": "eth1", "vrf": "mgmt"}}} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup server-1 global case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/ntp/servers/server[address=2.2.2.2]" + t.Run("Test delete ntp/servers/server vrf_intf_cleanup server-2 case", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup server-2 case", verifyDbResult(rclient, "NTP_SERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup server-2 global case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Test NTP global table cleanup on last server deletion - when only vrf is configured ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"key-id\": 100}}]}" + t.Run("Test ntp/servers/server vrf_intf_cleanup no-intf case", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "vrf": "mgmt"}}} + t.Run("Verify create on ntp/servers/server vrf_intf_cleanup no-intf global case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/ntp/servers/server[address=1.1.1.1]" + t.Run("Test delete ntp/servers/server vrf_intf_cleanup no-intf case", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup no-intf case", verifyDbResult(rclient, "NTP_SERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup no-intf global case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Test NTP global table cleanup on last server deletion - when vrf & src_intf not configured ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"key-id\": 100}}]}" + t.Run("Test ntp/servers/server vrf_intf_cleanup no-vrf-no-intf case", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + t.Run("Verify create on ntp/servers/server vrf_intf_cleanup no-vrf-no-intf global case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/ntp/servers/server[address=1.1.1.1]" + t.Run("Test delete ntp/servers/server vrf_intf_cleanup no-vrf-no-intf case", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup no-vrf-no-intf case", verifyDbResult(rclient, "NTP_SERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup no-vrf-no-intf global case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Test NTP global table cleanup on last server deletion - when NTP|global table is empty ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"key-id\": 100}}]}" + t.Run("Test ntp/servers/server vrf_intf_cleanup no-ntp-global case", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{}}} + t.Run("Verify create on ntp/servers/server vrf_intf_cleanup no-ntp-global global case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/ntp/servers/server[address=1.1.1.1]" + t.Run("Test delete ntp/servers/server vrf_intf_cleanup no-ntp-global case", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup no-ntp-global case", verifyDbResult(rclient, "NTP_SERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{}}} + t.Run("Verify delete on ntp/servers/server vrf_intf_cleanup no-ntp-global global case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + + /* + t.Log("\n\n+++++++++++++ Test NTP invalid source address - wrong syntax ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"source-address\": \"22.22.2.a\", \"key-id\": 100}}]}" + wrong_ip_err := errors.New("Invalid input") + t.Run("Test ntp/servers/server src_addr wrong syntax case", processSetRequest(url, url_body_json, "POST", true, wrong_ip_err)) + */ + + t.Log("\n\n+++++++++++++ Test NTP invalid source address - not configured on any port ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"source-address\": \"192.1.2.3\", \"key-id\": 100}}]}" + not_conf_ip_err := errors.New("Failed to get source interface for given source address") + t.Run("Test ntp/servers/server src_addr not configured on vrf any case", processSetRequest(url, url_body_json, "POST", true, not_conf_ip_err)) + + t.Log("\n\n+++++++++++++ Test NTP invalid source address - not configured on vrf port ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"network-instance\": \"mgmt\", \"source-address\": \"33.33.33.33\", \"key-id\": 100}}]}" + not_conf_vrf_ip_err := errors.New("Failed to get source interface for given source address") + t.Run("Test ntp/servers/server src_addr not configured on vrf port case", processSetRequest(url, url_body_json, "POST", true, not_conf_vrf_ip_err)) + + t.Log("\n\n+++++++++++++ Test NTP server src_intf is fetched correctly based on vrf already configured ++++++++++++") + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + pre_req_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "vrf": "default"}}} + loadDB(db.ConfigDB, pre_req_map) + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + cleanuptbl = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"1.1.1.1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + url = "/openconfig-system:system/ntp/servers" + url_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.1.1.1\", \"config\": { \"address\": \"1.1.1.1\", \"association-type\": \"SERVER\", \"version\": 4, \"iburst\": true, \"source-address\": \"44.44.44.44\", \"key-id\": 100}}]}" + t.Run("Test ntp/servers/server src_intf fetch case", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"NTP": map[string]interface{}{"global": map[string]interface{}{"admin_state": "enabled", "vrf": "default", "src_intf": "Ethernet8"}}} + t.Run("Verify create on ntp/servers/server vrf_intf_cleanup src_intf fetch case", verifyDbResult(rclient, "NTP|global", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean interface prefix + cleanuptbl = map[string]interface{}{"INTERFACE": map[string]interface{}{"Ethernet4": "", "Ethernet4|33.33.33.33": "", "Ethernet8|33.33.33.33": "", "Ethernet8|44.44.44.44/24": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean mgmt interface prefix + cleanuptbl = map[string]interface{}{"MGMT_INTERFACE": map[string]interface{}{"eth0|11.11.11.11/24": "", "eth1|22.22.22.22/32": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean Port + cleanuptbl = map[string]interface{}{"PORT": map[string]interface{}{"Ethernet4": "", "Ethernet8": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean mgmt port + cleanuptbl = map[string]interface{}{"MGMT_PORT": map[string]interface{}{"eth0": "", "eth1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean VRF + cleanuptbl = map[string]interface{}{"VRF": map[string]interface{}{"Vrf1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean mgmt vrf config + cleanuptbl = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean NTP Keys + cleanuptbl = map[string]interface{}{"NTP_KEY": map[string]interface{}{"100": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean NTP global + cleanuptbl = map[string]interface{}{"NTP": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Test delete iburst + t.Log("\n\n+++++++++++++ Performing delete on system/ntp/servers/server/config/iburst node ++++++++++++") + pre_req_map = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"association_type": "pool", "version": "3", "iburst": "on"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/ntp/servers/server[address=2.2.2.2]/config/iburst" + t.Run("Test delete on system/ntp/servers/server/config/iburst node", processDeleteRequest(url, false)) + expected_map = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"association_type": "pool", "version": "3", "iburst": "off"}}} + t.Run("Verify delete on system/ntp/servers/server/config/iburst node", verifyDbResult(rclient, "NTP_SERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"NTP_SERVER": map[string]interface{}{"2.2.2.2": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing delete on system/ntp/servers/server/config/iburst node ++++++++++++") + + /* ntp/servers/server/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/ntp/servers/server/state node ++++++++++++") + url = "/openconfig-system:system/ntp/servers/server/state" + t.Run("Test get on system/ntp/servers/server/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/ntp/servers/server/state node ++++++++++++") +} + +func Test_oc_system_dns(t *testing.T) { + var url, expected_get_json, url_body_json string + var pre_req_map, pre_req_map_empty, cleanuptbl, expected_map map[string]interface{} + + t.Log("\n\n+++++++++++++ Performing unit tests on system/dns container nodes ++++++++++++") + + /* dns/config/search */ + + t.Log("\n\n+++++++++++++ Performing create on system/dns/config/search node ++++++++++++") + url = "/openconfig-system:system/dns/config" + url_body_json = "{ \"openconfig-system:search\": [\"1.1.1.1\"]}" + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test create on system/dns/config/search node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify create on system/dns/config/search node", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing create on system/dns/config/search node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing create multiple nodes on system/dns/config/search node ++++++++++++") + url = "/openconfig-system:system/dns/config" + url_body_json = "{ \"openconfig-system:search\": [\"1.1.1.1\", \"2.2.2.2\"]}" + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + t.Run("Test create multiple nodes on system/dns/config/search node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify create multiple nodes on system/dns/config/search node 1", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify create multiple nodes on system/dns/config/search node 2", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": "", "2.2.2.2": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing create multiple nodes on system/dns/config/search node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing update on system/dns/config/search node ++++++++++++") + pre_req_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/dns/config/search" + url_body_json = "{ \"openconfig-system:search\": [\"2.2.2.2\"]}" + time.Sleep(1 * time.Second) + t.Run("Test update on system/dns/config/search node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify update on system/dns/config/search node old", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify update on system/dns/config/search node new", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": "", "2.2.2.2": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing update on system/dns/config/search node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/dns/config/search node ++++++++++++") + pre_req_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/dns/config/search" + t.Run("Test delete on system/dns/config/search node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify delete on system/dns/config/search node", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing delete on system/dns/config/search node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/dns/config/search node 3 entries ++++++++++++") + pre_req_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}, "2.2.2.2": map[string]interface{}{"NULL": "NULL"}, "3.3.3.3": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/dns/config/search" + t.Run("Test delete on system/dns/config/search node 3 entries", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify delete on system/dns/config/search node 3 entries", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + t.Run("Verify delete on system/dns/config/search node 3 entries", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + t.Run("Verify delete on system/dns/config/search node 3 entries", verifyDbResult(rclient, "DNS_NAMESERVER|3.3.3.3", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": "", "2.2.2.2": "", "3.3.3.3": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing delete on system/dns/config/search node 3 entries ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/dns/config node ++++++++++++") + pre_req_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/dns/config" + t.Run("Test delete on system/dns/config node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify delete on system/dns/config node", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing delete on system/dns/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/dns node ++++++++++++") + pre_req_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/dns" + t.Run("Test delete on system/dns node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify delete on system/dns node", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing delete on system/dns node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on dns - system node ++++++++++++") + pre_req_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system" + t.Run("Test delete on system node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify delete on system node", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("\n\n+++++++++++++ Done Performing delete on system node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing DELETE on system/dns/config/search no DB entry case ++++++++++++") + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/dns/config/search" + t.Run("Test delete on system/dns/config/search no db entry case", processDeleteRequest(url, false)) + t.Log("\n\n+++++++++++++ Done Performing delete on system/dns/config/search no DB entry case ++++++++++++") + + // Replace operation + t.Log("\n\n+++++++++++++ Performing Replace on system/dns/config/search node 0to1 ++++++++++++") + loadDB(db.ConfigDB, pre_req_map_empty) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/dns/config/search" + url_body_json = "{\"openconfig-system:search\": [\"1.1.1.1\"]}" + t.Run("Test Replace on system/dns/config/search node 0to1 ", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 0to1 ", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Replace on system/dns/config/search node 0to1 ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Replace on system/dns/config/search node 1to2 ++++++++++++") + url_body_json = "{\"openconfig-system:search\": [\"2.2.2.2\"]}" + t.Run("Test Replace on system/dns/config/search node 1to2 ", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify replace on system/dns/config/search node 1to2 del ", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 1to2 new ", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Replace on system/dns/config/search node 1to2 ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Replace on system/dns/config/search node 2to1-2 ++++++++++++") + url_body_json = "{\"openconfig-system:search\": [\"1.1.1.1\", \"2.2.2.2\"]}" + t.Run("Test Replace on system/dns/config/search node 2to1-2 ", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 2to1-2 new ", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 2to1-2 unchanged ", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Replace on system/dns/config/search node 2to1-2 ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Replace on system/dns/config/search node 1-2to3-4 ++++++++++++") + url_body_json = "{\"openconfig-system:search\": [\"3.3.3.3\", \"4.4.4.4\"]}" + t.Run("Test Replace on system/dns/config/search node 1-2to3-4 ", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify replace on system/dns/config/search node 1-2to3-4 old-1 ", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify replace on system/dns/config/search node 1-2to3-4 old-2 ", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 1-2to3-4 new-1 ", verifyDbResult(rclient, "DNS_NAMESERVER|3.3.3.3", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"4.4.4.4": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 1-2to3-4 new-2 ", verifyDbResult(rclient, "DNS_NAMESERVER|4.4.4.4", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Replace on system/dns/config/search node 1-2to3-4 ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Replace on system/dns/config/search node 3-4to4 ++++++++++++") + url_body_json = "{\"openconfig-system:search\": [\"4.4.4.4\"]}" + t.Run("Test Replace on system/dns/config/search node 3-4to4 ", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify replace on system/dns/config/search node 3-4to4 del ", verifyDbResult(rclient, "DNS_NAMESERVER|3.3.3.3", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"4.4.4.4": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 3-4to4 unchanged ", verifyDbResult(rclient, "DNS_NAMESERVER|4.4.4.4", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Replace on system/dns/config/search node 3-4to4 ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Replace on system/dns/config/search node 4to1-2-4 ++++++++++++") + url_body_json = "{\"openconfig-system:search\": [\"1.1.1.1\", \"2.2.2.2\", \"4.4.4.4\"]}" + t.Run("Test Replace on system/dns/config/search node 4to1-2-4 ", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 4to1-2-4 new ", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 4to1-2-4 new ", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"4.4.4.4": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 4to1-2-4 unchanged ", verifyDbResult(rclient, "DNS_NAMESERVER|4.4.4.4", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Replace on system/dns/config/search node 4to1-2-4 ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Replace on system/dns/config/search node 1-2-4to3-2 ++++++++++++") + url_body_json = "{\"openconfig-system:search\": [\"3.3.3.3\", \"2.2.2.2\"]}" + t.Run("Test Replace on system/dns/config/search node 1-2-4to3-2 ", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify replace on system/dns/config/search node 1-2-4to3-2 del-1 ", verifyDbResult(rclient, "DNS_NAMESERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 1-2-4to3-2 unchanged ", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node 1-2-4to3-2 new ", verifyDbResult(rclient, "DNS_NAMESERVER|3.3.3.3", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{}} + t.Run("Verify replace on system/dns/config/search node 1-2-4to3-2 del-2 ", verifyDbResult(rclient, "DNS_NAMESERVER|4.4.4.4", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Replace on system/dns/config/search node 1-2-4to3-2 ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Replace on system/dns/config/search node unchanged-2 ++++++++++++") + url_body_json = "{\"openconfig-system:search\": [\"3.3.3.3\", \"2.2.2.2\"]}" + t.Run("Test Replace on system/dns/config/search node unchanged-2 ", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node unchanged-2 unchanged ", verifyDbResult(rclient, "DNS_NAMESERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify replace on system/dns/config/search node unchanged-2 unchanged-2 ", verifyDbResult(rclient, "DNS_NAMESERVER|3.3.3.3", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Replace on system/dns/config/search node unchanged-2 ++++++++++++") + + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": "", "2.2.2.2": "", "3.3.3.3": "", "4.4.4.4": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + // Get + t.Log("\n\n+++++++++++++ Performing Get on system/dns/config/search node ++++++++++++") + pre_req_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:search\":[\"1.1.1.1\"]}" + url = "/openconfig-system:system/dns/config/search" + t.Run("Test get on system/dns/config/search node", processGetRequest(url, nil, expected_get_json, false, nil)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/dns/config/search node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/dns/config node ++++++++++++") + expected_get_json = "{\"openconfig-system:config\": {\"search\":[\"1.1.1.1\"]}}" + url = "/openconfig-system:system/dns/config" + t.Run("Test get on system/dns/config node", processGetRequest(url, nil, expected_get_json, false, nil)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/dns/config node ++++++++++++") + + t.Log("\n\n+++++++++++++ Performing Get on system/dns node ++++++++++++") + expected_get_json = "{\"openconfig-system:dns\": {\"config\": {\"search\":[\"1.1.1.1\"]}}}" + url = "/openconfig-system:system/dns" + t.Run("Test get on system/dns node", processGetRequest(url, nil, expected_get_json, false, nil)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/dns node ++++++++++++") + + /* + // boot-time & current-datetime also recvd + t.Log("\n\n+++++++++++++ Performing Get on system node ++++++++++++") + expected_get_json = "{\"openconfig-system:system\": {\"dns\": {\"config\": {\"search\":[\"1.1.1.1\"]}}}}" + url = "/openconfig-system:system" + t.Run("Test get on system node", processGetRequest(url, nil, expected_get_json, false, nil)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system node ++++++++++++") + + // Order is changing everytime + t.Log("\n\n+++++++++++++ Performing Get on system/dns/config/search multiple entries ++++++++++++") + pre_req_map = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"NULL": "NULL"}, "3.3.3.3": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + expected_get_json = "{\"openconfig-system:search\":[\"1.1.1.1\", \"3.3.3.3\", \"2.2.2.2\"]}" + url = "/openconfig-system:system/dns/config/search" + t.Run("Test get on system/dns/config/search multiple entries", processGetRequest(url, nil, expected_get_json, false, nil)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/dns/config/search multiple entries ++++++++++++") + */ + + cleanuptbl = map[string]interface{}{"DNS_NAMESERVER": map[string]interface{}{"1.1.1.1": "", "2.2.2.2": "", "3.3.3.3": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + /* dns/state */ + t.Log("\n\n+++++++++++++ Performing Get on system/dns/state node ++++++++++++") + url = "/openconfig-system:system/dns/state" + t.Run("Test get on system/dns/state node", processGetRequest(url, nil, "", true, not_implemented_err)) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Done Performing Get on system/dns/state node ++++++++++++") + + t.Log("\n\n+++++++++++++ Done Performing unit tests on system/dns container nodes ++++++++++++") +} + +func Test_openconfig_system_aaa_authentication(t *testing.T) { + var url string + var url_body_json string + var cleanuptbl map[string]interface{} + var expected_map map[string]interface{} + var pre_req_map map[string]interface{} + + t.Log("++++++++++++++ Starting Test: Authentication Method SET Transformations ++++++++++++++") + t.Log("\n\n+++++++++++++ Performing CREATE on authentication-method node ++++++++++++") + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/authentication/config" + url_body_json = "{\"openconfig-system:authentication-method\": [\"ldap\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "ldap"}}} + t.Run("Test create on authentication-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify create on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE Authentication Method Transformations ++++++++++++++") + + t.Log("++++++++++++++ Start Get Authentication Method Transformations ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "tacacs+"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + expected_get_json := "{\"openconfig-system:authentication-method\":[\"openconfig-aaa-types:TACACS_ALL\"]}" + + t.Log("++++++++++++++ Starting Test: Authentication performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on authentication-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authentication-method node ++++++++++++++") + + t.Log("++++++++++++++ Start Get Authentication Method Transformations ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + expected_get_json = "{\"openconfig-system:authentication-method\":[\"openconfig-aaa-types:TACACS_ALL\",\"openconfig-aaa-types:RADIUS_ALL\"]}" + + t.Log("++++++++++++++ Starting Test: Authentication performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on authentication-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authentication-method node ++++++++++++++") + + t.Log("++++++++++++++ Start Get Authentication Method Transformations ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "tacacs+,radius,local,default,ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + expected_get_json = "{\"openconfig-system:authentication-method\":[\"openconfig-aaa-types:TACACS_ALL\",\"openconfig-aaa-types:RADIUS_ALL\",\"openconfig-aaa-types:LOCAL\",\"default\",\"ldap\"]}" + + t.Log("++++++++++++++ Starting Test: Authentication performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on authentication-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authentication-method node ++++++++++++++") + + t.Log("++++++++++++++ Start Get Authentication Method Transformations ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "tacacs+,radius,local,invalid"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + t.Log("++++++++++++++ Starting Test: Authentication performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + t.Run("Test get on authentication-method node", func(t *testing.T) { + // Instead of expecting a valid response, we expect an error + err := processGetRequest(url, nil, "", false) // Assuming that an error is returned when invalid + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authentication-method node ++++++++++++++") + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "invalid"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + + t.Log("++++++++++++++ Starting Test: Authentication performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + t.Run("Test get on authentication-method node", func(t *testing.T) { + // Instead of expecting a valid response, we expect an error + err := processGetRequest(url, nil, "", false) // Assuming that an error is returned when invalid + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authentication-method node ++++++++++++++") + + t.Log("++++++++++++++ Start Get Authentication Method Transformations ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "invalid,tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + t.Log("++++++++++++++ Starting Test: Authentication performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + t.Run("Test get on authentication-method node", func(t *testing.T) { + // Instead of expecting a valid response, we expect an error + err := processGetRequest(url, nil, "", false) // Assuming that an error is returned when invalid + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authentication-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authentication Method for REPLACE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "ldap,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"LOCAL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "local"}}} + t.Run("Test replace on authentication-method node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify replace on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "ldap,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method node with one same node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"TACACS_ALL\", \"LOCAL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "tacacs+,local"}}} + t.Run("Test replace on authentication-method node with one same node", func(t *testing.T) { + processSetRequest(url, url_body_json, "PUT", false, nil) + time.Sleep(1 * time.Second) + verifyDbResult(rclient, "AAA|authentication", expected_map, false) + }) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "ldap,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method node with multiple values ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"LOCAL\", \"default\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "local,default"}}} + t.Run("Test replace on authentication-method node with multiple values", func(t *testing.T) { + processSetRequest(url, url_body_json, "PUT", false, nil) + time.Sleep(1 * time.Second) + verifyDbResult(rclient, "AAA|authentication", expected_map, false) + }) + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method node with empty db ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"LOCAL\", \"default\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "local,default"}}} + t.Run("Test replace on authentication-method node with multiple values", func(t *testing.T) { + processSetRequest(url, url_body_json, "PUT", false, nil) + time.Sleep(1 * time.Second) + verifyDbResult(rclient, "AAA|authentication", expected_map, false) + }) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method method type to db testt ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"LOCAL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "local"}}} + t.Run("Test replace on authentication-method node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify replace on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method default string and invalid payload ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method node with default string and invalid payload ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"invalid\"]}" + t.Run("Test replace on authentication-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PUT", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method default string and invalid and valid payload ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authentication-method node with multiple values ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"default\",\"invalid\"]}" + t.Run("Test replace on authentication-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PUT", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for REPLACE++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authentication Method for MULTI CREATE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 1 . Performing MULTI CREATE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config" + url_body_json = "{\"openconfig-system:authentication-method\": [\"ldap\", \"RADIUS_ALL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "local,ldap,radius"}}} + t.Run("Test MULTI CREATE on authentication-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify MULTI CREATE on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "default,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 2. Performing MULTI CREATE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config" + url_body_json = "{\"openconfig-system:authentication-method\": [\"LOCAL\", \"ldap\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "default,radius,local,ldap"}}} + t.Run("Test MULTI CREATE on authentication-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify MULTI CREATE on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "radius,local,ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 3 .Performing MULTI CREATE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config" + url_body_json = "{\"openconfig-system:authentication-method\": [\"LOCAL\",\"RADIUS_ALL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "radius,local,ldap"}}} + t.Run("Test MULTI CREATE on authentication-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify MULTI CREATE on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "radius,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ 4. Performing MULTI CREATE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config" + url_body_json = "{\"openconfig-system:authentication-method\": [\"default\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "radius,local,default"}}} + t.Run("Test MULTI CREATE on authentication-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify MULTI CREATE on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 5 .Performing MULTI CREATE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config" + url_body_json = "{\"openconfig-system:authentication-method\": [\"invalid\"]}" + t.Run("Test MULTI CREATE on authentication-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 6. Performing MULTI CREATE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config" + url_body_json = "{\"openconfig-system:authentication-method\": [\"default\",\"invalid\"]}" + t.Run("Test MULTI CREATE on authentication-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "radius,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 7. Performing MULTI CREATE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config" + url_body_json = "{\"openconfig-system:authentication-method\": [\"RADIUS_ALL\",\"LOCAL\",\"invalid\",\"ldap\"]}" + t.Run("Test MULTI CREATE on authentication-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for MULTI CREATE++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authentication Method for UPDATE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing UPDATE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"LOCAL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "ldap,local"}}} + t.Run("Test update on authentication-method node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + + // Test Case 2: UPDATE with multiple values when no initial values are present + t.Log("\n\n+++++++++++++ Performing UPDATE on authentication-method node with no initial values ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"LOCAL\", \"default\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "local,default"}}} + t.Run("Test update on authentication-method node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify update on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for UPDATE ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing UPDATE on authentication-method node with default string ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"invalid\"]}" + t.Run("Test replace on authentication-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PATCH", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for UPDATE ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing UPDATE on authentication-method node with default string ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"default\",\"invalid\"]}" + t.Run("Test replace on authentication-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PATCH", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for UPDATE ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing UPDATE on authentication-method node with default string ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + url_body_json = "{\"openconfig-system:authentication-method\": [\"TACACS_ALL\",\"RADIUS_ALL\",\"invalid\",\"local\"]}" + t.Run("Test replace on authentication-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PATCH", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for UPDATE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authentication Method for DELETE oper with tacacs+++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "tacacs+"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on authentication-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authentication Method for DELETE oper ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "tacacs+,radius,default,ldap,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on authentication-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authentication Method for DELETE oper ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": "ldap,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on authentication-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authentication Method for DELETE oper with empty db ++++++++++++++") + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on authentication-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on authentication-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on authentication-method node", verifyDbResult(rclient, "AAA|authentication", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authentication Method Transformations for DELETE ++++++++++++++") + + t.Log("\n\n+++++++++++++Testing invalid string on authentication-method node ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authentication": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/authentication/config/authentication-method" + exp_json := "{\"openconfig-system:authentication-method\": [\"invalidMethod\"]}" + + t.Run("Test invalid authentication-method node", func(t *testing.T) { + err := processSetRequest(url, exp_json, "PATCH", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Strings apart from local,radius,ldap,default and tacacs+ are not allowed: %v", err) + } + }) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing invalid accounting Method Transformations for UPDATE ++++++++++++++") + +} + +func Test_openconfig_system_aaa_authorization(t *testing.T) { + var url string + var url_body_json string + var cleanuptbl map[string]interface{} + var expected_map map[string]interface{} + var pre_req_map map[string]interface{} + + t.Log("++++++++++++++ Starting Test: authorization Method SET Transformations ++++++++++++++") + t.Log("\n\n+++++++++++++ Performing CREATE on authorization-method node ++++++++++++") + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/authorization/config" + url_body_json = "{\"openconfig-system:authorization-method\": [\"ldap\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "ldap"}}} + t.Run("Test create on authorization-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify create on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE authorization Method Transformations ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + expected_get_json := "{\"openconfig-system:authorization-method\":[\"openconfig-aaa-types:TACACS_ALL\"]}" + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on authorization-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authorization-method node ++++++++++++++") + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + expected_get_json = "{\"openconfig-system:authorization-method\":[\"openconfig-aaa-types:TACACS_ALL\",\"openconfig-aaa-types:RADIUS_ALL\"]}" + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on authorization-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authorization-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+,radius,local,default,ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + expected_get_json = "{\"openconfig-system:authorization-method\":[\"openconfig-aaa-types:TACACS_ALL\",\"openconfig-aaa-types:RADIUS_ALL\",\"openconfig-aaa-types:LOCAL\",\"default\",\"ldap\"]}" + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on authorization-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authorization-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "invalid"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + t.Run("Test get on authentication-method node", func(t *testing.T) { + // Instead of expecting a valid response, we expect an error + err := processGetRequest(url, nil, "", false) // Assuming that an error is returned when invalid + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authorization-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs,radius,invalid,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + t.Run("Test get on authentication-method node", func(t *testing.T) { + // Instead of expecting a valid response, we expect an error + err := processGetRequest(url, nil, "", false) // Assuming that an error is returned when invalid + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authorization-method node ++++++++++++++") + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "invalid,tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + + t.Log("++++++++++++++ Starting Test: authorization performing GET ++++++++++++++") + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + t.Run("Test get on authentication-method node", func(t *testing.T) { + // Instead of expecting a valid response, we expect an error + err := processGetRequest(url, nil, "", false) // Assuming that an error is returned when invalid + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on authorization-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: authorization Method for REPLACE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing REPLACE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"TACACS_ALL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+"}}} + t.Run("Test replace on authorization-method node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify replace on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authorization-method method type to db testt ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"LOCAL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "local"}}} + t.Run("Test replace on authorization-method node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify replace on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authorization-method default string and invalid payload ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authorization-method node with default string and invalid payload ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"invalid\"]}" + t.Run("Test replace on authorization-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PUT", false, nil) + if err == nil { + t.Error("Expected an error for invalid authorization method, but got none") + } else { + t.Logf("Correctly received error for invalid authorization method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authorization-method default string and invalid and valid payload ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing REPLACE on authorization-method node with multiple values ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"default\",\"invalid\"]}" + t.Run("Test replace on authorization-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PUT", false, nil) + if err == nil { + t.Error("Expected an error for invalid authorization method, but got none") + } else { + t.Logf("Correctly received error for invalid authorization method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Done Performing Authorization Method Transformations for REPLACE++++++++++++++") + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+,radius,local,ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 3 .Performing MULTI CREATE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config" + url_body_json = "{\"openconfig-system:authorization-method\": [\"LOCAL\",\"RADIUS_ALL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+,radius,local,ldap"}}} + t.Run("Test MULTI CREATE on authorization-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify MULTI CREATE on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "radius,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 4. Performing MULTI CREATE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config" + url_body_json = "{\"openconfig-system:authorization-method\": [\"default\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "radius,local,default"}}} + t.Run("Test MULTI CREATE on authorization-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify MULTI CREATE on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 5 .Performing MULTI CREATE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config" + url_body_json = "{\"openconfig-system:authorization-method\": [\"invalid\"]}" + t.Run("Test MULTI CREATE on authorization-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid authorization method, but got none") + } else { + t.Logf("Correctly received error for invalid authorization method: %v", err) + } + }) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 5 .Performing MULTI CREATE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config" + url_body_json = "{\"openconfig-system:authorization-method\": [\"default\",\"invalid\"]}" + t.Run("Test MULTI CREATE on authorization-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid authorization method, but got none") + } else { + t.Logf("Correctly received error for invalid authorization method: %v", err) + } + }) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ 5 .Performing MULTI CREATE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config" + url_body_json = "{\"openconfig-system:authorization-method\": [\"TACACS_ALL\",\"RADIUS_ALL\",\"default\",\"invalid\"]}" + t.Run("Test MULTI CREATE on authorization-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid authorization method, but got none") + } else { + t.Logf("Correctly received error for invalid authorization method: %v", err) + } + }) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Starting Test: Authorization Method for UPDATE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing UPDATE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"LOCAL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "ldap,local"}}} + t.Run("Test update on authorization-method node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + + t.Log("++++++++++++++ Performing Authorization Method for UPDATE oper with identityref ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing UPDATE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"RADIUS_ALL\",\"LOCAL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "radius,local"}}} + t.Run("Test update on authorization-method node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + + // Test Case 2: UPDATE with multiple values when no initial values are present + t.Log("\n\n+++++++++++++ Performing UPDATE on authorization-method node with no initial values ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"LOCAL\", \"default\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "local,default"}}} + t.Run("Test update on authorization-method node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify update on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Authorization Method Transformations for UPDATE ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing UPDATE on authorization-method node with default string ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"invalid\"]}" + t.Run("Test replace on authorization-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PATCH", false, nil) + if err == nil { + t.Error("Expected an error for invalid authorization method, but got none") + } else { + t.Logf("Correctly received error for invalid authorization method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing authorization Method Transformations for UPDATE ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing UPDATE on authorization-method node with default string ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + url_body_json = "{\"openconfig-system:authorization-method\": [\"default\",\"invalid\"]}" + t.Run("Test replace on authorization-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PATCH", false, nil) + if err == nil { + t.Error("Expected an error for invalid authorization method, but got none") + } else { + t.Logf("Correctly received error for invalid authorization method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing authorization Method Transformations for UPDATE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authorization Method for DELETE oper ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "ldap,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on authorization-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing authorization Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authorization Method for DELETE oper ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on authorization-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing authorization Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authorization Method for DELETE oper ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": "tacacs+,radius,ldap,local,default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on authorization-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing authorization Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Authorization Method for DELETE oper with empty db ++++++++++++++") + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on authorization-method node ++++++++++++") + url = "/openconfig-system:system/aaa/authorization/config/authorization-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"authorization": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on authorization-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on authorization-method node", verifyDbResult(rclient, "AAA|authorization", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing authorization Method Transformations for DELETE ++++++++++++++") +} + +func Test_openconfig_system_aaa_accounting(t *testing.T) { + var url string + var url_body_json string + var cleanuptbl map[string]interface{} + var expected_map map[string]interface{} + var pre_req_map map[string]interface{} + + t.Log("++++++++++++++ Starting Test: accounting Method SET Transformations ++++++++++++++") + t.Log("\n\n+++++++++++++ Performing CREATE on accounting-method node ++++++++++++") + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config" + url_body_json = "{\"openconfig-system:accounting-method\": [\"ldap\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "ldap"}}} + t.Run("Test create on accounting-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify create on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + + t.Log("\n\n+++++++++++++ Performing CREATE on accounting-method node ++++++++++++") + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config" + url_body_json = "{\"openconfig-system:accounting-method\": [\"TACACS_ALL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "ldap,tacacs+"}}} + t.Run("Test create on accounting-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify create on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE accounting Method Transformations ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing CREATE on accounting-method node ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config" + url_body_json = "{\"openconfig-system:accounting-method\": [\"TACACS_ALL\",\"RADIUS_ALL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius"}}} + t.Run("Test create on accounting-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify create on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE accounting Method Transformations ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing CREATE on accounting-method node ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config" + url_body_json = "{\"openconfig-system:accounting-method\": [\"LOCAL\",\"default\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius,local,default"}}} + t.Run("Test create on accounting-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify create on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE accounting Method Transformations ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing CREATE on accounting-method node ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "local,ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config" + url_body_json = "{\"openconfig-system:accounting-method\": [\"TACACS_ALL\",\"RADIUS_ALL\",\"LOCAL\",\"ldap\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "local,ldap,tacacs+,radius"}}} + t.Run("Test create on accounting-method node", processSetRequest(url, url_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify create on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE accounting Method Transformations ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing CREATE on accounting-method node ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config" + url_body_json = "{\"openconfig-system:accounting-method\": [\"invalid\"]}" + t.Run("Test MULTI CREATE on accounting-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE accounting Method Transformations ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing CREATE on accounting-method node ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config" + url_body_json = "{\"openconfig-system:accounting-method\": [\"invalid\"]}" + t.Run("Test MULTI CREATE on accounting-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid authentication method, but got none") + } else { + t.Logf("Correctly received error for invalid authentication method: %v", err) + } + }) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE accounting Method Transformations ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing CREATE on accounting-method node ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config" + url_body_json = "{\"openconfig-system:accounting-method\": [\"default\",\"invalid\"]}" + t.Run("Test MULTI CREATE on accounting-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "POST", false, nil) + if err == nil { + t.Error("Expected an error for invalid accounting method, but got none") + } else { + t.Logf("Correctly received error for invalid accounting method: %v", err) + } + }) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing CREATE accounting Method Transformations ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + expected_get_json := "{\"openconfig-system:accounting-method\":[\"openconfig-aaa-types:TACACS_ALL\"]}" + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on accounting-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on accounting-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + expected_get_json = "{\"openconfig-system:accounting-method\":[\"openconfig-aaa-types:TACACS_ALL\",\"openconfig-aaa-types:RADIUS_ALL\"]}" + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on accounting-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on accounting-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius,local,default,ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + expected_get_json = "{\"openconfig-system:accounting-method\":[\"openconfig-aaa-types:TACACS_ALL\",\"openconfig-aaa-types:RADIUS_ALL\",\"openconfig-aaa-types:LOCAL\",\"default\",\"ldap\"]}" + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + t.Logf("Performing GET request on URL: %s", url) + t.Run("Test get on accounting-method node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on accounting-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "invalid"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + t.Run("Test get on accounting-method node", func(t *testing.T) { + // Instead of expecting a valid response, we expect an error + err := processGetRequest(url, nil, "", false) // Assuming that an error is returned when invalid + if err == nil { + t.Error("Expected an error for invalid accounting method, but got none") + } else { + t.Logf("Correctly received error for invalid accounting method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on accounting-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting performing GET ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius,invalid,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + t.Run("Test get on accounting-method node", func(t *testing.T) { + // Instead of expecting a valid response, we expect an error + err := processGetRequest(url, nil, "", false) // Assuming that an error is returned when invalid + if err == nil { + t.Error("Expected an error for invalid accounting method, but got none") + } else { + t.Logf("Correctly received error for invalid accounting method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + t.Log("++++++++++++++ Done Performing Get on accounting-method node ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting Method for REPLACE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing REPLACE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"TACACS_ALL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+"}}} + t.Run("Test replace on accounting-method node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify replace on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Accounting Method Transformations for REPLACE++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting Method for REPLACE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing REPLACE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"LOCAL\",\"ldap\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "local,ldap"}}} + t.Run("Test replace on accounting-method node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify replace on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Accounting Method Transformations for REPLACE++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting Method for REPLACE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius,local,ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing REPLACE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"LOCAL\",\"TACACS_ALL\",\"RADIUS_ALL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "local,tacacs+,radius"}}} + t.Run("Test replace on accounting-method node", processSetRequest(url, url_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify replace on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Accounting Method Transformations for REPLACE++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting Method for REPLACE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing REPLACE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"invalid\"]}" + t.Run("Test replace on accounting-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PUT", false, nil) + if err == nil { + t.Error("Expected an error for invalid accounting method, but got none") + } else { + t.Logf("Correctly received error for invalid accounting method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Accounting Method Transformations for REPLACE++++++++++++++") + + t.Log("++++++++++++++ Starting Test: accounting Method for REPLACE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing REPLACE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"invalid\",\"default\"]}" + t.Run("Test replace on accounting-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PUT", false, nil) + if err == nil { + t.Error("Expected an error for invalid accounting method, but got none") + } else { + t.Logf("Correctly received error for invalid accounting method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing Accounting Method Transformations for REPLACE++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Accounting Method for UPDATE oper++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "ldap"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing UPDATE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"LOCAL\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "ldap,local"}}} + t.Run("Test update on accounting-method node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + + // Test Case 2: UPDATE with multiple values when no initial values are present + t.Log("\n\n+++++++++++++ Performing UPDATE on accounting-method node with no initial values ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"LOCAL\", \"default\"]}" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "local,default"}}} + t.Run("Test update on accounting-method node", processSetRequest(url, url_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify update on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing accounting Method Transformations for UPDATE ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing UPDATE on accounting-method node with default string ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"invalid\"]}" + t.Run("Test replace on accounting-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PATCH", false, nil) + if err == nil { + t.Error("Expected an error for invalid accounting method, but got none") + } else { + t.Logf("Correctly received error for invalid accounting method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing accounting Method Transformations for UPDATE ++++++++++++++") + + t.Log("\n\n+++++++++++++ Performing UPDATE on accounting-method node with default string ++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + url_body_json = "{\"openconfig-system:accounting-method\": [\"default\",\"invalid\"]}" + t.Run("Test replace on accounting-method node", func(t *testing.T) { + err := processSetRequest(url, url_body_json, "PATCH", false, nil) + if err == nil { + t.Error("Expected an error for invalid accounting method, but got none") + } else { + t.Logf("Correctly received error for invalid accounting method: %v", err) + } + }) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing accounting Method Transformations for UPDATE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Accounting Method for DELETE oper ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "ldap,local"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on accounting-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing accounting Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Accounting Method for DELETE oper ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on accounting-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing accounting Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Accounting Method for DELETE oper ++++++++++++++") + pre_req_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": "tacacs+,radius,ldap,local,default"}}} + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on accounting-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing accounting Method Transformations for DELETE ++++++++++++++") + + t.Log("++++++++++++++ Starting Test: Accounting Method for DELETE oper when db is null++++++++++++++") + cleanuptbl = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"login": ""}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++++++++ Performing DELETE on accounting-method node ++++++++++++") + url = "/openconfig-system:system/aaa/accounting/config/accounting-method" + expected_map = map[string]interface{}{"AAA": map[string]interface{}{"accounting": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Test delete on accounting-method node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Run("Verify delete on accounting-method node", verifyDbResult(rclient, "AAA|accounting", expected_map, false)) + + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done Performing accounting Method Transformations for DELETE ++++++++++++++") +} + +func Test_Aaa_ServerGroupFunctions(t *testing.T) { + t.Log("++++++++++++++ POST (CREATE)operation for Server Group tacacs Functions ++++++++++++++") + t.Log("+++++POST for XPATH: /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.1.1.1]/tacacs/config ++++++++++") + pre_req_map := map[string]interface{}{} + cleanuptbl := map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": ""}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + create_url := "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.1.1.1]/tacacs/config" + create_body_json := "{\"openconfig-aaa-tacacs:secret-key\":\"bngss\", \"openconfig-aaa-tacacs:port\":22}" + expected_map := map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 22}}} + + t.Run("Test POST(CREATE) on server-group node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("Verify POST (CREATE) on server-group tacacs node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done POST operation on Server Group tacacs Functions ++++++++++++++") + + t.Log("++++++++++++++ GET operation for Server Group tacacs Functions ++++++++++++++") + pre_req_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 22}}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url := "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.1.1.1]/tacacs/config" + expected_get_json := "{\"openconfig-system:config\":{\"secret-key\":\"bngss\", \"port\":22}}" + + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation on Server Group tacacs Functions ++++++++++++++") + + t.Log("++++++++++++++ PATCH(Update) operation for Server Group tacacs Functions ++++++++++++++") + pre_req_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 22}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + patch_url := "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.1.1.1]/tacacs/config" + patch_body_json := "{\"openconfig-system:config\": {\"openconfig-aaa-tacacs:secret-key\":\"bxb2345\", \"openconfig-aaa-tacacs:port\":34}}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bxb2345", "tcp_port": 34}}} + + t.Run("Test PATCH (UPDATE) on server-group node", processSetRequest(patch_url, patch_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify update (PATCH) on server-group tacacs node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map, false)) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PATCH (Update) operation on Server Group tacacs Functions ++++++++++++++") + t.Log("++++++++++++++ PUT(Replace) operation for Server Group tacacs Functions ++++++++++++++") + pre_req_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 22}}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + put_url := "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.1.1.1]/tacacs/config" + put_body_json := "{\"openconfig-system:config\": {\"openconfig-aaa-tacacs:secret-key\":\"bxb2345\", \"openconfig-aaa-tacacs:port\":34}}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bxb2345", "tcp_port": 34}}} + + t.Run("Test PUT (REPLACE) on server-group node", processSetRequest(put_url, put_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify update (PUT) on server-group tacacs node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map, false)) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT (replace) operation on Server Group tacacs Functions ++++++++++++++") + + /* ------------------------------------------------------------------------------------------------- */ + // Pre required configs + // Load mgmt vrf config + pre_req_map = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": map[string]interface{}{"mgmtVrfEnabled": "true"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load mgmt port + pre_req_map = map[string]interface{}{"MGMT_PORT": map[string]interface{}{"eth0": map[string]interface{}{"NULL": "NULL"}, "eth1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load mgmt interface prefix + pre_req_map = map[string]interface{}{"MGMT_INTERFACE": map[string]interface{}{"eth0|11.11.11.11/24": map[string]interface{}{"gwaddr": "11.11.11.1"}, "eth1|22.22.22.22/32": map[string]interface{}{"gwaddr": "22.22.22.1"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load VRF + pre_req_map = map[string]interface{}{"VRF": map[string]interface{}{"Vrf1": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load Port + pre_req_map = map[string]interface{}{"PORT": map[string]interface{}{"Ethernet4": map[string]interface{}{"NULL": "NULL"}, "Ethernet8": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + + // Load Interface prefix + pre_req_map = map[string]interface{}{"INTERFACE": map[string]interface{}{"Ethernet4": map[string]interface{}{"vrf_name": "Vrf1"}, "Ethernet4|33.33.33.33": map[string]interface{}{"NULL": "NULL"}, "Ethernet8|33.33.33.33": map[string]interface{}{"NULL": "NULL"}, "Ethernet8|44.44.44.44/24": map[string]interface{}{"NULL": "NULL"}}} + loadDB(db.ConfigDB, pre_req_map) + + t.Log("++++++++++++++ POST (CREATE)operation for Server Group tacacs source-address Functions ++++++++++++++") + pre_req_map = map[string]interface{}{} + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": ""}} + cleanuptbl2 := map[string]interface{}{"TACPLUS": map[string]interface{}{"global": ""}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.1.1.1]/tacacs/config" + create_body_json = "{\"openconfig-aaa-tacacs:source-address\":\"11.11.11.11\", \"openconfig-aaa-tacacs:port\":22}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"vrf": "mgmt", "tcp_port": 22}}} + + t.Run("Test POST(CREATE) on server-group node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("Verify POST (CREATE) on server-group tacacs node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map, false)) + time.Sleep(1 * time.Second) + expected_map2 := map[string]interface{}{"TACPLUS": map[string]interface{}{"global": map[string]interface{}{"src_intf": "eth0"}}} + time.Sleep(1 * time.Second) + t.Run("Verify POST (CREATE) on server-group tacacs node", verifyDbResult(rclient, "TACPLUS|global", expected_map2, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + unloadDB(db.ConfigDB, cleanuptbl2) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Done POST operation on Server Group tacacs Functions ++++++++++++++") + + t.Log("++++++++++++++ GET operation for Server Group tacacs source-addressFunctions ++++++++++++++") + pre_req_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"vrf": "mgmt", "tcp_port": 22}}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + pre_req_map2 := map[string]interface{}{"TACPLUS": map[string]interface{}{"global": map[string]interface{}{"src_intf": "eth0"}}} + + loadDB(db.ConfigDB, pre_req_map2) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.1.1.1]/tacacs/config" + expected_get_json = "{\"openconfig-system:config\":{\"source-address\":\"11.11.11.11\", \"port\":22}}" + + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ GET operation for Server Groups root level ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups" + expected_get_json = "{\"openconfig-system:server-groups\":{\"server-group\":[{\"name\":\"tacacs+\",\"config\":{\"name\":\"tacacs+\"}, \"servers\":{\"server\":[{\"address\":\"1.1.1.1\", \"config\":{\"address\":\"1.1.1.1\"}, \"tacacs\":{\"config\":{\"port\":22, \"source-address\": \"11.11.11.11\"}}}]}, \"state\":{\"name\":\"tacacs+\"}}]}}" + + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + t.Log("++++++++++++++ GET operation for Server Group servers root level ++++++++++++++") + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers" + expected_get_json = "{\"openconfig-system:servers\":{\"server\":[{\"address\":\"1.1.1.1\", \"config\":{\"address\":\"1.1.1.1\"}, \"tacacs\":{\"config\":{\"port\":22, \"source-address\": \"11.11.11.11\"}}}]}}" + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ GET operation for Server Group key level ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]" + expected_get_json = "{\"openconfig-system:server-group\": [{\"name\": \"tacacs+\",\"config\":{\"name\":\"tacacs+\"}, \"servers\":{\"server\":[{\"address\":\"1.1.1.1\", \"config\":{\"address\":\"1.1.1.1\"}, \"tacacs\":{\"config\":{\"port\":22, \"source-address\": \"11.11.11.11\"}}}]}, \"state\":{\"name\":\"tacacs+\"}}]}" + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + cleanuptbl2 = map[string]interface{}{"TACPLUS": map[string]interface{}{"global": ""}} + unloadDB(db.ConfigDB, cleanuptbl2) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation on Server Group tacacs source-address Functions ++++++++++++++") + + t.Log("++++++++++++++ POST (CREATE)operation for Server Group radius source-address Functions ++++++++++++++") + pre_req_map = map[string]interface{}{} + cleanuptbl = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": ""}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=2.2.2.2]/radius/config" + create_body_json = "{\"openconfig-aaa:source-address\":\"11.11.11.11\", \"openconfig-aaa:auth-port\":1812}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"auth_port": 1812, "vrf": "mgmt", "src_intf": "eth0"}}} + + t.Run("Test POST(CREATE) on server-group node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("Verify POST (CREATE) on server-group radius address node", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Done POST operation on Server Group radius Functions ++++++++++++++") + t.Log("++++++++++++++ GET operation for Server Group radius source-addressFunctions ++++++++++++++") + pre_req_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"vrf": "mgmt", "src_intf": "eth0"}}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=2.2.2.2]/radius/config" + expected_get_json = "{\"openconfig-system:config\":{\"source-address\":\"11.11.11.11\"}}" + + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation on Server Group radius source-address Functions ++++++++++++++") + // Clean interface prefix + cleanuptbl = map[string]interface{}{"INTERFACE": map[string]interface{}{"Ethernet4": "", "Ethernet4|33.33.33.33": "", "Ethernet8|33.33.33.33": "", "Ethernet8|44.44.44.44/24": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean mgmt interface prefix + cleanuptbl = map[string]interface{}{"MGMT_INTERFACE": map[string]interface{}{"eth0|11.11.11.11/24": "", "eth1|22.22.22.22/32": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean Port + cleanuptbl = map[string]interface{}{"PORT": map[string]interface{}{"Ethernet4": "", "Ethernet8": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean mgmt port + cleanuptbl = map[string]interface{}{"MGMT_PORT": map[string]interface{}{"eth0": "", "eth1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean VRF + cleanuptbl = map[string]interface{}{"VRF": map[string]interface{}{"Vrf1": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + + // Clean mgmt vrf config + cleanuptbl = map[string]interface{}{"MGMT_VRF_CONFIG": map[string]interface{}{"vrf_global": ""}} + unloadDB(db.ConfigDB, cleanuptbl) + +} + +func Test_Aaa_ServerGroupFunctions_at_root_levels(t *testing.T) { + /* POST /openconfig-system:system/aaa/server-groups + * PUT /openconfig-system:system/aaa/server-groups + * PATCH /openconfig-system:system/aaa/server-groups + * GET /openconfig-system:system/aaa/server-groups + * DELETE /openconfig-system:system/aaa/server-groups + */ + + t.Log("++++++++++++++ Performing POST (CREATE) operation for Server Group address /server-groups++++++++++++++") + pre_req_map := map[string]interface{}{} + cleanuptbl := map[string]interface{}{ + "TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": ""}, + "RADIUS_SERVER": map[string]interface{}{"2.2.2.2": ""}, // Clean up for RADIUS server + } + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + create_url1 := "/openconfig-system:system/aaa/server-groups" + create_body_json1 := "{\"openconfig-system:server-group\":[{\"name\":\"tacacs+\",\"config\":{\"name\":\"tacacs+\"},\"servers\":{\"server\":[{\"address\":\"1.1.1.1\",\"config\":{\"address\":\"1.1.1.1\"},\"tacacs\":{\"config\":{\"secret-key\":\"bngss\"}}}]}},{\"name\":\"radius\",\"config\":{\"name\":\"radius\"},\"servers\":{\"server\":[{\"address\":\"2.2.2.2\",\"config\":{\"address\":\"2.2.2.2\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey\"}}}]}}]}" + t.Run("Test POST(CREATE) on server-groups node", processSetRequest(create_url1, create_body_json1, "POST", false, nil)) + time.Sleep(1 * time.Second) + expected_map1 := map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 49}}} + expected_map2 := map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"passkey": "radiuskey", "auth_port": 1812}}} + t.Run("Verify POST (CREATE) on server-group tacacs+ node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map1, false)) + time.Sleep(1 * time.Second) + t.Run("Verify POST (CREATE) on server-group radius node", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map2, false)) + time.Sleep(1 * time.Second) + // t.Log("Unloading data from the database...") + // unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done POST operation on Server Group address recent server-groups ++++++++++++++") + + t.Log("++++++++++++++ Performing PUT (REPLACE) operation for Server Group address /server-groups++++++++++++++") + create_url1 = "/openconfig-system:system/aaa/server-groups" + create_body_json1 = "{\"openconfig-system:server-groups\": {\"openconfig-system:server-group\":[{\"name\":\"tacacs+\",\"config\":{\"name\":\"tacacs+\"},\"servers\":{\"server\":[{\"address\":\"1.1.1.1\",\"config\":{\"address\":\"1.1.1.1\"},\"tacacs\":{\"config\":{\"secret-key\":\"sonicss\"}}}]}},{\"name\":\"radius\",\"config\":{\"name\":\"radius\"},\"servers\":{\"server\":[{\"address\":\"2.2.2.2\",\"config\":{\"address\":\"2.2.2.2\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey_changed\"}}}]}}]}}" + t.Run("Test PUT(REPLACE) on server-groups node", processSetRequest(create_url1, create_body_json1, "PUT", false, nil)) + time.Sleep(1 * time.Second) + expected_map1 = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "sonicss", "tcp_port": 49}}} + expected_map2 = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"passkey": "radiuskey_changed", "auth_port": 1812}}} + t.Run("Verify PUT (REPLACE) on server-group tacacs+ node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map1, false)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT (REPLACE) on server-group radius node", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map2, false)) + time.Sleep(1 * time.Second) + // t.Log("Unloading data from the database...") + // unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on Server Group address recent server-groups ++++++++++++++") + + t.Log("++++++++++++++ Performing PATCH (UPDATE) operation for Server Group address /server-groups++++++++++++++") + create_url1 = "/openconfig-system:system/aaa/server-groups" + create_body_json1 = "{\"openconfig-system:server-groups\": {\"openconfig-system:server-group\":[{\"name\":\"tacacs+\",\"config\":{\"name\":\"tacacs+\"},\"servers\":{\"server\":[{\"address\":\"1.1.1.1\",\"config\":{\"address\":\"1.1.1.1\"},\"tacacs\":{\"config\":{\"port\":50}}}]}},{\"name\":\"radius\",\"config\":{\"name\":\"radius\"},\"servers\":{\"server\":[{\"address\":\"2.2.2.2\",\"config\":{\"address\":\"2.2.2.2\"},\"radius\":{\"config\":{\"auth-port\":1815}}}]}}]}}" + t.Run("Test PATCH(UPDATE) on server-groups node", processSetRequest(create_url1, create_body_json1, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + expected_map1 = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "sonicss", "tcp_port": 50}}} + expected_map2 = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"passkey": "radiuskey_changed", "auth_port": 1815}}} + t.Run("Verify PATCH (REPLACE) on server-group tacacs+ node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map1, false)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH (REPLACE) on server-group radius node", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map2, false)) + time.Sleep(1 * time.Second) + // t.Log("Unloading data from the database...") + // unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PATCH operation on Server Group address recent server-groups ++++++++++++++") + + /* GET Operation on /openconfig-system:system/aaa/server-groups */ + t.Log("++++++++++++++ Performing GET operation for Server Groups root level ++++++++++++++") + url := "/openconfig-system:system/aaa/server-groups" + expected_get_json := "{\"openconfig-system:server-groups\":{\"server-group\":[{\"name\":\"radius\",\"config\":{\"name\":\"radius\"},\"servers\":{\"server\":[{\"address\":\"2.2.2.2\",\"config\":{\"address\":\"2.2.2.2\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey_changed\", \"auth-port\":1815}}}]},\"state\":{\"name\":\"radius\"}}, {\"name\":\"tacacs+\",\"config\":{\"name\":\"tacacs+\"},\"servers\":{\"server\":[{\"address\":\"1.1.1.1\", \"config\":{\"address\":\"1.1.1.1\"}, \"tacacs\":{\"config\":{\"port\":50, \"secret-key\":\"sonicss\"}}}]}, \"state\":{\"name\":\"tacacs+\"}}]}}" + + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + + /* DELETE Operation on /openconfig-system:system/aaa/server-groups */ + t.Log("++++++++++++++ DELETE operation for Server Groups root level ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups" + t.Log(" /openconfig-system:system/aaa/server-groups Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del := map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map_del, false)) + expected_map_del2 := map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map_del2, false)) + time.Sleep(1 * time.Second) + + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + + /* POST /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+] + * POST /openconfig-system:system/aaa/server-groups/server-group[name=radius] + * PUT /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+] + * PUT /openconfig-system:system/aaa/server-groups/server-group[name=radius] + * PATCH /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+] + * PATCH /openconfig-system:system/aaa/server-groups/server-group[name=radius] + * GET /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+] + * GET /openconfig-system:system/aaa/server-groups/server-group[name=radius] + * DELETE /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+] + * DELETE /openconfig-system:system/aaa/server-groups/server-group[name=radius] + */ + + t.Log("++++++++++++++ Performing POST (CREATE) operation for TACACS+ Server Groups with Multiple Servers ++++++++++++++") + pre_req_map = map[string]interface{}{} + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": "", "1.1.1.2": ""}, "RADIUS_SERVER": map[string]interface{}{"2.2.2.2": "", "2.2.2.3": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + tacacs_url := "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]" + tacacs_post_body_json := "{\"servers\":{\"server\":[{\"address\":\"1.1.1.1\",\"config\":{\"address\":\"1.1.1.1\"},\"tacacs\":{\"config\":{\"secret-key\":\"bngss\"}}},{\"address\":\"1.1.1.2\",\"config\":{\"address\":\"1.1.1.2\"},\"tacacs\":{\"config\":{\"secret-key\":\"tacacssecret\"}}}]}}" + expected_map1 = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 49}}} + expected_map2 = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.2": map[string]interface{}{"passkey": "tacacssecret", "tcp_port": 49}}} + t.Run("Test POST(CREATE) on TACACS+ server-group with multiple servers", processSetRequest(tacacs_url, tacacs_post_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST (CREATE) on server-group tacacs+ node at system/aaa/server-groups/server-group[name=tacacs+]", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map1, false)) + time.Sleep(1 * time.Second) + t.Run("Verify POST (CREATE) on server-group tacacs+ node system/aaa/server-groups/server-group[name=tacacs+]", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.2", expected_map2, false)) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Performing POST (CREATE) operation for RADIUS Server Groups with Multiple Servers ++++++++++++++") + radius_url := "/openconfig-system:system/aaa/server-groups/server-group[name=radius]" + radius_post_body_json := "{\"servers\":{\"server\":[{\"address\":\"2.2.2.2\",\"config\":{\"address\":\"2.2.2.2\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey\"}}},{\"address\":\"2.2.2.3\",\"config\":{\"address\":\"2.2.2.3\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey\"}}}]}}" + expected_map3 := map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"auth_port": 1812, "passkey": "radiuskey"}}} + t.Run("Test POST(CREATE) on RADIUS server-group with multiple servers at system/aaa/server-groups/server-group[name=radius]", processSetRequest(radius_url, radius_post_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify POST (CREATE) on server-group radius node at at system/aaa/server-groups/server-group[name=radius]", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map3, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done POST operation on TACACS+ and RADIUS Server Groups with Multiple Servers /server-groups/server-group++++++++++++++") + + t.Log("++++++++++++++ Perfroming PUT (REPLACE) operation for TACACS+ Server Groups with Multiple Servers ++++++++++++++") + tacacs_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]" + tacacs_post_body_json = "{\"openconfig-system:server-group\": [{\"name\":\"tacacs+\", \"config\":{\"name\":\"tacacs+\"},\"servers\":{\"server\":[{\"address\":\"1.1.1.1\",\"config\":{\"address\":\"1.1.1.1\"},\"tacacs\":{\"config\":{\"secret-key\":\"bngss2\", \"port\":50}}},{\"address\":\"1.1.1.2\",\"config\":{\"address\":\"1.1.1.2\"},\"tacacs\":{\"config\":{\"secret-key\":\"tacacssecret2\", \"port\":50}}}]}}]}" + expected_map1 = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bngss2", "tcp_port": 50}}} + expected_map2 = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.2": map[string]interface{}{"passkey": "tacacssecret2", "tcp_port": 50}}} + t.Run("Test PUT(REPLACE) on TACACS+ server-group with multiple servers", processSetRequest(tacacs_url, tacacs_post_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT (REPLACE) on server-group tacacs+ node at system/aaa/server-groups/server-group[name=tacacs+]", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map1, false)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT (REPLACE) on server-group tacacs+ node system/aaa/server-groups/server-group[name=tacacs+]", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.2", expected_map2, false)) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Performing PUT (REPLACE) operation for RADIUS Server Groups with Multiple Servers ++++++++++++++") + radius_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]" + radius_put_body_json := "{\"openconfig-system:server-group\":[{\"name\":\"radius\", \"config\":{\"name\":\"radius\"},\"servers\":{\"server\":[{\"address\":\"2.2.2.2\",\"config\":{\"address\":\"2.2.2.2\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey2\", \"auth-port\":1921}}},{\"address\":\"2.2.2.3\",\"config\":{\"address\":\"2.2.2.3\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey2\",\"auth-port\":1852}}}]}}]}" + expected_map3 = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"auth_port": 1921, "passkey": "radiuskey2"}}} + expected_map4 := map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.3": map[string]interface{}{"auth_port": 1852, "passkey": "radiuskey2"}}} + t.Run("Test PUT(REPLACE) on RADIUS server-group with multiple servers at system/aaa/server-groups/server-group[name=radius]", processSetRequest(radius_url, radius_put_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT (REPLACE) on server-group radius node at at system/aaa/server-groups/server-group[name=radius]", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map3, false)) + time.Sleep(1 * time.Second) + t.Run("Verify PUT (REPLACE) on server-group radius node at at system/aaa/server-groups/server-group[name=radius]", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.3", expected_map4, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on TACACS+ and RADIUS Server Groups with Multiple Servers /server-groups/server-group++++++++++++++") + + t.Log("++++++++++++++ Performing PATCH (UPDATE) operation for TACACS+ Server Groups with Multiple Servers ++++++++++++++") + tacacs_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]" + tacacs_post_body_json = "{\"openconfig-system:server-group\": [{\"name\":\"tacacs+\", \"config\":{\"name\":\"tacacs+\"},\"servers\":{\"server\":[{\"address\":\"1.1.1.1\",\"config\":{\"address\":\"1.1.1.1\"},\"tacacs\":{\"config\":{\"secret-key\":\"bngss\", \"port\":50}}},{\"address\":\"1.1.1.2\",\"config\":{\"address\":\"1.1.1.2\"},\"tacacs\":{\"config\":{\"secret-key\":\"tacacssecret\", \"port\":50}}}]}}]}" + expected_map1 = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 50}}} + expected_map2 = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.2": map[string]interface{}{"passkey": "tacacssecret", "tcp_port": 50}}} + t.Run("Test PUT(REPLACE) on TACACS+ server-group with multiple servers", processSetRequest(tacacs_url, tacacs_post_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH (UPDATE) on server-group tacacs+ node at system/aaa/server-groups/server-group[name=tacacs+]", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map1, false)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH (UPDATE) on server-group tacacs+ node system/aaa/server-groups/server-group[name=tacacs+]", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.2", expected_map2, false)) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Performing PATCH (UPDATE) operation for RADIUS Server Groups with Multiple Servers ++++++++++++++") + radius_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]" + radius_patch_body_json := "{\"openconfig-system:server-group\":[{\"name\":\"radius\", \"config\":{\"name\":\"radius\"},\"servers\":{\"server\":[{\"address\":\"2.2.2.2\",\"config\":{\"address\":\"2.2.2.2\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey\", \"auth-port\":1921}}},{\"address\":\"2.2.2.3\",\"config\":{\"address\":\"2.2.2.3\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey\",\"auth-port\":1852}}}]}}]}" + expected_map3 = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{"auth_port": 1921, "passkey": "radiuskey"}}} + expected_map4 = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.3": map[string]interface{}{"auth_port": 1852, "passkey": "radiuskey"}}} + t.Run("Test PATCH(UPDATE) on RADIUS server-group with multiple servers at system/aaa/server-groups/server-group[name=radius]", processSetRequest(radius_url, radius_patch_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH (UPDATE) on server-group radius node at at system/aaa/server-groups/server-group[name=radius]", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map3, false)) + time.Sleep(1 * time.Second) + t.Run("Verify PATCH (UPDATE) on server-group radius node at at system/aaa/server-groups/server-group[name=radius]", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.3", expected_map4, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PATCH operation on TACACS+ and RADIUS Server Groups with Multiple Servers /server-groups/server-group++++++++++++++") + + /* GET Operation on /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+] */ + t.Log("++++++++++++++ Performing GET operation for TACACS+ Server Groups with Multiple Servers ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]" + expected_get_json = "{\"openconfig-system:server-group\": [{\"name\":\"tacacs+\", \"config\":{\"name\":\"tacacs+\"},\"servers\":{\"server\":[{\"address\":\"1.1.1.1\",\"config\":{\"address\":\"1.1.1.1\"},\"tacacs\":{\"config\":{\"secret-key\":\"bngss\", \"port\":50}}},{\"address\":\"1.1.1.2\",\"config\":{\"address\":\"1.1.1.2\"},\"tacacs\":{\"config\":{\"secret-key\":\"tacacssecret\", \"port\":50}}}]}, \"state\":{\"name\":\"tacacs+\"}}]}" + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + + /* GET Operation on /openconfig-system:system/aaa/server-groups/server-group[name=radius] */ + t.Log("++++++++++++++ Performing GET operation for radius Server Groups with Multiple Servers ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]" + expected_get_json = "{\"openconfig-system:server-group\":[{\"name\":\"radius\", \"config\":{\"name\":\"radius\"},\"servers\":{\"server\":[{\"address\":\"2.2.2.2\",\"config\":{\"address\":\"2.2.2.2\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey\", \"auth-port\":1921}}},{\"address\":\"2.2.2.3\",\"config\":{\"address\":\"2.2.2.3\"},\"radius\":{\"config\":{\"secret-key\":\"radiuskey\",\"auth-port\":1852}}}]}, \"state\":{\"name\":\"radius\"}}]}" + t.Run("Test GET on server-group node", processGetRequest(url, nil, expected_get_json, false)) + + t.Log("++++++++++++++ Done GET operation on TACACS+ and RADIUS Server Groups with Multiple Servers /server-groups/server-group++++++++++++++") + + /* DELETE Operation on /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+] */ + t.Log("++++++++++++++ Performing DELETE operation for radius Server Groups with Multiple Servers ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.1", expected_map_del, false)) + expected_map_del = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.2": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "TACPLUS_SERVER|1.1.1.2", expected_map_del, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done DELETE operation for tacplus Server Groups with Multiple Servers ++++++++++++++") + + /* DELETE Operation on /openconfig-system:system/aaa/server-groups/server-group[name=radius] */ + t.Log("++++++++++++++ Performing DELETE operation for radius Server Groups with Multiple Servers ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.2": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.2", expected_map_del, false)) + expected_map_del = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"2.2.2.3": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "RADIUS_SERVER|2.2.2.3", expected_map_del, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done DELETE operation for radius Server Groups with Multiple Servers ++++++++++++++") + + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + /* POST /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers + * POST /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers + * PUT /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers + * PUT /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers + * PATCH /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers + * PATCH /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers + * GET /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers + * GET /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers + * DELETE /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers + * DELETE /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers + */ + pre_req_map = map[string]interface{}{} + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": ""}, "RADIUS_SERVER": map[string]interface{}{"1.2.2.2": ""}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Performing POST (create)operation for servergroup tacacs+ servers node ++++++++++++++") + create_url := "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers" + create_body_json := "{\"openconfig-system:server\": [{\"address\": \"1.2.2.1\", \"config\": { \"address\": \"1.2.2.1\",\"timeout\": 5}, \"tacacs\":{\"config\":{\"port\":50, \"secret-key\":\"bngss\"}}}]}" + expected_map := map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"timeout": 5, "passkey": "bngss", "tcp_port": 50}}} + + t.Run("test post(create) on server-group/servers node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("verify post (create) on server-group/servers tacacs+ node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done post operation on server group/servers tacacs+ functions ++++++++++++++") + + t.Log("++++++++++++++ Performing POST (create)operation for servergroup radius servers node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers" + create_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.2.2.2\", \"config\": { \"address\": \"1.2.2.2\",\"timeout\": 5}, \"radius\":{\"config\":{\"auth-port\":1813, \"secret-key\":\"radius-key\", \"retransmit-attempts\":2}}}]}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"timeout": 5, "passkey": "radius-key", "auth_port": 1813, "retransmit": 2}}} + + t.Run("test post(create) on server-group/servers node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify post (create) on server-group tacacs+ node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Performing PUT (Replace)operation for servergroup tacacs+ servers node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers" + create_body_json = "{\"openconfig-system:servers\": {\"server\": [{\"address\": \"1.2.2.1\", \"config\": { \"address\": \"1.2.2.1\",\"timeout\": 6}, \"tacacs\":{\"config\":{\"port\":55, \"secret-key\":\"bngss2\"}}}]}}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"timeout": 6, "passkey": "bngss2", "tcp_port": 55}}} + + t.Run("test PUT(REPLACE) on server-group tacacs+ servers node", processSetRequest(create_url, create_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify PUT (REPLACE) on server-group tacacs+ servers node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on server group tacacs+ servers node ++++++++++++++") + + t.Log("++++++++++++++ Performing PUT (Replace)operation for servergroup radius servers node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers" + create_body_json = "{\"openconfig-system:servers\": {\"server\": [{\"address\": \"1.2.2.2\", \"config\": { \"address\": \"1.2.2.2\",\"timeout\": 6}, \"radius\":{\"config\":{\"auth-port\":1813, \"secret-key\":\"radius-key2\", \"retransmit-attempts\":4}}}]}}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"timeout": 6, "passkey": "radius-key2", "auth_port": 1813, "retransmit": 4}}} + + t.Run("test PUT(REPLACE) on server-group radius servers node", processSetRequest(create_url, create_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify PUT (REPLACE) on server-group radius servers node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on server group radius servers node ++++++++++++++") + + t.Log("++++++++++++++ Performing PATCH (Update)operation for servergroup tacacs+ servers node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers" + create_body_json = "{\"openconfig-system:servers\": {\"server\": [{\"address\": \"1.2.2.1\", \"config\": { \"address\": \"1.2.2.1\",\"timeout\": 1}, \"tacacs\":{\"config\":{\"port\":50, \"secret-key\":\"bngss\"}}}]}}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"timeout": 1, "passkey": "bngss", "tcp_port": 50}}} + + t.Run("test PATCH(Update) on server-group tacacs+ servers node", processSetRequest(create_url, create_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify PATCH (UPDATE) on server-group tacacs+ servers node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PATCH operation on server group tacacs+ servers node ++++++++++++++") + + t.Log("++++++++++++++ Performing PATCH (Update)operation for servergroup radius servers node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers" + create_body_json = "{\"openconfig-system:servers\": {\"server\": [{\"address\": \"1.2.2.2\", \"config\": { \"address\": \"1.2.2.2\",\"timeout\": 1}, \"radius\":{\"config\":{\"auth-port\":1813, \"secret-key\":\"radius-key\", \"retransmit-attempts\":2}}}]}}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"timeout": 1, "passkey": "radius-key", "auth_port": 1813, "retransmit": 2}}} + + t.Run("test PATCH(UPDATE) on server-group radius servers node", processSetRequest(create_url, create_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify PUT (REPLACE) on server-group radius servers node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on server group radius servers node ++++++++++++++") + + t.Log("++++++++++++++ Performing GET operation for Server Group tacacs+/servers ++++++++++++++") + get_url1 := "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers" + expected_get_json1 := "{\"openconfig-system:servers\":{\"server\":[{\"address\":\"1.2.2.1\",\"config\":{\"address\":\"1.2.2.1\", \"timeout\":1},\"tacacs\":{\"config\":{\"secret-key\":\"bngss\", \"port\":50}}}]}}" + t.Run("Test GET on server-group tacacs+ servers node", processGetRequest(get_url1, nil, expected_get_json1, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for Server Group tacacs+/servers ++++++++++++++") + + t.Log("++++++++++++++ Performing GET operation for Server Group radius/servers ++++++++++++++") + get_url1 = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers" + expected_get_json1 = "{\"openconfig-system:servers\":{\"server\":[{\"address\":\"1.2.2.2\",\"config\":{\"address\":\"1.2.2.2\", \"timeout\":1},\"radius\":{\"config\":{\"secret-key\":\"radius-key\", \"auth-port\":1813, \"retransmit-attempts\":2}}}]}}" + t.Run("Test GET on server-group radius servers node", processGetRequest(get_url1, nil, expected_get_json1, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for Server Group radius/servers ++++++++++++++") + + t.Log("++++++++++++++ Performing DELETE operation for Server Group tacacs+/servers ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map_del, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done DELETE operation for Server Group radius/servers ++++++++++++++") + + t.Log("++++++++++++++ Performing DELETE operation for Server Group radius/servers ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map_del, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done DELETE operation for Server Group radius/servers ++++++++++++++") + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + /* POST /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1] + * POST /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2] + * PUT /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1] + * PUT /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[adress=1.2.2.2] + * PATCH /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1] + * PATCH /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2] + * GET /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1] + * GET /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2] + * DELETE /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1] + * DELETE /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2] + */ + pre_req_map = map[string]interface{}{} + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": ""}, "RADIUS_SERVER": map[string]interface{}{"1.2.2.2": ""}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Performing POST (create)operation for servergroup tacacs+ servers/server node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]" + create_body_json = "{\"config\": {\"address\": \"1.2.2.1\",\"timeout\": 8}, \"tacacs\":{\"config\":{\"port\":50, \"secret-key\":\"bngss\"}}}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"timeout": 8, "passkey": "bngss", "tcp_port": 50}}} + + t.Run("test post(create) on server-group/servers/server node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("verify post (create) on server-group/servers tacacs+ node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done post operation on server group tacacs+/servers/server functions ++++++++++++++") + + t.Log("++++++++++++++ Performing POST (create)operation for servergroup radius servers/server node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]" + create_body_json = "{\"config\": { \"address\": \"1.2.2.2\",\"timeout\": 9}, \"radius\":{\"config\":{\"auth-port\":1813, \"secret-key\":\"radius-key\", \"retransmit-attempts\":3}}}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"timeout": 9, "passkey": "radius-key", "auth_port": 1813, "retransmit": 3}}} + + t.Run("test post(create) on server-group radius /servers/server node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify post (create) on server-group radius/servers/server node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done post operation on server group radius/servers/server functions ++++++++++++++") + + t.Log("++++++++++++++ Performing PUT (Replace)operation for servergroup tacacs+ servers/server node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]" + create_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.2.2.1\", \"config\": { \"address\": \"1.2.2.1\",\"timeout\": 1}, \"tacacs\":{\"config\":{\"port\":60, \"secret-key\":\"bngss2\"}}}]}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"timeout": 1, "passkey": "bngss2", "tcp_port": 60}}} + + t.Run("test put(replace) on server-group/servers/server node", processSetRequest(create_url, create_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("verify put (replace) on server-group/servers tacacs+ node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on server group tacacs+/servers/server functions ++++++++++++++") + + t.Log("++++++++++++++ Performing PUT (Replace)operation for servergroup radius servers/server node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]" + create_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.2.2.2\", \"config\": { \"address\": \"1.2.2.2\",\"timeout\": 5}, \"radius\":{\"config\":{\"auth-port\":1812, \"secret-key\":\"radius-key2\", \"retransmit-attempts\":1}}}]}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"timeout": 5, "passkey": "radius-key2", "auth_port": 1812, "retransmit": 1}}} + + t.Run("test PUT(Replace) on server-group radius /servers/server node", processSetRequest(create_url, create_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify put (replace) on server-group radius/servers/server node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on server group radius/servers/server functions ++++++++++++++") + + t.Log("++++++++++++++ Performing PATCH (Update)operation for servergroup tacacs+ servers/server node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]" + create_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.2.2.1\", \"config\": { \"address\": \"1.2.2.1\",\"timeout\": 10}, \"tacacs\":{\"config\":{\"port\":50, \"secret-key\":\"bngss\"}}}]}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"timeout": 10, "passkey": "bngss", "tcp_port": 50}}} + + t.Run("test PATCH(update) on server-group/servers/server node", processSetRequest(create_url, create_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("verify patch (update) on server-group/servers tacacs+ node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PATCH operation on server group tacacs+/servers/server functions ++++++++++++++") + + t.Log("++++++++++++++ Performing PATCH (Update)operation for servergroup radius servers/server node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]" + create_body_json = "{\"openconfig-system:server\": [{\"address\": \"1.2.2.2\", \"config\": { \"address\": \"1.2.2.2\",\"timeout\": 10}, \"radius\":{\"config\":{\"auth-port\":1813, \"secret-key\":\"radius-key\", \"retransmit-attempts\":2}}}]}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"timeout": 10, "passkey": "radius-key", "auth_port": 1813, "retransmit": 2}}} + + t.Run("test PATCH(Update) on server-group radius /servers/server node", processSetRequest(create_url, create_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify patch (update) on server-group radius/servers/server node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PATCH operation on server group radius/servers/server functions ++++++++++++++") + + t.Log("++++++++++++++ Performing GET operation for Server Group tacacs+/servers/server ++++++++++++++") + get_url1 = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]" + expected_get_json1 = "{\"openconfig-system:server\":[{\"address\":\"1.2.2.1\",\"config\":{\"address\":\"1.2.2.1\",\"timeout\":10},\"tacacs\":{\"config\":{\"secret-key\":\"bngss\", \"port\":50}}}]}" + t.Run("Test GET on server-group tacacs+ servers node", processGetRequest(get_url1, nil, expected_get_json1, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for Server Group tacacs+/servers/server ++++++++++++++") + + t.Log("++++++++++++++ Performing GET operation for Server Group radius/servers ++++++++++++++") + get_url1 = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]" + expected_get_json1 = "{\"openconfig-system:server\":[{\"address\":\"1.2.2.2\",\"config\":{\"address\":\"1.2.2.2\",\"timeout\":10},\"radius\":{\"config\":{\"secret-key\":\"radius-key\", \"auth-port\":1813, \"retransmit-attempts\":2}}}]}" + t.Run("Test GET on server-group radius servers/server node", processGetRequest(get_url1, nil, expected_get_json1, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for Server Group radius/servers/server node ++++++++++++++") + + t.Log("++++++++++++++ Performing DELETE operation for Server Group tacacs+/servers/server ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map_del, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done DELETE operation for Server Group tacacs+/servers ++++++++++++++") + + t.Log("++++++++++++++ Performing DELETE operation for Server Group radius/servers ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius servers/server radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map_del, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done DELETE operation for Server Group radius/servers ++++++++++++++") + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + /* POST /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs + * POST /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius + * PUT /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs + * PUT /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[adress=1.2.2.2]/radius + * PATCH /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs + * PATCH /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius + * GET /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs + * GET /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius + * DELETE /openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs + * DELETE /openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius + */ + //pre_req_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"ipaddress": "1.2.2.1"}}, "RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"ipaddress": "1.2.2.2"}}} + pre_req_map = map[string]interface{}{} + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": ""}, "RADIUS_SERVER": map[string]interface{}{"1.2.2.2": ""}} + + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Performing POST (create)operation for servergroup tacacs+ servers/server/tacacs node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs" + create_body_json = "{\"openconfig-system:config\":{\"port\":50, \"secret-key\":\"bngss\"}}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 50}}} + + t.Run("test post(create) on server-group/servers/server/tacacs node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("verify post (create) on server-group tacacs+/servers/tacacs node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done post operation on server group tacacs+/servers/server/tacacs functions ++++++++++++++") + t.Log("++++++++++++++ Performing POST (create)operation for servergroup radius servers/server/radius node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius" + create_body_json = "{\"openconfig-system:config\":{\"auth-port\":1813, \"secret-key\":\"radius-key\", \"retransmit-attempts\":5}}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"passkey": "radius-key", "auth_port": 1813, "retransmit": 5}}} + + t.Run("test post(create) on server-group radius /servers/server/radius node", processSetRequest(create_url, create_body_json, "POST", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify post (create) on server-group radius/servers/server node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done post operation on server group radius/servers/server/radius functions ++++++++++++++") + + t.Log("++++++++++++++ Performing PUT (Replace)operation for servergroup tacacs+ servers/server/tacacs node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs" + create_body_json = "{\"openconfig-system:tacacs\":{\"config\":{\"port\":60, \"secret-key\":\"bngss2\"}}}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"passkey": "bngss2", "tcp_port": 60}}} + + t.Run("test PUT(Replace) on server-group/servers/server/tacacs node", processSetRequest(create_url, create_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("verify PUT (Replace) on server-group/servers/tacacs node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on server group tacacs+/servers/server functions ++++++++++++++") + + t.Log("++++++++++++++ Performing PUT (Replace)operation for servergroup radius servers/server/radius node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius" + create_body_json = "{\"openconfig-system:radius\":{\"config\":{\"auth-port\":1812, \"secret-key\":\"radius-key2\", \"retransmit-attempts\":6}}}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"passkey": "radius-key2", "auth_port": 1812, "retransmit": 6}}} + + t.Run("test PUT(Replace) on server-group radius /servers/server/radius node", processSetRequest(create_url, create_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify post (create) on server-group radius/servers/server/radius node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PUT operation on server group radius/servers/server/radius functions ++++++++++++++") + + t.Log("++++++++++++++ Performing PATCH (Update)operation for servergroup tacacs+ servers/server/tacacs node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs" + create_body_json = "{\"openconfig-system:tacacs\":{\"config\":{\"port\":50, \"secret-key\":\"bngss\"}}}" + expected_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"passkey": "bngss", "tcp_port": 50}}} + + t.Run("test PATCH(update) on server-group/servers/server/tacacs node", processSetRequest(create_url, create_body_json, "PATCH", false, nil)) + time.Sleep(1 * time.Second) + + t.Run("verify patch (update) on server-group/servers/tacacs node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PATCH operation on server group tacacs+/servers/server/tacacs functions ++++++++++++++") + + t.Log("++++++++++++++ Performing PATCH (Update)operation for servergroup radius servers/server/radius node ++++++++++++++") + create_url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius" + create_body_json = "{\"openconfig-system:radius\":{\"config\":{\"auth-port\":1813, \"secret-key\":\"radius-key\", \"retransmit-attempts\":7}}}" + expected_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"passkey": "radius-key", "auth_port": 1813, "retransmit": 7}}} + + t.Run("test PATCH(Update) on server-group radius /servers/server/radius node", processSetRequest(create_url, create_body_json, "PUT", false, nil)) + time.Sleep(1 * time.Second) + t.Run("verify patch (update) on server-group radius/servers/server/radius node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done PATCH operation on server group radius/servers/server/radius functions ++++++++++++++") + + t.Log("++++++++++++++ Performing GET operation for Server Group tacacs+/servers/server/tacacs ++++++++++++++") + get_url1 = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs" + expected_get_json1 = "{\"openconfig-system:tacacs\":{\"config\":{\"secret-key\":\"bngss\", \"port\":50}}}" + t.Run("Test GET on server-group tacacs+ servers node", processGetRequest(get_url1, nil, expected_get_json1, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for Server Group tacacs+/servers/server/tacacs ++++++++++++++") + + t.Log("++++++++++++++ Performing GET operation for Server Group radius/servers/radius ++++++++++++++") + get_url1 = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius" + expected_get_json1 = "{\"openconfig-system:radius\":{\"config\":{\"secret-key\":\"radius-key\", \"auth-port\":1813, \"retransmit-attempts\":7}}}" + t.Run("Test GET on server-group radius servers/server/radius node", processGetRequest(get_url1, nil, expected_get_json1, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for Server Group radius/servers/server node ++++++++++++++") + + t.Log("++++++++++++++ Performing DELETE operation for Server Group tacacs+/servers/server/tacacs ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=tacacs+]/servers/server[address=1.2.2.1]/tacacs" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.2.2.1": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "TACPLUS_SERVER|1.2.2.1", expected_map_del, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done DELETE operation for Server Group tacacs+/servers/server/tacacs ++++++++++++++") + + t.Log("++++++++++++++ Performing DELETE operation for Server Group radius/servers ++++++++++++++") + url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.2.2.2]/radius" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius servers/server radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.2.2.2": map[string]interface{}{"NULL": "NULL"}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "RADIUS_SERVER|1.2.2.2", expected_map_del, false)) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done DELETE operation for Server Group radius/servers/server/radius ++++++++++++++") + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + + t.Log("++++++++++++++ Performing POST (CREATE) operation for TACACS+ and RADIUS Server Groups at server-group container level with Multiple Servers ++++++++++++++") + pre_req_map = map[string]interface{}{} + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": "", "1.1.1.2": ""}, "RADIUS_SERVER": map[string]interface{}{"2.2.2.2": "", "2.2.2.3": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + t.Log("\n\n+++++++++++++ Performing Delete on server-group radius configuration node ++++++++++++") + pre_req_map = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.1.1.2": map[string]interface{}{"passkey": "test123"}}} + loadDB(db.ConfigDB, pre_req_map) // Ensure data is loaded correctly into the DB + time.Sleep(1 * time.Second) + // url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]/servers/server[address=1.1.1.2]/radius/config/secret-key" + url = "/openconfig-system:system/aaa/server-groups/server-group[name=radius]" + t.Log("Before delete: ", db.ConfigDB) // Log before delete + t.Run("Test delete on server-group radius configuration node", processDeleteRequest(url, false)) + time.Sleep(1 * time.Second) + + t.Log("After delete: ", db.ConfigDB) // Log after delete + expected_map_del = map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.1.1.2": map[string]interface{}{}}} + t.Run("Verify delete on server-group radius configuration node", verifyDbResult(rclient, "RADIUS_SERVER|1.1.1.2", expected_map_del, false)) + time.Sleep(1 * time.Second) + + unloadDB(db.ConfigDB, map[string]interface{}{"RADIUS_SERVER": map[string]interface{}{"1.1.1.2": ""}}) + time.Sleep(1 * time.Second) + + t.Log("\n\n+++++++") + + t.Log("++++++++++++++ Performing GET operation for /system/aaa ++++++++++++++") + pre_req_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "secret1", "timeout": 22}}, "RADIUS_SERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"passkey": "secret3", "timeout": 25}}} + t.Log("Pre-requisite map for /system/aaa:", pre_req_map) + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": ""}, "RADIUS_SERVER": map[string]interface{}{"3.3.3.3": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa" + expected_get_json = "{\"openconfig-system:aaa\":{\"server-groups\":{\"server-group\":[{\"config\":{\"name\":\"radius\"}, \"name\":\"radius\", \"servers\":{\"server\":[{\"address\":\"3.3.3.3\", \"config\":{\"address\":\"3.3.3.3\", \"timeout\":25}, \"radius\":{\"config\":{\"secret-key\":\"secret3\"}}}]}, \"state\":{\"name\":\"radius\"}}, {\"config\":{\"name\":\"tacacs+\"}, \"name\":\"tacacs+\", \"servers\":{\"server\":[{\"address\":\"1.1.1.1\", \"config\":{\"address\":\"1.1.1.1\", \"timeout\":22}, \"tacacs\":{\"config\":{\"secret-key\":\"secret1\"}}}]}, \"state\":{\"name\":\"tacacs+\"}}]}}}" + t.Run("Test GET on /system/aaa", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for /system/aaa ++++++++++++++") + + t.Log("++++++++++++++ Performing GET operation for /system/aaa ++++++++++++++") + pre_req_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "secret1", "timeout": 22}}} + t.Log("Pre-requisite map for /system/aaa:", pre_req_map) + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system/aaa" + expected_get_json = "{\"openconfig-system:aaa\":{\"server-groups\":{\"server-group\":[{\"config\":{\"name\":\"tacacs+\"}, \"name\":\"tacacs+\", \"servers\":{\"server\":[{\"address\":\"1.1.1.1\", \"config\":{\"address\":\"1.1.1.1\", \"timeout\":22}, \"tacacs\":{\"config\":{\"secret-key\":\"secret1\"}}}]}, \"state\":{\"name\":\"tacacs+\"}}]}}}" + t.Run("Test GET on /system/aaa", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for /system/aaa tacacs ++++++++++++++") + /* + * Commenting out the test case as the current-datetime, up-time, boot-time are varaible + + t.Log("++++++++++++++ GET operation for /system ++++++++++++++") + pre_req_map = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": map[string]interface{}{"passkey": "secret1", "timeout": 22}}, "RADIUS_SERVER": map[string]interface{}{"3.3.3.3": map[string]interface{}{"passkey": "secret3", "timeout": 25}}} + t.Log("Pre-requisite map for /system:", pre_req_map) + cleanuptbl = map[string]interface{}{"TACPLUS_SERVER": map[string]interface{}{"1.1.1.1": ""}, "RADIUS_SERVER": map[string]interface{}{"3.3.3.3": ""}} + loadDB(db.ConfigDB, pre_req_map) + time.Sleep(1 * time.Second) + url = "/openconfig-system:system" + expected_get_json = "{\"openconfig-system:system\":{\"aaa\":{\"server-groups\":{\"server-group\":[{\"config\":{\"name\":\"radius\"}, \"name\":\"radius\", \"servers\":{\"server\":[{\"address\":\"3.3.3.3\", \"config\":{\"address\":\"3.3.3.3\", \"timeout\":25}, \"radius\":{\"config\":{\"secret-key\":\"secret3\"}}}]}, \"state\":{\"name\":\"radius\"}}, {\"config\":{\"name\":\"tacacs+\"}, \"name\":\"tacacs+\", \"servers\":{\"server\":[{\"address\":\"1.1.1.1\", \"config\":{\"address\":\"1.1.1.1\", \"timeout\":22}, \"tacacs\":{\"config\":{\"secret-key\":\"secret1\"}}}]}, \"state\":{\"name\":\"tacacs+\"}}]}}, \"state\":{\"boot-time\":1750101238566211541, \"current-datetime\":\"2025-06-25T14:07:18Z+00:00\", \"up-time\":759200000000000}}}" + t.Run("Test GET on /system", processGetRequest(url, nil, expected_get_json, false)) + time.Sleep(1 * time.Second) + t.Log("Unloading data from the database...") + unloadDB(db.ConfigDB, cleanuptbl) + time.Sleep(1 * time.Second) + t.Log("++++++++++++++ Done GET operation for /system ++++++++++++++") + + ****/ +} diff --git a/translib/transformer/xlate_del_to_db.go b/translib/transformer/xlate_del_to_db.go index 2fa762924..bfd685e4a 100644 --- a/translib/transformer/xlate_del_to_db.go +++ b/translib/transformer/xlate_del_to_db.go @@ -608,6 +608,8 @@ func yangContainerDelData(xlateParams xlateToParams, dbDataMap *map[db.DBNum]map } } } + } else if isFirstCall && virtualTbl { + fillFields = true } } else { if !spec.hasChildSubTree { @@ -628,8 +630,16 @@ func yangContainerDelData(xlateParams xlateToParams, dbDataMap *map[db.DBNum]map curXlateParams := xlateParams curXlateParams.uri = chldUri curXlateParams.xpath = chldXpath - curXlateParams.tableName = curTbl - curXlateParams.keyName = curKey + if len(curTbl) == 0 && chldSpec.tableName != nil { + curXlateParams.tableName = *chldSpec.tableName + } else { + curXlateParams.tableName = curTbl + } + if len(curKey) == 0 && chldSpec.keyName != nil { + curXlateParams.keyName = *chldSpec.keyName + } else { + curXlateParams.keyName = curKey + } curXlateParams.parentXpath = xlateParams.xpath if curXlateParams.replaceInfo != nil { if curXlateParams.replaceInfo.skipFieldSiblingTraversalForDelete == nil { diff --git a/translib/transformer/xlate_from_db.go b/translib/transformer/xlate_from_db.go index 7cb36caf3..689e71f0b 100644 --- a/translib/transformer/xlate_from_db.go +++ b/translib/transformer/xlate_from_db.go @@ -1405,7 +1405,13 @@ func terminalNodeProcess(inParamsForGet xlateFromDbParams, terminalNodeQuery boo } } } else { - val, ok := (*dbDataMap)[cdb][tbl][tblKey].Field[dbFldName] + /* If table-name, key-name is available for leaf spec */ + var val string + if xYangSpecMap[xpath].tableName != nil && xYangSpecMap[xpath].keyName != nil && (len(tbl) == 0 || len(tblKey) == 0) { + val, ok = (*dbDataMap)[cdb][*xYangSpecMap[xpath].tableName][*xYangSpecMap[xpath].keyName].Field[dbFldName] + } else { + val, ok = (*dbDataMap)[cdb][tbl][tblKey].Field[dbFldName] + } if ok { resVal, _, err := DbToYangType(yangDataType, xpath, val, inParamsForGet.oper) if err != nil { @@ -2036,9 +2042,16 @@ func dbDataToYangJsonCreate(inParamsForGet xlateFromDbParams) (string, bool, err return jsonData, false, nil } } else { - tbl, key, _ := tableNameAndKeyFromDbMapGet((*dbDataMap)[cdb], xpathKeyExtRet.tableName) - inParamsForGet.tbl = tbl - inParamsForGet.tblKey = key + /* If yang annot has explicitly mentioned table-name and key-name for field */ + if (xYangSpecMap[xpathKeyExtRet.xpath].tableName != nil) && len(*xYangSpecMap[xpathKeyExtRet.xpath].tableName) > 0 && + (xYangSpecMap[xpathKeyExtRet.xpath].keyName != nil) && len(*xYangSpecMap[xpathKeyExtRet.xpath].keyName) > 0 { + inParamsForGet.tbl = *xYangSpecMap[xpathKeyExtRet.xpath].tableName + inParamsForGet.tblKey = *xYangSpecMap[xpathKeyExtRet.xpath].keyName + } else { + tbl, key, _ := tableNameAndKeyFromDbMapGet((*dbDataMap)[cdb], xpathKeyExtRet.tableName) + inParamsForGet.tbl = tbl + inParamsForGet.tblKey = key + } var fldValMap map[string]interface{} fldValMap, fldErr = terminalNodeProcess(inParamsForGet, true, yangEntry) if (fldErr != nil) || (len(fldValMap) == 0) { @@ -2079,16 +2092,18 @@ func dbDataToYangJsonCreate(inParamsForGet xlateFromDbParams) (string, bool, err "ygNode: %v, ygot parent obj: %v; inParamsForGet.relUri: %v; error: %v", inParamsForGet.uri, parentUriPath, inParamsForGet.ygSchema.Name, reflect.TypeOf(*inParamsForGet.ygParentObj), inParamsForGet.relUri, err) return "", true, err - } else { + } else if ygotCtx.trgtYgObj != nil { inParamsForGet.ygParentObj = ygotCtx.trgtYgObj inParamsForGet.ygSchema = ygotCtx.trgtYgSchema inParamsForGet.relUri = uriPathList[len(uriPathList)-1] } } - if err := ytypes.Unmarshal(inParamsForGet.ygSchema, *inParamsForGet.ygParentObj, fldValMap); err != nil { - log.Warningf("yangDataFill: error in object unmarshalling: %v; schema: %v; parent obj: %v, "+ - "resFldValMap: %v", inParamsForGet.ygSchema.Name, reflect.TypeOf(*inParamsForGet.ygParentObj), fldValMap) - return "", true, err + if inParamsForGet.ygParentObj != nil { + if err := ytypes.Unmarshal(inParamsForGet.ygSchema, *inParamsForGet.ygParentObj, fldValMap); err != nil { + log.Warningf("yangDataFill: error in object unmarshalling: %v; schema: %v; parent obj: %v, "+ + "resFldValMap: %v", inParamsForGet.ygSchema.Name, reflect.TypeOf(*inParamsForGet.ygParentObj), fldValMap) + return "", true, err + } } } }