terraform-routeros / terraform-provider-routeros

Terraform Provider for Mikrotik RouterOS
Mozilla Public License 2.0
165 stars 46 forks source link

Additional info for easy import #488

Open cmdorexe opened 3 weeks ago

cmdorexe commented 3 weeks ago

as example i used "/ip fi ad" foreach i in=[/ip fi ad find dynamic=no] do={put [/ip fi ad get $i]} we get all we are needed out it to import_fw_addr_list.txt

Now we can export it to variable in default section to move.

.id=*1;address=192.168.88.11;comment=example 2;creation-time=1970-01-02 07:00:52;disabled=false;dynamic=false;list=srv
.id=*2;address=192.168.88.12;comment=example 2;creation-time=1970-01-02 07:00:52;disabled=false;dynamic=false;list=srv
.id=*3;address=192.168.88.1;comment=example;creation-time=1970-01-02 07:00:52;disabled=false;dynamic=false;list=routeros
cat ./import_fw_addr_list.txt | perl -pe 's/^\.id=(.*)\;address=((?>\d+\.\d+\.\d+.\d+)|(?>\d+\.\d+\.\d+.\d+\/\d+))(\;comment=(.*)|.?)\;.*\;.*\;.*\;.*list=(.*)$/{ address="\2", comment="\4", list="\5" },/g' > import_fw_addr_list.tf.txt
#!/bin/bash
findexes=$(cat ./import_fw_addr_list.txt | sed -r 's/.id=(.*).*/\U\1/g' | awk -F";" '{ print $1}')
i=0
for index in $findexes
do
idx=$(printf "%00004d" $i)
#remove idx
  bash -cv "tofu state rm 'module.dev-gw0.routeros_ip_firewall_addr_list.address_list[\"$idx\"]'"
  bash -cv "tofu import 'module.dev-gw0.routeros_ip_firewall_addr_list.address_list[\"$idx\"]' \"$index\""
  let i=${i}+1
