Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iosxe_restconf code for TACACS Server #169

Open
ipeph opened this issue Jun 7, 2024 · 5 comments
Open

iosxe_restconf code for TACACS Server #169

ipeph opened this issue Jun 7, 2024 · 5 comments
Labels
question Further information is requested

Comments

@ipeph
Copy link

ipeph commented Jun 7, 2024

Hi I have this JSON result from tacacs API..

{
    "Cisco-IOS-XE-aaa:server": [
        {
            "name": "ISE1",
            "address": {
                "ipv4": "1.1.1.1"
            },
            "key": {
                "encryption": "7",
                "key": "XXX"
            }
        },
        {
            "name": "ISE2",
            "address": {
                "ipv4": "2.2.2.2"
            },
            "key": {
                "encryption": "7",
                "key": "XXX"
            }
        }
    ]
}

How i can translate this code above to use iosxe_restconf, because i want to create another line of ISE config.

I'm using this code below but its failed.

resource "iosxe_restconf" "aaa_server" {
  path = "Cisco-IOS-XE-native:native/tacacs"
  lists = [
    {
      name = "Cisco-IOS-XE-aaa:server"
      key = "name"
      items = [
        {
          name = "ISE3",
          address = jsonencode(
          {"ipv4": "3.3.3.3"}
          ),
          key = jsonencode(
          {"key": {
              "encryption": "7",
              "key": "XXXX"
           }
          }
          )
        }
      ]
    }
  ]
}

Error result :

╷
│ Error: Client Error
│ 
│   with iosxe_restconf.aaa_server,
│   on main.tf line 102, in resource "iosxe_restconf" "aaa_server":
│  102: resource "iosxe_restconf" "aaa_server" {
│ 
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:malformed-message ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/tacacs ErrorMessage:invalid value for: address in /ios:native/ios:tacacs/ios-aaa:server[ios-aaa:name='ISE3']/ios-aaa:address ErrorInfo:}]} {PatchId:
│ GlobalStatus:{Ok:false Errors:{Error:[]}} EditStatus:{Edit:[]} Errors:{Error:[]}}

Thanks.

@ipeph ipeph changed the title Restconf code for TACACS iosxe_restconf code for TACACS Server Jun 7, 2024
@jabielecki
Copy link
Collaborator

Hi @ipeph, a question of fact: Does this dedicated resource work with your setup at all?: https://registry.terraform.io/providers/CiscoDevNet/iosxe/latest/docs/resources/tacacs_server

@danischm danischm added the question Further information is requested label Jun 8, 2024
@danischm
Copy link
Member

danischm commented Jun 8, 2024

As @jabielecki mentioned, the dedicated resource would be the preferred method of configuration. When using iosxe_restconf there is no need to use jsonencode(), you would address nested elements using a "path" syntax:

resource "iosxe_restconf" "aaa_server" {
  path = "Cisco-IOS-XE-native:native/tacacs"
  lists = [
    {
      name = "Cisco-IOS-XE-aaa:server"
      key = "name"
      items = [
        {
          name = "ISE3"
          "address/ipv4" = "3.3.3.3"
          "key/key" = "ABCDEFG"
        }
      ]
    }
  ]
}

@ipeph
Copy link
Author

ipeph commented Jun 9, 2024

Hi @ipeph, a question of fact: Does this dedicated resource work with your setup at all?: https://registry.terraform.io/providers/CiscoDevNet/iosxe/latest/docs/resources/tacacs_server

Hi @jabielecki, yes correct i could use that but i had some problem using this resource.

resource "iosxe_tacacs_server" "ISE1" {
  name         = "ISE1"
  address_ipv4 = "1.1.1.1"
  key          = "XXXXXXX"
}

resource "iosxe_tacacs_server" "ISE2" {
  name         = "ISE2"
  address_ipv4 = "2.2.2.2"
  key          = "XXXXXXX"
}

Output

  # iosxe_tacacs_server.APDC3 will be updated in-place
  ~ resource "iosxe_tacacs_server" "ISE1" {
        id           = "Cisco-IOS-XE-native:native/tacacs/Cisco-IOS-XE-aaa:server=ISE1"
      ~ key          = "153B2F41061B3E2C0667132B170D1514" -> "XXXXXXX"
        name         = "ISE1"
        # (1 unchanged attribute hidden)
    }

  # iosxe_tacacs_server.APDC4 will be updated in-place
  ~ resource "iosxe_tacacs_server" "ISE2" {
        id           = "Cisco-IOS-XE-native:native/tacacs/Cisco-IOS-XE-aaa:server=ISE2"
      ~ key          = "10672D540726070322500C2220223022" -> "XXXXXXX"
        name         = "ISE2"
        # (1 unchanged attribute hidden)
    }

