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

feat: Add user manager support #310

Merged
merged 13 commits into from
Dec 2, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import routeros_user_manager_advanced.settings .
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource "routeros_user_manager_advanced" "settings" {
web_private_password = "password"
web_private_username = "admin"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#The ID can be found via API or the terminal
#The command for the terminal is -> :put [/user-manager/attribute get [print show-ids]]
terraform routeros_user_manager_attribute.mikrotik_wireless_comment '*1'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "routeros_user_manager_attribute" "mikrotik_wireless_comment" {
name = "Mikrotik-Wireless-Comment"
packet_types = ["access-accept"]
type_id = 21
value_type = "string"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import routeros_user_manager_database.settings .
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "routeros_user_manager_database" "settings" {
db_path = "/flash/user-manager5"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#The ID can be found via API or the terminal
#The command for the terminal is -> :put [/user-manager/limitation get [print show-ids]]
terraform import routeros_user_manager_limitation.test '*1'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "routeros_user_manager_limitation" "test" {
name = "test"
download_limit = 1024
upload_limit = 1024
uptime_limit = "10d"
}
3 changes: 3 additions & 0 deletions examples/resources/routeros_user_manager_profile/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#The ID can be found via API or the terminal
#The command for the terminal is -> :put [/user-manager/profile get [print show-ids]]
terraform import routeros_user_manager_profile.test '*1'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "routeros_user_manager_profile" "test" {
name = "test"
name_for_users = "Test"
price = 0.02
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#The ID can be found via API or the terminal
#The command for the terminal is -> :put [/user-manager/profile-limitation get [print show-ids]]
terraform import routeros_user_manager_profile_limitation.weekend_night '*1'
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
resource "routeros_user_manager_limitation" "test" {
name = "test"
download_limit = 1024
upload_limit = 1024
uptime_limit = "10d"
}

resource "routeros_user_manager_profile" "test" {
name = "test"
name_for_users = "Test"
price = 0.02
}

resource "routeros_user_manager_profile_limitation" "weekend_night" {
limitation = routeros_user_manager_limitation.test.name
profile = routeros_user_manager_profile.test.name
from_time = "0s"
till_time = "6h"
weekdays = [
"sunday",
"saturday",
]
}
3 changes: 3 additions & 0 deletions examples/resources/routeros_user_manager_router/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#The ID can be found via API or the terminal
#The command for the terminal is -> :put [/user-manager/router get [print show-ids]]
terraform import routeros_user_manager_router.test '*1'
5 changes: 5 additions & 0 deletions examples/resources/routeros_user_manager_router/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "routeros_user_manager_router" "test" {
address = "127.0.0.1"
name = "test"
shared_secret = "password"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import routeros_user_manager_settings.settings .
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "routeros_user_manager_settings" "settings" {
enabled = true
}
3 changes: 3 additions & 0 deletions examples/resources/routeros_user_manager_user/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#The ID can be found via API or the terminal
#The command for the terminal is -> :put [/user-manager/user get [print show-ids]]
terraform import routeros_user_manager_user.test '*1'
25 changes: 25 additions & 0 deletions examples/resources/routeros_user_manager_user/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
resource "routeros_user_manager_attribute" "mikrotik_wireless_comment" {
name = "Mikrotik-Wireless-Comment"
type_id = 21
value_type = "string"
}

resource "routeros_user_manager_attribute" "mikrotik_wireless_vlanid" {
name = "Mikrotik-Wireless-VLANID"
type_id = 26
value_type = "uint32"
}

resource "routeros_user_manager_user_group" "test" {
name = "test"
}

resource "routeros_user_manager_user" "test" {
attributes = [
"${routeros_user_manager_attribute.mikrotik_wireless_comment.name}:Test Group",
"${routeros_user_manager_attribute.mikrotik_wireless_vlanid.name}:100",
]
group = routeros_user_manager_user_group.test.name
name = "test"
password = "password"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#The ID can be found via API or the terminal
#The command for the terminal is -> :put [/user-manager/user/group get [print show-ids]]
terraform import routeros_user_manager_user_group.test '*1'
27 changes: 27 additions & 0 deletions examples/resources/routeros_user_manager_user_group/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
resource "routeros_user_manager_attribute" "mikrotik_wireless_comment" {
name = "Mikrotik-Wireless-Comment"
type_id = 21
value_type = "string"
}

resource "routeros_user_manager_attribute" "mikrotik_wireless_vlanid" {
name = "Mikrotik-Wireless-VLANID"
type_id = 26
value_type = "uint32"
}

resource "routeros_user_manager_user_group" "test" {
name = "test"
attributes = [
"${routeros_user_manager_attribute.mikrotik_wireless_comment.name}:Test Group",
"${routeros_user_manager_attribute.mikrotik_wireless_vlanid.name}:100",
]
inner_auths = [
"ttls-chap",
"ttls-pap",
]
outer_auths = [
"chap",
"pap",
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#The ID can be found via API or the terminal
#The command for the terminal is -> :put [/user-manager/user-profile get [print show-ids]]
terraform import routeros_user_manager_user_profile.test '*1'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resource "routeros_user_manager_profile" "test" {
name = "test"
}

resource "routeros_user_manager_user" "test" {
name = "test"
}

resource "routeros_user_manager_user_profile" "test" {
profile = routeros_user_manager_profile.test.name
user = routeros_user_manager_user.test.name
}
42 changes: 37 additions & 5 deletions routeros/mikrotik_serialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func isEmpty(propName string, schemaProp *schema.Schema, d *schema.ResourceData,
return v.(string) == "" && schemaProp.Default.(string) == ""
}
return v.(string) == "" && confValue.IsNull()
case schema.TypeInt:
case schema.TypeFloat, schema.TypeInt:
return confValue.IsNull() && schemaProp.Default == nil
case schema.TypeBool:
// If true, it is always not empty:
Expand Down Expand Up @@ -195,6 +195,8 @@ func TerraformResourceDataToMikrotik(s map[string]*schema.Schema, d *schema.Reso
switch terraformMetadata.Type {
case schema.TypeString:
item[mikrotikKebabName] = value.(string)
case schema.TypeFloat:
item[mikrotikKebabName] = strconv.FormatFloat(value.(float64), 'f', -1, 64)
case schema.TypeInt:
item[mikrotikKebabName] = strconv.Itoa(value.(int))
case schema.TypeBool:
Expand Down Expand Up @@ -360,10 +362,18 @@ func MikrotikResourceDataToTerraform(item MikrotikItem, s map[string]*schema.Sch
case schema.TypeString:
err = d.Set(terraformSnakeName, mikrotikValue)

case schema.TypeFloat:
f, e := strconv.ParseFloat(mikrotikValue, 64)
if e != nil {
diags = diag.Errorf("%v for '%v' field", e, terraformSnakeName)
break
}
err = d.Set(terraformSnakeName, f)

case schema.TypeInt:
i, e := strconv.Atoi(mikrotikValue)
if e != nil {
diags = diag.Errorf("%v for '%v' field", err, terraformSnakeName)
diags = diag.Errorf("%v for '%v' field", e, terraformSnakeName)
break
}
err = d.Set(terraformSnakeName, i)
Expand Down Expand Up @@ -391,15 +401,24 @@ func MikrotikResourceDataToTerraform(item MikrotikItem, s map[string]*schema.Sch
// Flat Lists & Sets:
if _, ok := s[terraformSnakeName].Elem.(*schema.Schema); mikrotikValue != "" && ok {
for _, v := range strings.Split(mikrotikValue, ",") {
if s[terraformSnakeName].Elem.(*schema.Schema).Type == schema.TypeInt {
i, err := strconv.Atoi(v)
switch s[terraformSnakeName].Elem.(*schema.Schema).Type {
case schema.TypeFloat:
f, err := strconv.ParseFloat(v, 64)
if err != nil {
diags = diag.Errorf("%v for '%v' field", err, terraformSnakeName)
continue
}
l = append(l, f)

case schema.TypeInt:
i, err := strconv.Atoi(v)
if err != nil {
diags = diag.Errorf("%v for '%v' field", err, terraformSnakeName)
continue
}
l = append(l, i)
} else {

default:
l = append(l, v)
}
}
Expand Down Expand Up @@ -429,6 +448,11 @@ func MikrotikResourceDataToTerraform(item MikrotikItem, s map[string]*schema.Sch
switch s[terraformSnakeName].Elem.(*schema.Resource).Schema[subFieldSnakeName].Type {
case schema.TypeString:
v = mikrotikValue
case schema.TypeFloat:
v, err = strconv.ParseFloat(mikrotikValue, 64)
if err != nil {
diags = diag.Errorf("%v for '%v.%v' field", err, terraformSnakeName, subFieldSnakeName)
}
case schema.TypeInt:
v, err = strconv.Atoi(mikrotikValue)
if err != nil {
Expand Down Expand Up @@ -572,6 +596,14 @@ func MikrotikResourceDataToTerraformDatasource(items *[]MikrotikItem, resourceDa
case schema.TypeString:
propValue = mikrotikValue

case schema.TypeFloat:
f, err := strconv.ParseFloat(mikrotikValue, 64)
if err != nil {
diags = append(diags, diag.Errorf("%v for '%v' field", err, terraformSnakeName)...)
continue
}
propValue = f

case schema.TypeInt:
i, err := strconv.Atoi(mikrotikValue)
if err != nil {
Expand Down
21 changes: 14 additions & 7 deletions routeros/mikrotik_serialize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ var (
"string": {
Type: schema.TypeString,
},
"float": {
Type: schema.TypeFloat,
},
"int": {
Type: schema.TypeInt,
},
Expand All @@ -40,6 +43,9 @@ var (
"string": {
Type: schema.TypeString,
},
"float": {
Type: schema.TypeFloat,
},
"int": {
Type: schema.TypeInt,
},
Expand All @@ -55,10 +61,10 @@ var (

func Test_mikrotikResourceDataToTerraform(t *testing.T) {

testItem := MikrotikItem{".id": "*39", "string": "string12345", "int": "10", "bool": "true"}
testItem := MikrotikItem{".id": "*39", "string": "string12345", "float": "0.01", "int": "10", "bool": "true"}

testResourceData := testResource.TestResourceData()
expectedRes := map[string]interface{}{"string": "string12345", "int": 10, "bool": true}
expectedRes := map[string]interface{}{"string": "string12345", "float": 0.01, "int": 10, "bool": true}

err := MikrotikResourceDataToTerraform(testItem, testResource.Schema, testResourceData)
if err != nil {
Expand All @@ -77,11 +83,12 @@ func Test_mikrotikResourceDataToTerraform(t *testing.T) {

func Test_terraformResourceDataToMikrotik(t *testing.T) {

expected := MikrotikItem{"string": "string12345", "int": "10", "bool": "yes"}
expected := MikrotikItem{"string": "string12345", "float": "0.01", "int": "10", "bool": "yes"}

testResourceData := testResource.TestResourceData()
testResourceData.SetId("*39")
testResourceData.Set("string", "string12345")
testResourceData.Set("float", 0.01)
testResourceData.Set("int", 10)
testResourceData.Set("bool", true)

Expand All @@ -94,14 +101,14 @@ func Test_terraformResourceDataToMikrotik(t *testing.T) {

func Test_mikrotikResourceDataToTerraformDatasource(t *testing.T) {
testItems := []MikrotikItem{
{"string": "string12345", "int": "10", "bool": "yes"},
{"string": "12345string", "int": "20", "bool": "no"},
{"string": "string12345", "float": "0.01", "int": "10", "bool": "yes"},
{"string": "12345string", "float": "0.02", "int": "20", "bool": "no"},
}

testResourceData := testDatasource.TestResourceData()
expectedRes := []map[string]interface{}{
{MetaResourcePath: "", MetaId: 0, "string": "string12345", "int": 10, "bool": true},
{MetaResourcePath: "", MetaId: 0, "string": "12345string", "int": 20, "bool": false},
{MetaResourcePath: "", MetaId: 0, "string": "string12345", "float": 0.01, "int": 10, "bool": true},
{MetaResourcePath: "", MetaId: 0, "string": "12345string", "float": 0.02, "int": 20, "bool": false},
}

err := MikrotikResourceDataToTerraformDatasource(&testItems, "test_name", testDatasource.Schema, testResourceData)
Expand Down
13 changes: 13 additions & 0 deletions routeros/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,19 @@ func Provider() *schema.Provider {

// Helpers
"routeros_wireguard_keys": ResourceWireguardKeys(),

// User Manager
"routeros_user_manager_advanced": ResourceUserManagerAdvanced(),
"routeros_user_manager_attribute": ResourceUserManagerAttribute(),
"routeros_user_manager_database": ResourceUserManagerDatabase(),
"routeros_user_manager_limitation": ResourceUserManagerLimitation(),
"routeros_user_manager_profile": ResourceUserManagerProfile(),
"routeros_user_manager_profile_limitation": ResourceUserManagerProfileLimitation(),
"routeros_user_manager_router": ResourceUserManagerRouter(),
"routeros_user_manager_settings": ResourceUserManagerSettings(),
"routeros_user_manager_user": ResourceUserManagerUser(),
"routeros_user_manager_user_group": ResourceUserManagerUserGroup(),
"routeros_user_manager_user_profile": ResourceUserManagerUserProfile(),
},
DataSourcesMap: map[string]*schema.Resource{
"routeros_firewall": DatasourceFirewall(),
Expand Down
4 changes: 4 additions & 0 deletions routeros/provider_schema_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,10 @@ var (
// Prevents the need of hardcode values for default values, as those are harder to track over time/versions of
// routeros
AlwaysPresentNotUserProvided = func(k, old, new string, d *schema.ResourceData) bool {
// For lists and sets, the key will look like `something.12345` or `something.#`.
// But in the raw config it will be just `something`.
k = strings.Split(k, ".")[0]

if old != "" && d.GetRawConfig().GetAttr(k).IsNull() {
return true
}
Expand Down
Loading
Loading