done
variable "address_list" {
  type = list(object({
#    id = string
    address = string
    comment = optional(string)
    #    creation_time  = optional(string)
    disabled = optional(bool, false)
    dynamic  = optional(bool, false)
    list     = string
  }))

  default = [
    { address="192.168.88.11", comment="example 2", list="srv" },
    { address="192.168.88.12", comment="example 2", list="srv" },
    { address="192.168.88.1", comment="example", list="routeros" },
]

locals {
  # https://discuss.hashicorp.com/t/does-map-sort-keys/12056/2
  # Map keys are always iterated in lexicographical order!
  address_list_map = { for idx, rule in var.address_list : format("%00004d", idx) => rule }
}

resource "routeros_ip_firewall_addr_list" "address_list" {
  for_each = local.address_list_map
#  id       = each.value.id
  address  = each.value.address
  comment  = each.value.comment
  #  creation_time  = each.value.creation_time
  disabled = each.value.disabled
  list     = each.value.list
}
cmdorexe commented 3 weeks ago
╷
│ Error: from RouterOS device: no such command prefix
│ 
│   with module.dev-gw0.routeros_move_items.fw_addr_list,
│   on dev/network/gw0/firewall_addr_list.tf line 130, in resource "routeros_move_items" "fw_addr_list":
│  130: resource "routeros_move_items" "fw_addr_list" {

Error: from RouterOS device: no such command prefix

vaerh commented 3 weeks ago

Thanks, I'll look into it a bit more and try to include it in the documentation.

cmdorexe commented 3 weeks ago

I found some trouble 🎉

locals {
  # https://discuss.hashicorp.com/t/does-map-sort-keys/12056/2
  # Map keys are always iterated in lexicographical order!
  address_list_map = { for idx, rule in var.address_list : format("%00004d", idx) => rule }
}

and fix it in bash.

#!/bin/bash
findexes=$(cat ./import_fw_addr_list.txt | sed -r 's/.id=(.*).*/\U\1/g' | awk -F";" '{ print $1}')
i=0
for index in $findexes
do
idx=$(printf "%00004d" $i)
#remove idx
  bash -cv "tofu state rm 'module.dev-gw0.routeros_ip_firewall_addr_list.address_list[\"$idx\"]'"
  bash -cv "tofu import 'module.dev-gw0.routeros_ip_firewall_addr_list.address_list[\"$idx\"]' \"$index\""
  let i=${i}+1
done
vaerh commented 3 weeks ago

Can you also add the module code without specific snippets so that the example is complete?

cmdorexe commented 3 weeks ago

Example is completed in the ticket header, but I have an error problem. Error: from RouterOS device: no such command prefix

vaerh commented 3 weeks ago

Then you have to debug the configuration: run TF_LOG=debug ROS_LOG_COLOR=1 terraform... and see what commands go to MT in the green lines.

cmdorexe commented 3 weeks ago

it's bug ip/firewall/addr/list/move

module.dev-gw0.routeros_move_items.fw_addr_list: Creating...
2024-06-07T17:56:22.631+0300 [INFO]  Starting apply for module.dev-gw0.routeros_move_items.fw_addr_list
2024-06-07T17:56:22.632+0300 [DEBUG] module.dev-gw0.routeros_move_items.fw_addr_list: applying the planned Create change
2024-06-07T17:56:22.633+0300 [DEBUG] provider.terraform-provider-routeros_v1.54.1: request body:  ip/firewall/addr/list/move =destination=*CBE =numbers=*8,*1D,
*1E,*20,*21,*22,*23,*25,*27,*28,*29,*2A,*2B,*2C,*2D,*2E,*2F,*30,*31,*32,*33,*34,*35,*38,*3A,*3B,*3C,*3D,*3E,*9E,*9F,*A0,*A1,*A2,*A3,*A4,*A5,*A6,*A7,*A8,*A9,*
AA,*AB,*AC,*AD,*15B,*15C,*15D,*15E,*160,*161,*162,*163,*164,*165,*166,*16A,*16B,*16D,*16E,*170,*171,*174,*175,*176,*1CA,*1CB,*1CC,*1CD,*1CE,*1CF,*1D0,*1D2,*1
D3,*1D4,*1D5,*1D6,*1D7,*1D8,*1D9,*1DA,*1DB,*1DC,*1DF,*1E0,*236,*23C,*23D,*2E6,*516,*517,*518,*560,*561,*562,*8B5,*B59,*C4C: tf_rpc=Configure @caller=github.c
om/terraform-routeros/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=aca9dcde-6244-b0
58-e325-9d4d2e4bc2e2 timestamp="2024-06-07T17:56:22.633+0300"
2024-06-07T17:56:22.648+0300 [DEBUG] provider.terraform-provider-routeros_v1.54.1: An error was encountered while sending a PUT request to the API: from Rout
erOS device: no such command prefix: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=5408fede-1b2c-652c-71ea-21537d18bb26 tf_resource
_type=routeros_move_items tf_rpc=ApplyResourceChange @caller=github.com/terraform-routeros/terraform-provider-routeros/routeros/log.go:27 timestamp="2024-06-
07T17:56:22.648+0300"
2024-06-07T17:56:22.648+0300 [ERROR] provider.terraform-provider-routeros_v1.54.1: Response contains error diagnostic: diagnostic_detail="" diagnostic_summar
y="from RouterOS device: no such command prefix" tf_provider_addr=terraform-routeros/routeros tf_resource_type=routeros_move_items @module=sdk.proto @caller=
github.com/hashicorp/terraform-plugin-go@v0.23.0/tfprotov5/internal/diag/diagnostics.go:58 tf_req_id=5408fede-1b2c-652c-71ea-21537d18bb26 tf_rpc=ApplyResourc
eChange diagnostic_severity=ERROR tf_proto_version=5.6 timestamp="2024-06-07T17:56:22.648+0300"
2024-06-07T17:56:22.649+0300 [DEBUG] State storage *statemgr.Filesystem declined to persist a state snapshot
2024-06-07T17:56:22.649+0300 [ERROR] vertex "module.dev-gw0.routeros_move_items.fw_addr_list" error: from RouterOS device: no such command prefix
╷
│ Error: from RouterOS device: no such command prefix
│ 
│   with module.dev-gw0.routeros_move_items.fw_addr_list,
│   on dev/network/gw0/firewall_addr_list.tf line 130, in resource "routeros_move_items" "fw_addr_list":
│  130: resource "routeros_move_items" "fw_addr_list" {
│  
╵
2024-06-07T17:56:22.659+0300 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: E
OF"
2024-06-07T17:56:22.659+0300 [DEBUG] provider: plugin process exited: path=.terraform/providers/some.local.fqdn/terraform-routeros/routeros/1.54.1/linu
x_amd64/terraform-provider-routeros_v1.54.1 pid=110832
2024-06-07T17:56:22.659+0300 [DEBUG] provider: plugin exited
cmdorexe commented 3 weeks ago

I think in the future I can give options for using ci import.yml with gitea.

vaerh commented 3 weeks ago

Hmmm, what version of ROS are you using? And can you run this command in CLI?

cmdorexe commented 3 weeks ago

ros

vaerh commented 3 weeks ago

Address Lists do not provide for moving entries in either the winbox or the CLI. The REST API used by this provider is a wrapper over the CLI, so we cannot use commands that are not supported by the router itself.

vaerh commented 3 weeks ago

I looked at your script again and I have a question: why do you want to organize the address lists? In general, you can create them unsorted, and it is done manually in Winbox.

cmdorexe commented 3 weeks ago

it's just example. Wonna import full configuration 2 terraform and structurized typicly configuration for many backends. And I found best way to do it: RouterOS Rest API gives output in json, and it easy to implement import to terraform.

p.s. ty @vaerh. I fixed example HEAD of tread.