╷
│ Error: Client Error
│ 
│   with iosxe_tacacs_server.ISE1,
│   on main.tf line 127, in resource "iosxe_tacacs_server" "ISE1":
│  127: resource "iosxe_tacacs_server" "ISE1" {
│ 
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:invalid-value ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/tacacs/Cisco-IOS-XE-aaa:server ErrorMessage:inconsistent value: Device refused one or more commands ErrorInfo:}]}
│ {PatchId: GlobalStatus:{Ok:false Errors:{Error:[]}} EditStatus:{Edit:[]} Errors:{Error:[]}}
╵
╷
│ Error: Client Error
│ 
│   with iosxe_tacacs_server.ISE2,
│   on main.tf line 133, in resource "iosxe_tacacs_server" "ISE2":
│  133: resource "iosxe_tacacs_server" "ISE2" {
│ 
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:invalid-value ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/tacacs/Cisco-IOS-XE-aaa:server ErrorMessage:inconsistent value: Device refused one or more commands ErrorInfo:}]}
│ {PatchId: GlobalStatus:{Ok:false Errors:{Error:[]}} EditStatus:{Edit:[]} Errors:{Error:[]}}

Sometimes the state is not sync because terraform sometimes read the encypted value of tacacs so i though i could use the iosxe_restconf resource directly.

@ipeph
Copy link
Author

ipeph commented Jun 9, 2024

As @jabielecki mentioned, the dedicated resource would be the preferred method of configuration. When using iosxe_restconf there is no need to use jsonencode(), you would address nested elements using a "path" syntax:

resource "iosxe_restconf" "aaa_server" {
  path = "Cisco-IOS-XE-native:native/tacacs"
  lists = [
    {
      name = "Cisco-IOS-XE-aaa:server"
      key = "name"
      items = [
        {
          name = "ISE3"
          "address/ipv4" = "3.3.3.3"
          "key/key" = "ABCDEFG"
        }
      ]
    }
  ]
}

Hi @danischm,

Thanks this is work perfectly like charm. And i have some request if its ok with you, this example is not listed on the documentation, maybe if this example can be added on the documentation.

Thanks.

@ipeph
Copy link
Author

ipeph commented Jun 9, 2024

Hi @danischm,

I have another question.
I have this API result from this URL.

https://{{host}}:{{port}}/restconf/data/Cisco-IOS-XE-native:native/aaa/authenticaiton

{
    "Cisco-IOS-XE-aaa:authentication": {
        "attempts": {
            "login": 4
        },
        "enable": {
            "default": {
                "group": "tacacs+",
                "enable": [
                    null
                ]
            }
        },
        "login": [
            {
                "name": "default",
                "a1": {
                    "local": [
                        null
                    ]
                },
                "a2": {
                    "group": "tacacs+"
                }
            }
        ]
    }
}

How i can translate this into correct terraform code ?

I tried this 2 code below, and having an error after applying the code.
1st code

resource "iosxe_restconf" "aaa_authentication" {
  path = "Cisco-IOS-XE-native:native/aaa/authentication"
  attributes = {
    "attempts/login" = 4
    "enable/default/group"  = "tacacs+"
    "enable/default/enable" = null
    "login/name"            = "default"
    "login/a1/local"        = null
    "login/a2/group"        = "tacacs+"
  }
}

output:

Plan: 1 to add, 0 to change, 0 to destroy.
iosxe_restconf.aaa_authentication: Creating...
╷
│ Error: Client Error
│ 
│   with iosxe_restconf.aaa_authentication,
│   on main.tf line 175, in resource "iosxe_restconf" "aaa_authentication":
│  175: resource "iosxe_restconf" "aaa_authentication" {
│ 
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:malformed-message ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/aaa/Cisco-IOS-XE-aaa:authentication ErrorMessage:0: Internal error ErrorInfo:}]} {PatchId: GlobalStatus:{Ok:false Errors:{Error:[]}}
│ EditStatus:{Edit:[]} Errors:{Error:[]}}
╵

2nd code

resource "iosxe_restconf" "aaa_authentication" {
  path = "Cisco-IOS-XE-native:native/aaa/authentication"
  lists = [
    {
      name = "Cisco-IOS-XE-aaa:authentication"
      key = "login"
      items = [
        {
          "attempts/login" = 4
          "enable/default/group"  = "tacacs+"
          "enable/default/enable" = null
          "login/name"            = "default"
          "login/a1/local"        = null
          "login/a2/group"        = "tacacs+"
        }
      ]
    }
  ]
}

output

iosxe_restconf.aaa_authentication: Creating...
╷
│ Error: Client Error
│ 
│   with iosxe_restconf.aaa_authentication,
│   on main.tf line 187, in resource "iosxe_restconf" "aaa_authentication":
│  187: resource "iosxe_restconf" "aaa_authentication" {
│ 
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:malformed-message ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/aaa/Cisco-IOS-XE-aaa:authentication ErrorMessage:0: Internal error ErrorInfo:}]} {PatchId: GlobalStatus:{Ok:false Errors:{Error:[]}}
│ EditStatus:{Edit:[]} Errors:{Error:[]}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants