From 78191e2038607af5081d06dfaabc208010f6d667 Mon Sep 17 00:00:00 2001 From: vaerh <64400271+vaerh@users.noreply.github.com> Date: Fri, 5 May 2023 21:26:14 +0300 Subject: [PATCH] feat: Support creating users #200 (#201) --- .../resources/routeros_system_user/import.sh | 3 + .../routeros_system_user/resource.tf | 7 ++ routeros/provider.go | 1 + routeros/resource_system_user.go | 72 +++++++++++++++++++ routeros/resource_system_user_test.go | 65 +++++++++++++++++ 5 files changed, 148 insertions(+) create mode 100644 examples/resources/routeros_system_user/import.sh create mode 100644 examples/resources/routeros_system_user/resource.tf create mode 100644 routeros/resource_system_user.go create mode 100644 routeros/resource_system_user_test.go diff --git a/examples/resources/routeros_system_user/import.sh b/examples/resources/routeros_system_user/import.sh new file mode 100644 index 00000000..59900b18 --- /dev/null +++ b/examples/resources/routeros_system_user/import.sh @@ -0,0 +1,3 @@ +#The ID can be found via API or the terminal +#The command for the terminal is -> :put [/user get [print show-ids]] +terraform import routeros_system_user.test *1 \ No newline at end of file diff --git a/examples/resources/routeros_system_user/resource.tf b/examples/resources/routeros_system_user/resource.tf new file mode 100644 index 00000000..4bff646b --- /dev/null +++ b/examples/resources/routeros_system_user/resource.tf @@ -0,0 +1,7 @@ +resource "routeros_system_user" "test" { + name = "test-user-1" + address = "0.0.0.0/0" + group = "read" + password = "secret" + comment = "Test User" +} diff --git a/routeros/provider.go b/routeros/provider.go index e5b6d282..92eb456d 100644 --- a/routeros/provider.go +++ b/routeros/provider.go @@ -121,6 +121,7 @@ func Provider() *schema.Provider { "routeros_system_identity": ResourceSystemIdentity(), "routeros_system_scheduler": ResourceSystemScheduler(), "routeros_system_certificate": ResourceSystemCertificate(), + "routeros_system_user": ResourceUser(), // Aliases for system objects to retain compatibility between original and fork "routeros_identity": ResourceSystemIdentity(), diff --git a/routeros/resource_system_user.go b/routeros/resource_system_user.go new file mode 100644 index 00000000..a722b4e2 --- /dev/null +++ b/routeros/resource_system_user.go @@ -0,0 +1,72 @@ +package routeros + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +/* + { + ".id": "*1", + "address": "0.0.0.0/0", + "comment": "system default user", + "disabled": "false", + "expired": "true", + "group": "full", + "last-logged-in": "may/02/2023 05:21:45", + "name": "admin" + } +*/ + +// https://help.mikrotik.com/docs/display/ROS/User#User-RouterUsers +func ResourceUser() *schema.Resource { + resSchema := map[string]*schema.Schema{ + MetaResourcePath: PropResourcePath("/user"), + MetaId: PropId(Id), + + "address": { + Type: schema.TypeString, + Optional: true, + Description: "Host or network address from which the user is allowed to log in.", + }, + KeyComment: PropCommentRw, + KeyDisabled: PropDisabledRw, + "expired": { + Type: schema.TypeBool, + Computed: true, + Description: "Password expired.", + }, + "group": { + Type: schema.TypeString, + Required: true, + Description: "Name of the group the user belongs to.", + }, + KeyName: PropName("User name. Although it must start with an alphanumeric character, it may contain '*', " + + "'_', '.' and '@' symbols."), + "password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + Description: "User password. If not specified, it is left blank (hit [Enter] when logging in). It " + + "conforms to standard Unix characteristics of passwords and may contain letters, digits, " + + "'*' and '_' symbols.", + }, + "last_logged_in": { + Type: schema.TypeString, + Computed: true, + Description: "Read-only field. Last time and date when a user logged in.", + }, + } + + return &schema.Resource{ + CreateContext: DefaultCreate(resSchema), + ReadContext: DefaultRead(resSchema), + UpdateContext: DefaultUpdate(resSchema), + DeleteContext: DefaultDelete(resSchema), + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: resSchema, + } +} diff --git a/routeros/resource_system_user_test.go b/routeros/resource_system_user_test.go new file mode 100644 index 00000000..a9e5c75a --- /dev/null +++ b/routeros/resource_system_user_test.go @@ -0,0 +1,65 @@ +package routeros + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +const testUserAddress = "routeros_system_user.test" + +func TestAccUserTest_basic(t *testing.T) { + t.Parallel() + for _, name := range testNames { + t.Run(name, func(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testSetTransportEnv(t, name) + }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testCheckResourceDestroy("/user", "routeros_system_user"), + Steps: []resource.TestStep{ + { + Config: testAccUserConfig(), + Check: resource.ComposeTestCheckFunc( + testAccCheckUserExists(testUserAddress), + resource.TestCheckResourceAttr(testUserAddress, "name", "test-user-1"), + ), + }, + }, + }) + + }) + } +} + +func testAccCheckUserExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("not found: %s", name) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("no id is set") + } + + return nil + } +} + +func testAccUserConfig() string { + return providerConfig + ` + +resource "routeros_system_user" "test" { + name = "test-user-1" + address = "0.0.0.0/0" + group = "read" + password = "secret" + comment = "Test User" +} +` +}