mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-29 18:21:10 +00:00
feat(node): add support for node config API (#1482)
* feat(node): implement CRUD API for proxmox node config Signed-off-by: Björn Brauer <zaubernerd@zaubernerd.de> * fix: add unit tests, fix UnmarshalJSON Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> --------- Signed-off-by: Björn Brauer <zaubernerd@zaubernerd.de> Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
dd50873e2a
commit
3e025fd6c8
41
proxmox/nodes/config.go
Normal file
41
proxmox/nodes/config.go
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||
)
|
||||
|
||||
// GetConfig retrieves the config for a node.
|
||||
func (c *Client) GetConfig(ctx context.Context) (*[]ConfigGetResponseData, error) {
|
||||
resBody := &ConfigGetResponseBody{}
|
||||
|
||||
err := c.DoRequest(ctx, http.MethodGet, c.ExpandPath("config"), nil, resBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving node config: %w", err)
|
||||
}
|
||||
|
||||
if resBody.Data == nil {
|
||||
return nil, api.ErrNoDataObjectInResponse
|
||||
}
|
||||
|
||||
return resBody.Data, nil
|
||||
}
|
||||
|
||||
// UpdateConfig updates the config for a node.
|
||||
func (c *Client) UpdateConfig(ctx context.Context, d *ConfigUpdateRequestBody) error {
|
||||
err := c.DoRequest(ctx, http.MethodPost, c.ExpandPath("config"), d, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error updating node config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
240
proxmox/nodes/config_types.go
Normal file
240
proxmox/nodes/config_types.go
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ConfigGetResponseBody contains the body from a config get response.
|
||||
type ConfigGetResponseBody struct {
|
||||
Data *[]ConfigGetResponseData `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// ConfigGetResponseData contains the data from a config get response.
|
||||
type ConfigGetResponseData struct {
|
||||
// Node specific ACME settings.
|
||||
ACME *ACMEConfig `json:"acme,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain0 *ACMEDomainConfig `json:"acmedomain0,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain1 *ACMEDomainConfig `json:"acmedomain1,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain2 *ACMEDomainConfig `json:"acmedomain2,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain3 *ACMEDomainConfig `json:"acmedomain3,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain4 *ACMEDomainConfig `json:"acmedomain4,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain5 *ACMEDomainConfig `json:"acmedomain5,omitempty"`
|
||||
// Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.
|
||||
Digest *string `json:"digest,omitempty"`
|
||||
// Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.
|
||||
StartAllOnbootDelay *int `json:"startall-onboot-delay,omitempty"`
|
||||
// Node specific wake on LAN settings.
|
||||
WakeOnLan *WakeOnLandConfig `json:"wakeonlan,omitempty"`
|
||||
}
|
||||
|
||||
// ConfigUpdateRequestBody contains the body for a config update request.
|
||||
type ConfigUpdateRequestBody struct {
|
||||
// Node specific ACME settings.
|
||||
ACME *ACMEConfig `json:"acme,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain0 *ACMEDomainConfig `json:"acmedomain0,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain1 *ACMEDomainConfig `json:"acmedomain1,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain2 *ACMEDomainConfig `json:"acmedomain2,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain3 *ACMEDomainConfig `json:"acmedomain3,omitempty"`
|
||||
// ACME domain and validation plugin
|
||||
ACMEDomain4 *ACMEDomainConfig `json:"acmedomain4,omitempty"`
|
||||
Delete *string `json:"delete,omitempty"`
|
||||
// Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.
|
||||
Digest *string `json:"digest,omitempty"`
|
||||
// Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.
|
||||
StartAllOnbootDelay *int `json:"startall-onboot-delay,omitempty"`
|
||||
// Node specific wake on LAN settings.
|
||||
WakeOnLan *WakeOnLandConfig `json:"wakeonlan,omitempty"`
|
||||
}
|
||||
|
||||
// ACMEConfig contains the ACME account / domains configuration that use the "standalone" plugin (http challenge).
|
||||
type ACMEConfig struct {
|
||||
// account name
|
||||
Account *string
|
||||
// domains
|
||||
Domains []string
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals a ACMEConfig struct from JSON.
|
||||
func (a *ACMEConfig) UnmarshalJSON(b []byte) error {
|
||||
config := ACMEConfig{}
|
||||
|
||||
s := ""
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return fmt.Errorf("error unmarshaling json: %w", err)
|
||||
}
|
||||
|
||||
parts := strings.Split(s, ",")
|
||||
for _, part := range parts {
|
||||
kv := strings.Split(part, "=")
|
||||
if len(kv) != 2 {
|
||||
return fmt.Errorf("invalid key-value pair: %s", part)
|
||||
}
|
||||
|
||||
switch kv[0] {
|
||||
case "account":
|
||||
config.Account = &kv[1]
|
||||
case "domains":
|
||||
config.Domains = strings.Split(kv[1], ";")
|
||||
default:
|
||||
return fmt.Errorf("unknown key: %s", kv[0])
|
||||
}
|
||||
}
|
||||
|
||||
*a = config
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeValues encodes a ACMEConfig struct into a string.
|
||||
func (a *ACMEConfig) EncodeValues(key string, v *url.Values) error {
|
||||
value := ""
|
||||
if a.Account != nil {
|
||||
value = fmt.Sprintf("account=%s", *a.Account)
|
||||
}
|
||||
|
||||
value = fmt.Sprintf("%s,%s", value, strings.Join(a.Domains, ";"))
|
||||
v.Add(key, value)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ACMEDomainConfig contains the ACME domain configuration for domains using the dns challenge plugin.
|
||||
type ACMEDomainConfig struct {
|
||||
// domain name
|
||||
Domain string
|
||||
// alias for the domain
|
||||
Alias *string
|
||||
// name of the plugin configuration
|
||||
Plugin *string
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals a ACMEDomainConfig struct from JSON.
|
||||
func (a *ACMEDomainConfig) UnmarshalJSON(b []byte) error {
|
||||
config := ACMEDomainConfig{}
|
||||
|
||||
s := ""
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return fmt.Errorf("error unmarshaling json: %w", err)
|
||||
}
|
||||
|
||||
parts := strings.Split(s, ",")
|
||||
for _, part := range parts {
|
||||
kv := strings.Split(part, "=")
|
||||
if len(kv) == 1 {
|
||||
config.Domain = kv[0]
|
||||
} else {
|
||||
switch kv[0] {
|
||||
case "domain":
|
||||
config.Domain = kv[1]
|
||||
case "alias":
|
||||
config.Alias = &kv[1]
|
||||
case "plugin":
|
||||
config.Plugin = &kv[1]
|
||||
default:
|
||||
return fmt.Errorf("unknown key: %s", kv[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*a = config
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeValues encodes a ACMEDomainConfig struct into a string.
|
||||
func (a *ACMEDomainConfig) EncodeValues(key string, v *url.Values) error {
|
||||
value := a.Domain
|
||||
if a.Alias != nil {
|
||||
value = fmt.Sprintf("%s,alias=%s", value, *a.Alias)
|
||||
}
|
||||
|
||||
if a.Plugin != nil {
|
||||
value = fmt.Sprintf("%s,plugin=%s", value, *a.Plugin)
|
||||
}
|
||||
|
||||
v.Add(key, value)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WakeOnLandConfig contains the wake on LAN configuration.
|
||||
type WakeOnLandConfig struct {
|
||||
// MAC address
|
||||
MACAddress string
|
||||
// bind interface
|
||||
BindInterface *string
|
||||
// IPv4 broadcast address
|
||||
BroadcastAddress *string
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals a WakeOnLandConfig struct from JSON.
|
||||
func (a *WakeOnLandConfig) UnmarshalJSON(b []byte) error {
|
||||
config := WakeOnLandConfig{}
|
||||
|
||||
s := ""
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return fmt.Errorf("error unmarshaling json: %w", err)
|
||||
}
|
||||
|
||||
parts := strings.Split(s, ",")
|
||||
for _, part := range parts {
|
||||
kv := strings.Split(part, "=")
|
||||
if len(kv) == 1 {
|
||||
config.MACAddress = kv[0]
|
||||
} else {
|
||||
switch kv[0] {
|
||||
case "mac":
|
||||
config.MACAddress = kv[1]
|
||||
case "bind-interface":
|
||||
config.BindInterface = &kv[1]
|
||||
case "broadcast-address":
|
||||
config.BroadcastAddress = &kv[1]
|
||||
default:
|
||||
return fmt.Errorf("unknown key: %s", kv[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*a = config
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeValues encodes a WakeOnLandConfig struct into a string.
|
||||
func (a *WakeOnLandConfig) EncodeValues(key string, v *url.Values) error {
|
||||
value := a.MACAddress
|
||||
if a.BindInterface != nil {
|
||||
value = fmt.Sprintf("%s,bind-interface=%s", value, *a.BindInterface)
|
||||
}
|
||||
|
||||
if a.BroadcastAddress != nil {
|
||||
value = fmt.Sprintf("%s,broadcast-address=%s", value, *a.BroadcastAddress)
|
||||
}
|
||||
|
||||
v.Add(key, value)
|
||||
|
||||
return nil
|
||||
}
|
409
proxmox/nodes/config_types_test.go
Normal file
409
proxmox/nodes/config_types_test.go
Normal file
@ -0,0 +1,409 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/helpers/ptr"
|
||||
)
|
||||
|
||||
func TestACMEConfig_UnmarshalJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config ACMEConfig
|
||||
str string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "account only",
|
||||
config: ACMEConfig{
|
||||
Account: ptr.Ptr("foo"),
|
||||
Domains: nil,
|
||||
},
|
||||
str: `"account=foo"`,
|
||||
},
|
||||
{
|
||||
name: "account and domains",
|
||||
config: ACMEConfig{
|
||||
Account: ptr.Ptr("foo"),
|
||||
Domains: []string{"bar", "baz"},
|
||||
},
|
||||
str: `"account=foo,domains=bar;baz"`,
|
||||
},
|
||||
{
|
||||
name: "domains only",
|
||||
config: ACMEConfig{
|
||||
Account: nil,
|
||||
Domains: []string{"bar", "baz"},
|
||||
},
|
||||
str: `"domains=bar;baz"`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if err := tt.config.UnmarshalJSON([]byte(tt.str)); (err != nil) != tt.wantErr {
|
||||
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestACMEConfig_EncodeValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
key string
|
||||
v *url.Values
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config ACMEConfig
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "account only",
|
||||
config: ACMEConfig{
|
||||
Account: ptr.Ptr("foo"),
|
||||
Domains: nil,
|
||||
},
|
||||
args: args{
|
||||
"acme",
|
||||
&url.Values{
|
||||
"account": {"foo"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "account and domains",
|
||||
config: ACMEConfig{
|
||||
Account: ptr.Ptr("foo"),
|
||||
Domains: []string{"bar", "baz"},
|
||||
},
|
||||
args: args{
|
||||
"acme",
|
||||
&url.Values{
|
||||
"account": {"foo"},
|
||||
"domains": {"bar;baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "domains only",
|
||||
config: ACMEConfig{
|
||||
Account: nil,
|
||||
Domains: []string{"bar", "baz"},
|
||||
},
|
||||
args: args{
|
||||
"acme",
|
||||
&url.Values{
|
||||
"domains": {"bar;baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if err := tt.config.EncodeValues(tt.args.key, tt.args.v); (err != nil) != tt.wantErr {
|
||||
t.Errorf("EncodeValues() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestACMEDomainConfig_UnmarshalJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config ACMEDomainConfig
|
||||
str string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "domain only",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
},
|
||||
str: `"foo"`,
|
||||
},
|
||||
{
|
||||
name: "domain only with key",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
},
|
||||
str: `"domain=foo"`,
|
||||
},
|
||||
{
|
||||
name: "domain and alias",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
Alias: ptr.Ptr("bar"),
|
||||
},
|
||||
str: `"domain=foo,alias=bar"`,
|
||||
},
|
||||
{
|
||||
name: "domain and plugin",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
Plugin: ptr.Ptr("bar"),
|
||||
},
|
||||
str: `"domain=foo,plugin=bar"`,
|
||||
},
|
||||
{
|
||||
name: "domain, alias, and plugin",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
Alias: ptr.Ptr("bar"),
|
||||
Plugin: ptr.Ptr("baz"),
|
||||
},
|
||||
str: `"domain=foo,alias=bar,plugin=baz"`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if err := tt.config.UnmarshalJSON([]byte(tt.str)); (err != nil) != tt.wantErr {
|
||||
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestACMEDomainConfig_EncodeValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
key string
|
||||
v *url.Values
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config ACMEDomainConfig
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "domain only",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
},
|
||||
args: args{
|
||||
"acme",
|
||||
&url.Values{
|
||||
"domain": {"foo"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "domain and alias",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
Alias: ptr.Ptr("bar"),
|
||||
},
|
||||
args: args{
|
||||
"acme",
|
||||
&url.Values{
|
||||
"domain": {"foo"},
|
||||
"alias": {"bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "domain and plugin",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
Plugin: ptr.Ptr("bar"),
|
||||
},
|
||||
args: args{
|
||||
"acme",
|
||||
&url.Values{
|
||||
"domain": {"foo"},
|
||||
"plugin": {"bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "domain, alias, and plugin",
|
||||
config: ACMEDomainConfig{
|
||||
Domain: "foo",
|
||||
Alias: ptr.Ptr("bar"),
|
||||
Plugin: ptr.Ptr("baz"),
|
||||
},
|
||||
args: args{
|
||||
"acme",
|
||||
&url.Values{
|
||||
"domain": {"foo"},
|
||||
"alias": {"bar"},
|
||||
"plugin": {"baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if err := tt.config.EncodeValues(tt.args.key, tt.args.v); (err != nil) != tt.wantErr {
|
||||
t.Errorf("EncodeValues() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWakeOnLandConfig_UnmarshalJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config WakeOnLandConfig
|
||||
str string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "mac only",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
},
|
||||
str: `"00:11:22:33:44:55"`,
|
||||
},
|
||||
{
|
||||
name: "mac only with key",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
},
|
||||
str: `"mac=00:11:22:33:44:55"`,
|
||||
},
|
||||
{
|
||||
name: "mac and bind interface",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
BindInterface: ptr.Ptr("eth0"),
|
||||
},
|
||||
str: `"mac=00:11:22:33:44:55,bind-interface=eth0"`,
|
||||
},
|
||||
{
|
||||
name: "mac and broadcast address",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
BroadcastAddress: ptr.Ptr("192.168.0.155"),
|
||||
},
|
||||
str: `"mac=00:11:22:33:44:55,broadcast-address=192.168.0.255"`,
|
||||
},
|
||||
{
|
||||
name: "mac, bind interface, and broadcast address",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
BindInterface: ptr.Ptr("eth0"),
|
||||
BroadcastAddress: ptr.Ptr("192.168.0.255"),
|
||||
},
|
||||
str: `"mac=00:11:22:33:44:55,bind-interface=eth0,broadcast-address=192.168.0.255"`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if err := tt.config.UnmarshalJSON([]byte(tt.str)); (err != nil) != tt.wantErr {
|
||||
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWakeOnLandConfig_EncodeValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
key string
|
||||
v *url.Values
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config WakeOnLandConfig
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "mac only",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
},
|
||||
args: args{
|
||||
"wakeonlan",
|
||||
&url.Values{
|
||||
"mac": {"00:11:22:33:44:55"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "mac and bind interface",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
BindInterface: ptr.Ptr("eth0"),
|
||||
},
|
||||
args: args{
|
||||
"wakeonlan",
|
||||
&url.Values{
|
||||
"mac": {"00:11:22:33:44:55"},
|
||||
"bind-interface": {"eth0"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "mac and broadcast address",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
BroadcastAddress: ptr.Ptr("192.168.0.255"),
|
||||
},
|
||||
args: args{
|
||||
"wakeonlan",
|
||||
&url.Values{
|
||||
"mac": {"00:11:22:33:44:55"},
|
||||
"broadcast-address": {"192.168.0.255"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "mac, bind interface, and broadcast address",
|
||||
config: WakeOnLandConfig{
|
||||
MACAddress: "00:11:22:33:44:55",
|
||||
BindInterface: ptr.Ptr("eth0"),
|
||||
BroadcastAddress: ptr.Ptr("10.255.255.255"),
|
||||
},
|
||||
args: args{
|
||||
"wakeonlan",
|
||||
&url.Values{
|
||||
"mac": {"00:11:22:33:44:55"},
|
||||
"bind-interface": {"eth0"},
|
||||
"broadcast-address": {"10.255.255.255"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if err := tt.config.EncodeValues(tt.args.key, tt.args.v); (err != nil) != tt.wantErr {
|
||||
t.Errorf("EncodeValues() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user