diff --git a/scripts/run_agent.sh b/scripts/run_agent.sh index 45884f5..4d724d2 100755 --- a/scripts/run_agent.sh +++ b/scripts/run_agent.sh @@ -21,6 +21,7 @@ docker run --rm -it --network=host \ --mount type=bind,source=/etc/ssh,target=/etc/ssh,readonly \ --mount type=bind,source=/etc/os-release,target=/etc/os-release,readonly \ --mount type=bind,source=/var/lib/NetworkManager,target=/var/lib/NetworkManager,readonly \ + --mount type=bind,source=/var/run/NetworkManager,target=/var/run/NetworkManager,readonly \ --mount type=bind,source=/var/run/dbus,target=/var/run/dbus,readonly \ --privileged \ ${DOCKER_SZTP_IMAGE} \ diff --git a/sztp-agent/Dockerfile b/sztp-agent/Dockerfile index 1920cb6..fde633a 100644 --- a/sztp-agent/Dockerfile +++ b/sztp-agent/Dockerfile @@ -17,8 +17,8 @@ RUN go build -v -o /opi-sztp-agent && CGO_ENABLED=0 go test -v ./... # second stage to reduce image size FROM alpine:3.20 -RUN apk add --no-cache --no-check-certificate curl dbus networkmanager && rm -rf /var/cache/apk/* +RUN apk add --no-cache --no-check-certificate curl && rm -rf /var/cache/apk/* COPY --from=builder /opi-sztp-agent / -CMD ["sh", "-c", "dbus-daemon --system && /opi-sztp-agent"] +CMD ["/opi-sztp-agent"] diff --git a/sztp-agent/cmd/daemon.go b/sztp-agent/cmd/daemon.go index 69c5dd4..8b504a6 100644 --- a/sztp-agent/cmd/daemon.go +++ b/sztp-agent/cmd/daemon.go @@ -59,7 +59,7 @@ func Daemon() *cobra.Command { return fmt.Errorf("must not be folder: %q", filePath) } } - a := secureagent.NewAgent(bootstrapURL, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) + a := secureagent.NewAgent([]string{bootstrapURL}, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) return a.RunCommandDaemon() }, } diff --git a/sztp-agent/cmd/disable.go b/sztp-agent/cmd/disable.go index 3ce70a4..886b54e 100644 --- a/sztp-agent/cmd/disable.go +++ b/sztp-agent/cmd/disable.go @@ -34,7 +34,7 @@ func Disable() *cobra.Command { Use: "disable", Short: "Run the disable command", RunE: func(_ *cobra.Command, _ []string) error { - a := secureagent.NewAgent(bootstrapURL, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) + a := secureagent.NewAgent([]string{bootstrapURL}, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) return a.RunCommandDisable() }, } diff --git a/sztp-agent/cmd/enable.go b/sztp-agent/cmd/enable.go index 745bd79..9159f7b 100644 --- a/sztp-agent/cmd/enable.go +++ b/sztp-agent/cmd/enable.go @@ -34,7 +34,7 @@ func Enable() *cobra.Command { Use: "enable", Short: "Run the enable command", RunE: func(_ *cobra.Command, _ []string) error { - a := secureagent.NewAgent(bootstrapURL, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) + a := secureagent.NewAgent([]string{bootstrapURL}, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) return a.RunCommandEnable() }, } diff --git a/sztp-agent/cmd/run.go b/sztp-agent/cmd/run.go index 9ee6152..e8d56e4 100644 --- a/sztp-agent/cmd/run.go +++ b/sztp-agent/cmd/run.go @@ -59,7 +59,7 @@ func Run() *cobra.Command { return fmt.Errorf("must not be folder: %q", filePath) } } - a := secureagent.NewAgent(bootstrapURL, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) + a := secureagent.NewAgent([]string{bootstrapURL}, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) return a.RunCommand() }, } diff --git a/sztp-agent/cmd/status.go b/sztp-agent/cmd/status.go index cf5043a..ce6eef5 100644 --- a/sztp-agent/cmd/status.go +++ b/sztp-agent/cmd/status.go @@ -34,7 +34,7 @@ func Status() *cobra.Command { Use: "status", Short: "Run the status command", RunE: func(_ *cobra.Command, _ []string) error { - a := secureagent.NewAgent(bootstrapURL, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) + a := secureagent.NewAgent([]string{bootstrapURL}, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert) return a.RunCommandStatus() }, } diff --git a/sztp-agent/pkg/dhcp/bootstrap_url.go b/sztp-agent/pkg/dhcp/bootstrap_url.go new file mode 100644 index 0000000..ef6c442 --- /dev/null +++ b/sztp-agent/pkg/dhcp/bootstrap_url.go @@ -0,0 +1,25 @@ +/* +SPDX-License-Identifier: Apache-2.0 +Copyright (C) 2022-2023 Intel Corporation +Copyright (c) 2022 Dell Inc, or its subsidiaries. +Copyright (C) 2022 Red Hat. +*/ + +// Package dhcp implements the DHCP client +package dhcp + +import "log" + +// GetBootstrapURL returns the bootstrap URL +func GetBootstrapURL(dhcpLeaseFile string) ([]string, error) { + url, err := getBootstrapURLViaLeaseFile(dhcpLeaseFile) + if err == nil { + return []string{url}, nil + } + log.Println("[INFO] Trying to get the URL from NetworkManager") + urls, err := getBootstrapURLViaNetworkManager() + if err == nil { + return urls, nil + } + return nil, err +} diff --git a/sztp-agent/pkg/dhcp/bootstrap_url_test.go b/sztp-agent/pkg/dhcp/bootstrap_url_test.go new file mode 100644 index 0000000..fa5eabb --- /dev/null +++ b/sztp-agent/pkg/dhcp/bootstrap_url_test.go @@ -0,0 +1,15 @@ +/* +SPDX-License-Identifier: Apache-2.0 +Copyright (C) 2022-2023 Intel Corporation +Copyright (c) 2022 Dell Inc, or its subsidiaries. +Copyright (C) 2022 Red Hat. +*/ + +// Package dhcp implements the DHCP client +package dhcp + +import "testing" + +func TestGetBootstrapURL(_ *testing.T) { + // TODO: Implement the test +} diff --git a/sztp-agent/pkg/dhcp/dhcp_lease.go b/sztp-agent/pkg/dhcp/dhcp_lease.go new file mode 100644 index 0000000..34105c2 --- /dev/null +++ b/sztp-agent/pkg/dhcp/dhcp_lease.go @@ -0,0 +1,33 @@ +/* +SPDX-License-Identifier: Apache-2.0 +Copyright (C) 2022-2023 Intel Corporation +Copyright (c) 2022 Dell Inc, or its subsidiaries. +Copyright (C) 2022 Red Hat. +*/ + +// Package dhcp implements the DHCP client +package dhcp + +import ( + "errors" + "log" + "os" +) + +const sztpRedirectUrls = "sztp-redirect-urls" + +// getBootstrapURLViaLeaseFile returns the sztp redirect URL via DHCP lease file +func getBootstrapURLViaLeaseFile(dhcpLeaseFile string) (string, error) { + var line string + if _, err := os.Stat(dhcpLeaseFile); err == nil { + for { + line = LinesInFileContains(dhcpLeaseFile, sztpRedirectUrls) + if line != "" { + break + } + } + return ExtractfromLine(line, `(?m)[^"]*`, 1), nil + } + log.Println("[Error] File " + dhcpLeaseFile + " does not exist") + return "", errors.New("File " + dhcpLeaseFile + " does not exist") +} diff --git a/sztp-agent/pkg/dhcp/dhcp_lease_test.go b/sztp-agent/pkg/dhcp/dhcp_lease_test.go new file mode 100644 index 0000000..a907eba --- /dev/null +++ b/sztp-agent/pkg/dhcp/dhcp_lease_test.go @@ -0,0 +1,53 @@ +/* +SPDX-License-Identifier: Apache-2.0 +Copyright (C) 2022-2023 Intel Corporation +Copyright (c) 2022 Dell Inc, or its subsidiaries. +Copyright (C) 2022 Red Hat. +*/ + +// Package dhcp implements the DHCP client +package dhcp + +import "testing" + +func TestGetBootstrapURLViaLeaseFile(t *testing.T) { + dhcpTestFileOK := "/tmp/test.dhcp" + CreateTempTestFile(dhcpTestFileOK, DHCPTestContent, true) + + type fields struct { + DhcpLeaseFile string + } + tests := []struct { + name string + fields fields + want string + wantErr bool + }{ + { + name: "Test OK Case file exists and get the URL", + fields: fields{ + DhcpLeaseFile: dhcpTestFileOK, + }, + want: "http://mymock/test", + wantErr: false, + }, + { + name: "Test KO Case file does not exist", + fields: fields{ + DhcpLeaseFile: "/kk/kk", + }, + want: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getBootstrapURLViaLeaseFile(tt.fields.DhcpLeaseFile) + if (err != nil) != tt.wantErr { + t.Errorf("GetBootstrapURLViaLeaseFile() error = %v, wantErr %v", err, tt.wantErr) + } else if got != tt.want { + t.Errorf("GetBootstrapURLViaLeaseFile() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/sztp-agent/pkg/dhcp/network_manager.go b/sztp-agent/pkg/dhcp/network_manager.go index 672562f..c65e608 100644 --- a/sztp-agent/pkg/dhcp/network_manager.go +++ b/sztp-agent/pkg/dhcp/network_manager.go @@ -15,11 +15,11 @@ import ( "github.com/godbus/dbus/v5" ) -// GetBootstrapURLViaNetworkManager returns the sztp redirect URL via NetworkManager -func GetBootstrapURLViaNetworkManager() (string, error) { +// getBootstrapURLViaNetworkManager returns the sztp redirect URL via NetworkManager +func getBootstrapURLViaNetworkManager() ([]string, error) { conn, err := dbus.SystemBus() if err != nil { - return "", fmt.Errorf("failed to connect to system bus: %v", err) + return nil, fmt.Errorf("failed to connect to system bus: %v", err) } nm := conn.Object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager") @@ -27,13 +27,14 @@ func GetBootstrapURLViaNetworkManager() (string, error) { var activeConnections []dbus.ObjectPath err = nm.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager", "ActiveConnections").Store(&activeConnections) if err != nil { - return "", fmt.Errorf("failed to get ActiveConnections property: %v", err) + return nil, fmt.Errorf("failed to get ActiveConnections property: %v", err) } if len(activeConnections) == 0 { - return "", fmt.Errorf("no active connections found") + return nil, fmt.Errorf("no active connections found") } + var sztpRedirectURLs []string for _, activeConnPath := range activeConnections { connActive := conn.Object("org.freedesktop.NetworkManager", activeConnPath) @@ -54,14 +55,15 @@ func GetBootstrapURLViaNetworkManager() (string, error) { if variant, ok := options["sztp_redirect_urls"]; ok { if variant.Signature().String() == "s" { - sztpRedirectURLs := variant.Value().(string) - log.Println("[SUCCESS] sztp_redirect_urls: ", sztpRedirectURLs) - return sztpRedirectURLs, nil + sztpRedirectURL := variant.Value().(string) + log.Println("[INFO] sztp_redirect_url found: ", sztpRedirectURLs) + sztpRedirectURLs = append(sztpRedirectURLs, sztpRedirectURL) + continue } log.Println("[INFO] sztp_redirect_urls is not a string in DHCP4Config ", dhcpPath) } else { log.Println("[INFO] sztp_redirect_urls not found in DHCP4Config ", dhcpPath) } } - return "", fmt.Errorf("sztp_redirect_urls not found in any active connection") + return sztpRedirectURLs, fmt.Errorf("sztp_redirect_urls not found in any active connection") } diff --git a/sztp-agent/pkg/secureagent/agent.go b/sztp-agent/pkg/secureagent/agent.go index 774a96a..f3a38c8 100644 --- a/sztp-agent/pkg/secureagent/agent.go +++ b/sztp-agent/pkg/secureagent/agent.go @@ -12,7 +12,6 @@ package secureagent const ( CONTENT_TYPE_YANG = "application/yang-data+json" OS_RELEASE_FILE = "/etc/os-release" - SZTP_REDIRECT_URL = "sztp-redirect-urls" ARTIFACTS_PATH = "/tmp/" ) @@ -70,7 +69,7 @@ type BootstrapServerErrorOutput struct { // Agent is the basic structure to define an agent instance type Agent struct { - BootstrapURL string // Bootstrap complete URL + BootstrapURL []string // Bootstrap complete URL SerialNumber string // Device's Serial Number DevicePassword string // Device's Password DevicePrivateKey string // Device's private key @@ -85,7 +84,7 @@ type Agent struct { } -func NewAgent(bootstrapURL, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert string) *Agent { +func NewAgent(bootstrapURL []string, serialNumber, dhcpLeaseFile, devicePassword, devicePrivateKey, deviceEndEntityCert, bootstrapTrustAnchorCert string) *Agent { return &Agent{ BootstrapURL: bootstrapURL, SerialNumber: GetSerialNumber(serialNumber), @@ -102,7 +101,7 @@ func NewAgent(bootstrapURL, serialNumber, dhcpLeaseFile, devicePassword, deviceP } } -func (a *Agent) GetBootstrapURL() string { +func (a *Agent) GetBootstrapURL() []string { return a.BootstrapURL } @@ -138,8 +137,8 @@ func (a *Agent) GetProgressJSON() ProgressJSON { return a.ProgressJSON } -func (a *Agent) SetBootstrapURL(url string) { - a.BootstrapURL = url +func (a *Agent) SetBootstrapURL(urls []string) { + a.BootstrapURL = urls } func (a *Agent) SetSerialNumber(serialNumber string) { diff --git a/sztp-agent/pkg/secureagent/agent_test.go b/sztp-agent/pkg/secureagent/agent_test.go index 41ba21a..95ae286 100644 --- a/sztp-agent/pkg/secureagent/agent_test.go +++ b/sztp-agent/pkg/secureagent/agent_test.go @@ -15,7 +15,7 @@ import ( func TestAgent_GetBootstrapTrustAnchorCert(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -32,7 +32,7 @@ func TestAgent_GetBootstrapTrustAnchorCert(t *testing.T) { { name: "Test get case BootstrapTrustAnchorCert", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -65,7 +65,7 @@ func TestAgent_GetBootstrapTrustAnchorCert(t *testing.T) { func TestAgent_GetBootstrapURL(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -77,12 +77,12 @@ func TestAgent_GetBootstrapURL(t *testing.T) { tests := []struct { name string fields fields - want string + want []string }{ { name: "Test get case BootstrapURL", fields: fields{ - BootstrapURL: "testBootstrapURL", + BootstrapURL: []string{"testBootstrapURL"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -91,7 +91,7 @@ func TestAgent_GetBootstrapURL(t *testing.T) { ContentTypeReq: "test", InputJSONContent: "test", }, - want: "testBootstrapURL", + want: []string{"testBootstrapURL"}, }, } for _, tt := range tests { @@ -106,8 +106,8 @@ func TestAgent_GetBootstrapURL(t *testing.T) { ContentTypeReq: tt.fields.ContentTypeReq, InputJSONContent: tt.fields.InputJSONContent, } - if got := a.GetBootstrapURL(); got != tt.want { - t.Errorf("GetBootstrapURL() = %v, want %v", got, tt.want) + if !reflect.DeepEqual(a.GetBootstrapURL(), tt.want) { + t.Errorf("GetBootstrapURL() = %v, want %v", a.GetBootstrapURL(), tt.want) } }) } @@ -115,7 +115,7 @@ func TestAgent_GetBootstrapURL(t *testing.T) { func TestAgent_GetContentTypeReq(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -132,7 +132,7 @@ func TestAgent_GetContentTypeReq(t *testing.T) { { name: "Test get ContentTypeReq ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -165,7 +165,7 @@ func TestAgent_GetContentTypeReq(t *testing.T) { func TestAgent_GetDeviceEndEntityCert(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -182,7 +182,7 @@ func TestAgent_GetDeviceEndEntityCert(t *testing.T) { { name: "Test get GetDeviceEndEntityCert ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -215,7 +215,7 @@ func TestAgent_GetDeviceEndEntityCert(t *testing.T) { func TestAgent_GetDevicePassword(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -232,7 +232,7 @@ func TestAgent_GetDevicePassword(t *testing.T) { { name: "Test get GetDevicePassword ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "testDevicePassword", DevicePrivateKey: "test", @@ -265,7 +265,7 @@ func TestAgent_GetDevicePassword(t *testing.T) { func TestAgent_GetDevicePrivateKey(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -282,7 +282,7 @@ func TestAgent_GetDevicePrivateKey(t *testing.T) { { name: "Test get GetDevicePrivateKey ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "testDevicePrivateKey", @@ -315,7 +315,7 @@ func TestAgent_GetDevicePrivateKey(t *testing.T) { func TestAgent_GetInputJSONContent(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -332,7 +332,7 @@ func TestAgent_GetInputJSONContent(t *testing.T) { { name: "Test get GetInputJsonContent ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -365,7 +365,7 @@ func TestAgent_GetInputJSONContent(t *testing.T) { func TestAgent_GetSerialNumber(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -382,7 +382,7 @@ func TestAgent_GetSerialNumber(t *testing.T) { { name: "Test get GetSerialNumber ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "testSerialNumber", DevicePassword: "test", DevicePrivateKey: "test", @@ -396,7 +396,7 @@ func TestAgent_GetSerialNumber(t *testing.T) { { name: "Test SMBIOS GetSerialNumber ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "", DevicePassword: "test", DevicePrivateKey: "test", @@ -429,7 +429,7 @@ func TestAgent_GetSerialNumber(t *testing.T) { func TestAgent_SetBootstrapTrustAnchorCert(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -449,7 +449,7 @@ func TestAgent_SetBootstrapTrustAnchorCert(t *testing.T) { { name: "Test set SetDeviceEndEntityCert ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -485,7 +485,7 @@ func TestAgent_SetBootstrapTrustAnchorCert(t *testing.T) { func TestAgent_SetBootstrapURL(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -495,7 +495,7 @@ func TestAgent_SetBootstrapURL(t *testing.T) { InputJSONContent string } type args struct { - bootstrapURL string + bootstrapURL []string } tests := []struct { name string @@ -505,7 +505,7 @@ func TestAgent_SetBootstrapURL(t *testing.T) { { name: "Test set SetBootstrapURL ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -515,7 +515,7 @@ func TestAgent_SetBootstrapURL(t *testing.T) { InputJSONContent: "test", }, args: args{ - bootstrapURL: "bootstrapURL", + bootstrapURL: []string{"bootstrapURL"}, }, }, } @@ -532,7 +532,7 @@ func TestAgent_SetBootstrapURL(t *testing.T) { InputJSONContent: tt.fields.InputJSONContent, } a.SetBootstrapURL(tt.args.bootstrapURL) - if a.GetBootstrapURL() != tt.args.bootstrapURL { + if !reflect.DeepEqual(a.GetBootstrapURL(), tt.args.bootstrapURL) { t.Errorf("SetBootstrapURL = %v, want %v", a.GetBootstrapURL(), tt.args.bootstrapURL) } }) @@ -541,7 +541,7 @@ func TestAgent_SetBootstrapURL(t *testing.T) { func TestAgent_SetContentTypeReq(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -561,7 +561,7 @@ func TestAgent_SetContentTypeReq(t *testing.T) { { name: "Test set setContentType ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -597,7 +597,7 @@ func TestAgent_SetContentTypeReq(t *testing.T) { func TestAgent_SetDeviceEndEntityCert(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -617,7 +617,7 @@ func TestAgent_SetDeviceEndEntityCert(t *testing.T) { { name: "Test set SetDeviceEndEntityCert ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -653,7 +653,7 @@ func TestAgent_SetDeviceEndEntityCert(t *testing.T) { func TestAgent_SetDevicePassword(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -673,7 +673,7 @@ func TestAgent_SetDevicePassword(t *testing.T) { { name: "Test set SetDevicePassword ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -709,7 +709,7 @@ func TestAgent_SetDevicePassword(t *testing.T) { func TestAgent_SetDevicePrivateKey(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -729,7 +729,7 @@ func TestAgent_SetDevicePrivateKey(t *testing.T) { { name: "Test set GetBootstrapURL ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -765,7 +765,7 @@ func TestAgent_SetDevicePrivateKey(t *testing.T) { func TestAgent_SetSerialNumber(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -785,7 +785,7 @@ func TestAgent_SetSerialNumber(t *testing.T) { { name: "Test set setSerialnumber ", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -821,7 +821,7 @@ func TestAgent_SetSerialNumber(t *testing.T) { func TestNewAgent(t *testing.T) { type args struct { - bootstrapURL string + bootstrapURL []string serialNumber string dhcpLeaseFile string devicePassword string @@ -837,7 +837,7 @@ func TestNewAgent(t *testing.T) { { name: "Test Constructor", args: args{ - bootstrapURL: "TestBootstrap", + bootstrapURL: []string{"TestBootstrap"}, serialNumber: "TestSerialNumber", dhcpLeaseFile: "TestDhcpLeaseFile", devicePassword: "TestDevicePassword", @@ -846,7 +846,7 @@ func TestNewAgent(t *testing.T) { bootstrapTrustAnchorCert: "TestBootstrapTrustCert", }, want: &Agent{ - BootstrapURL: "TestBootstrap", + BootstrapURL: []string{"TestBootstrap"}, SerialNumber: "TestSerialNumber", DevicePassword: "TestDevicePassword", DevicePrivateKey: "TestDevicePrivateKey", @@ -869,7 +869,7 @@ func TestNewAgent(t *testing.T) { func TestAgent_GetProgressJson(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -888,7 +888,7 @@ func TestAgent_GetProgressJson(t *testing.T) { { name: "Test GetProgressJson", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", @@ -960,7 +960,7 @@ func TestAgent_GetProgressJson(t *testing.T) { // nolint:funlen func TestAgent_SetProgressJson(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -982,7 +982,7 @@ func TestAgent_SetProgressJson(t *testing.T) { { name: "Test SetProgressJson", fields: fields{ - BootstrapURL: "test", + BootstrapURL: []string{"test"}, SerialNumber: "test", DevicePassword: "test", DevicePrivateKey: "test", diff --git a/sztp-agent/pkg/secureagent/daemon.go b/sztp-agent/pkg/secureagent/daemon.go index aeccc55..f39716f 100644 --- a/sztp-agent/pkg/secureagent/daemon.go +++ b/sztp-agent/pkg/secureagent/daemon.go @@ -46,7 +46,7 @@ func (a *Agent) RunCommandDaemon() error { for { err := a.performBootstrapSequence() if err != nil { - log.Println("[ERROR] Failed to perform the bootstrap sequence: ", err.Error()) + log.Println("[ERROR] ", err.Error()) log.Println("[INFO] Retrying in 5 seconds") time.Sleep(5 * time.Second) continue @@ -57,65 +57,69 @@ func (a *Agent) RunCommandDaemon() error { func (a *Agent) performBootstrapSequence() error { var err error - if a.GetBootstrapURL() == "" { + // check if empty + if len(a.GetBootstrapURL()) == 1 && a.GetBootstrapURL()[0] == "" { + log.Println("lmao") err = a.getBootstrapURL() if err != nil { return err } } - err = a.doRequestBootstrapServerOnboardingInfo() - if err != nil { - return err - } - err = a.doHandleBootstrapRedirect() - if err != nil { - return err - } - err = a.downloadAndValidateImage() - if err != nil { - return err - } - err = a.copyConfigurationFile() - if err != nil { - return err - } - err = a.launchScriptsConfiguration(PRE) - if err != nil { - return err - } - err = a.launchScriptsConfiguration(POST) - if err != nil { - return err + log.Println("Bootstrap URL: ", a.GetBootstrapURL()) + bootstrapURLs := a.GetBootstrapURL() + for _, bootstrapURL := range bootstrapURLs { + bootstrapURLCopy := bootstrapURL + err = a.doRequestBootstrapServerOnboardingInfo(&bootstrapURLCopy) + if err != nil { + log.Println("[ERROR] ", err.Error()) + continue + } + err = a.doHandleBootstrapRedirect(&bootstrapURLCopy) + if err != nil { + log.Println("[ERROR] ", err.Error()) + continue + } + err = a.downloadAndValidateImage(&bootstrapURLCopy) + if err != nil { + log.Println("[ERROR] ", err.Error()) + continue + } + err = a.copyConfigurationFile(&bootstrapURLCopy) + if err != nil { + log.Println("[ERROR] ", err.Error()) + continue + } + err = a.launchScriptsConfiguration(PRE, &bootstrapURLCopy) + if err != nil { + log.Println("[ERROR] ", err.Error()) + continue + } + err = a.launchScriptsConfiguration(POST, &bootstrapURLCopy) + if err != nil { + log.Println("[ERROR] ", err.Error()) + continue + } + _ = a.doReportProgress(ProgressTypeBootstrapComplete, "Bootstrap Complete", bootstrapURLCopy) + return nil } - _ = a.doReportProgress(ProgressTypeBootstrapComplete, "Bootstrap Complete") - return nil + return errors.New("failed to perform the bootstrap sequence") } func (a *Agent) getBootstrapURL() error { log.Println("[INFO] Get the Bootstrap URL from DHCP client") - var line string - if _, err := os.Stat(a.DhcpLeaseFile); err == nil { - for { - line = dhcp.LinesInFileContains(a.DhcpLeaseFile, SZTP_REDIRECT_URL) - if line != "" { - break - } - } - a.SetBootstrapURL(dhcp.ExtractfromLine(line, `(?m)[^"]*`, 1)) - } else { - log.Println("[INFO] File " + a.DhcpLeaseFile + " does not exist, trying to get the URL from NetworkManager") - url, err := dhcp.GetBootstrapURLViaNetworkManager() - if err != nil { - log.Println("[ERROR] ", err.Error()) - return err - } - a.SetBootstrapURL(url) + + sztpRedirectUrls, err := dhcp.GetBootstrapURL(a.DhcpLeaseFile) + if err != nil { + log.Println("[ERROR] ", err.Error()) + return err } - log.Println("[INFO] Bootstrap URL retrieved successfully: " + a.GetBootstrapURL()) + a.SetBootstrapURL(sztpRedirectUrls) + // log.Println("[INFO] Bootstrap URL retrieved successfully: " + a.GetBootstrapURL()) + log.Println("[INFO] Bootstrap URL retrieved successfully") return nil } -func (a *Agent) doHandleBootstrapRedirect() error { +func (a *Agent) doHandleBootstrapRedirect(bootstrapURL *string) error { if reflect.ValueOf(a.BootstrapServerRedirectInfo).IsZero() { return nil } @@ -128,26 +132,27 @@ func (a *Agent) doHandleBootstrapRedirect() error { port := a.BootstrapServerRedirectInfo.IetfSztpConveyedInfoRedirectInformation.BootstrapServer[0].Port // Change URL to point to new redirect IP and PORT - u, err := url.Parse(a.GetBootstrapURL()) + u, err := url.Parse(*bootstrapURL) if err != nil { return err } u.Host = fmt.Sprintf("%s:%d", addr, port) - a.SetBootstrapURL(u.String()) + // a.SetBootstrapURL(u.String()) + *bootstrapURL = u.String() // Request onboard ino again (with new URL now) - return a.doRequestBootstrapServerOnboardingInfo() + return a.doRequestBootstrapServerOnboardingInfo(bootstrapURL) } -func (a *Agent) doRequestBootstrapServerOnboardingInfo() error { +func (a *Agent) doRequestBootstrapServerOnboardingInfo(bootstrapURL *string) error { log.Println("[INFO] Starting the Request to get On-boarding Information.") - res, err := a.doTLSRequest(a.GetInputJSONContent(), a.GetBootstrapURL(), false) + res, err := a.doTLSRequest(a.GetInputJSONContent(), *bootstrapURL, false) if err != nil { log.Println("[ERROR] ", err.Error()) return err } log.Println("[INFO] Response retrieved successfully") - _ = a.doReportProgress(ProgressTypeBootstrapInitiated, "Bootstrap Initiated") + _ = a.doReportProgress(ProgressTypeBootstrapInitiated, "Bootstrap Initiated", *bootstrapURL) crypto := res.IetfSztpBootstrapServerOutput.ConveyedInformation newVal, err := base64.StdEncoding.DecodeString(crypto) if err != nil { @@ -185,9 +190,9 @@ func (a *Agent) doRequestBootstrapServerOnboardingInfo() error { } //nolint:funlen -func (a *Agent) downloadAndValidateImage() error { +func (a *Agent) downloadAndValidateImage(bootstrapURL *string) error { log.Printf("[INFO] Starting the Download Image: %v", a.BootstrapServerOnboardingInfo.IetfSztpConveyedInfoOnboardingInformation.BootImage.DownloadURI) - _ = a.doReportProgress(ProgressTypeBootImageInitiated, "BootImage Initiated") + _ = a.doReportProgress(ProgressTypeBootImageInitiated, "BootImage Initiated", *bootstrapURL) // Download the image from DownloadURI and save it to a file a.BootstrapServerOnboardingInfo.IetfSztpConveyedInfoOnboardingInformation.InfoTimestampReference = fmt.Sprintf("%8d", time.Now().Unix()) for i, item := range a.BootstrapServerOnboardingInfo.IetfSztpConveyedInfoOnboardingInformation.BootImage.DownloadURI { @@ -273,7 +278,7 @@ func (a *Agent) downloadAndValidateImage() error { return errors.New("checksum mismatch") } log.Println("[INFO] Checksum verified successfully") - _ = a.doReportProgress(ProgressTypeBootImageComplete, "BootImage Complete") + _ = a.doReportProgress(ProgressTypeBootImageComplete, "BootImage Complete", *bootstrapURL) return nil default: return errors.New("unsupported hash algorithm") @@ -282,9 +287,9 @@ func (a *Agent) downloadAndValidateImage() error { return nil } -func (a *Agent) copyConfigurationFile() error { +func (a *Agent) copyConfigurationFile(bootstrapURL *string) error { log.Println("[INFO] Starting the Copy Configuration.") - _ = a.doReportProgress(ProgressTypeConfigInitiated, "Configuration Initiated") + _ = a.doReportProgress(ProgressTypeConfigInitiated, "Configuration Initiated", *bootstrapURL) // Copy the configuration file to the device file, err := os.Create(ARTIFACTS_PATH + a.BootstrapServerOnboardingInfo.IetfSztpConveyedInfoOnboardingInformation.InfoTimestampReference + "-config") if err != nil { @@ -310,11 +315,11 @@ func (a *Agent) copyConfigurationFile() error { return err } log.Println("[INFO] Configuration file copied successfully") - _ = a.doReportProgress(ProgressTypeConfigComplete, "Configuration Complete") + _ = a.doReportProgress(ProgressTypeConfigComplete, "Configuration Complete", *bootstrapURL) return nil } -func (a *Agent) launchScriptsConfiguration(typeOf string) error { +func (a *Agent) launchScriptsConfiguration(typeOf string, bootstrapURL *string) error { var script, scriptName string var reportStart, reportEnd ProgressType switch typeOf { @@ -330,7 +335,7 @@ func (a *Agent) launchScriptsConfiguration(typeOf string) error { reportEnd = ProgressTypePreScriptComplete } log.Println("[INFO] Starting the " + scriptName + "-configuration.") - _ = a.doReportProgress(reportStart, "Report starting") + _ = a.doReportProgress(reportStart, "Report starting", *bootstrapURL) // nolint:gosec file, err := os.Create(ARTIFACTS_PATH + a.BootstrapServerOnboardingInfo.IetfSztpConveyedInfoOnboardingInformation.InfoTimestampReference + scriptName + "configuration.sh") if err != nil { @@ -363,7 +368,7 @@ func (a *Agent) launchScriptsConfiguration(typeOf string) error { return err } log.Println(string(out)) // remove it - _ = a.doReportProgress(reportEnd, "Report end") + _ = a.doReportProgress(reportEnd, "Report end", *bootstrapURL) log.Println("[INFO] " + scriptName + "-Configuration script executed successfully") return nil } diff --git a/sztp-agent/pkg/secureagent/daemon_test.go b/sztp-agent/pkg/secureagent/daemon_test.go index d7537c0..25dda97 100644 --- a/sztp-agent/pkg/secureagent/daemon_test.go +++ b/sztp-agent/pkg/secureagent/daemon_test.go @@ -21,7 +21,7 @@ func TestAgent_getBootstrapURL(t *testing.T) { dhcp.CreateTempTestFile(dhcpTestFileOK, dhcp.DHCPTestContent, true) type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -39,7 +39,7 @@ func TestAgent_getBootstrapURL(t *testing.T) { { name: "Test OK Case file exists and get url successfully", fields: fields{ - BootstrapURL: "http://localhost", + BootstrapURL: []string{"http://localhost"}, SerialNumber: "my-serial-number", DevicePassword: "my-password", DevicePrivateKey: "", @@ -54,7 +54,7 @@ func TestAgent_getBootstrapURL(t *testing.T) { { name: "Test KO when not file found", fields: fields{ - BootstrapURL: "http://localhost", + BootstrapURL: []string{"http://localhost"}, SerialNumber: "my-serial-number", DevicePassword: "my-password", DevicePrivateKey: "", @@ -162,7 +162,7 @@ func TestAgent_doReqBootstrap(t *testing.T) { defer svr.Close() type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -180,7 +180,7 @@ func TestAgent_doReqBootstrap(t *testing.T) { { name: "Test OK passing all the Onboarding information", fields: fields{ - BootstrapURL: svr.URL, + BootstrapURL: []string{svr.URL}, SerialNumber: "USER", DevicePassword: "PASS", DevicePrivateKey: "", @@ -195,7 +195,7 @@ func TestAgent_doReqBootstrap(t *testing.T) { { name: "Test OK passing all the Redirect information", fields: fields{ - BootstrapURL: svr.URL, + BootstrapURL: []string{svr.URL}, SerialNumber: "REDIRECT", DevicePassword: "PASS", DevicePrivateKey: "", @@ -210,7 +210,7 @@ func TestAgent_doReqBootstrap(t *testing.T) { { name: "Test KO getting error with basic auth", fields: fields{ - BootstrapURL: svr.URL, + BootstrapURL: []string{svr.URL}, SerialNumber: "KO", DevicePassword: "KO", DevicePrivateKey: "", @@ -225,7 +225,7 @@ func TestAgent_doReqBootstrap(t *testing.T) { { name: "Test KO getting error with wrong Base64 output", fields: fields{ - BootstrapURL: svr.URL, + BootstrapURL: []string{svr.URL}, SerialNumber: "KOBASE64", DevicePassword: "KO", DevicePrivateKey: "", @@ -240,7 +240,7 @@ func TestAgent_doReqBootstrap(t *testing.T) { { name: "Test KO pointint to wrong url", fields: fields{ - BootstrapURL: "http://wrongURL", + BootstrapURL: []string{"http://wrongURL"}, SerialNumber: "KOBASE64", DevicePassword: "KO", DevicePrivateKey: "", @@ -266,7 +266,7 @@ func TestAgent_doReqBootstrap(t *testing.T) { InputJSONContent: tt.fields.InputJSONContent, DhcpLeaseFile: tt.fields.DhcpLeaseFile, } - if err := a.doRequestBootstrapServerOnboardingInfo(); (err != nil) != tt.wantErr { + if err := a.doRequestBootstrapServerOnboardingInfo(&(tt.fields.BootstrapURL[0])); (err != nil) != tt.wantErr { t.Errorf("doRequestBootstrapServer() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -285,7 +285,7 @@ func TestAgent_downloadAndValidateImage(t *testing.T) { defer svr.Close() type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -306,7 +306,7 @@ func TestAgent_downloadAndValidateImage(t *testing.T) { { name: "error writing file", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -355,7 +355,7 @@ func TestAgent_downloadAndValidateImage(t *testing.T) { { name: "Image wrong", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -402,9 +402,9 @@ func TestAgent_downloadAndValidateImage(t *testing.T) { wantErr: true, }, { - name: "Image wrong", + name: "Image wrong 2", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -453,7 +453,7 @@ func TestAgent_downloadAndValidateImage(t *testing.T) { { name: "OK Case but with error due to hash checksum", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -508,7 +508,7 @@ func TestAgent_downloadAndValidateImage(t *testing.T) { { name: "OK Case but with error due to hash checksum", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -577,7 +577,7 @@ func TestAgent_downloadAndValidateImage(t *testing.T) { BootstrapServerOnboardingInfo: tt.fields.BootstrapServerOnboardingInfo, BootstrapServerRedirectInfo: tt.fields.BootstrapServerRedirectInfo, } - if err := a.downloadAndValidateImage(); (err != nil) != tt.wantErr { + if err := a.downloadAndValidateImage(&(tt.fields.BootstrapURL[0])); (err != nil) != tt.wantErr { t.Errorf("downloadAndValidateImage() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -587,7 +587,7 @@ func TestAgent_downloadAndValidateImage(t *testing.T) { // nolint:funlen func TestAgent_copyConfigurationFile(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -608,7 +608,7 @@ func TestAgent_copyConfigurationFile(t *testing.T) { { name: "Error Writing file", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -663,7 +663,7 @@ func TestAgent_copyConfigurationFile(t *testing.T) { { name: "OK Case", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -732,7 +732,7 @@ func TestAgent_copyConfigurationFile(t *testing.T) { BootstrapServerOnboardingInfo: tt.fields.BootstrapServerOnboardingInfo, BootstrapServerRedirectInfo: tt.fields.BootstrapServerRedirectInfo, } - if err := a.copyConfigurationFile(); (err != nil) != tt.wantErr { + if err := a.copyConfigurationFile(&(tt.fields.BootstrapURL[0])); (err != nil) != tt.wantErr { t.Errorf("copyConfigurationFile() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -742,7 +742,7 @@ func TestAgent_copyConfigurationFile(t *testing.T) { // nolint:funlen func TestAgent_launchScriptsConfiguration(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -768,7 +768,7 @@ func TestAgent_launchScriptsConfiguration(t *testing.T) { args: args{typeOf: "default or pre"}, name: "OK Case with PRE", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -824,7 +824,7 @@ func TestAgent_launchScriptsConfiguration(t *testing.T) { args: args{typeOf: "post"}, name: "OK Case with POST", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -880,7 +880,7 @@ func TestAgent_launchScriptsConfiguration(t *testing.T) { args: args{typeOf: "post"}, name: "OK Case with POST", fields: fields{ - BootstrapURL: "", + BootstrapURL: []string{""}, SerialNumber: "", DevicePassword: "", DevicePrivateKey: "", @@ -949,7 +949,7 @@ func TestAgent_launchScriptsConfiguration(t *testing.T) { BootstrapServerOnboardingInfo: tt.fields.BootstrapServerOnboardingInfo, BootstrapServerRedirectInfo: tt.fields.BootstrapServerRedirectInfo, } - if err := a.launchScriptsConfiguration(tt.args.typeOf); (err != nil) != tt.wantErr { + if err := a.launchScriptsConfiguration(tt.args.typeOf, &(tt.fields.BootstrapURL[0])); (err != nil) != tt.wantErr { t.Errorf("launchScriptsConfiguration() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/sztp-agent/pkg/secureagent/disable_test.go b/sztp-agent/pkg/secureagent/disable_test.go index 4af6c85..0a4b1e5 100644 --- a/sztp-agent/pkg/secureagent/disable_test.go +++ b/sztp-agent/pkg/secureagent/disable_test.go @@ -8,7 +8,7 @@ import "testing" func TestAgent_RunCommandDisable(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -29,7 +29,7 @@ func TestAgent_RunCommandDisable(t *testing.T) { { name: "TestAgent_RunCommandDisable", fields: fields{ - BootstrapURL: "https://localhost:8443", + BootstrapURL: []string{"https://localhost:8443"}, SerialNumber: "1234567890", DevicePassword: "password", DevicePrivateKey: "privateKey", diff --git a/sztp-agent/pkg/secureagent/enable_test.go b/sztp-agent/pkg/secureagent/enable_test.go index 447260f..9e3ed27 100644 --- a/sztp-agent/pkg/secureagent/enable_test.go +++ b/sztp-agent/pkg/secureagent/enable_test.go @@ -8,7 +8,7 @@ import "testing" func TestAgent_RunCommandEnable(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -29,7 +29,7 @@ func TestAgent_RunCommandEnable(t *testing.T) { { name: "TestAgent_RunCommandEnable", fields: fields{ - BootstrapURL: "https://localhost:8443", + BootstrapURL: []string{"https://localhost:8443"}, SerialNumber: "1234567890", DevicePassword: "password", DevicePrivateKey: "privateKey", diff --git a/sztp-agent/pkg/secureagent/progress.go b/sztp-agent/pkg/secureagent/progress.go index 0b46fef..e74e0f8 100644 --- a/sztp-agent/pkg/secureagent/progress.go +++ b/sztp-agent/pkg/secureagent/progress.go @@ -109,9 +109,9 @@ func (s ProgressType) String() string { return "unknown" } -func (a *Agent) doReportProgress(s ProgressType, message string) error { +func (a *Agent) doReportProgress(s ProgressType, message string, bootstrapURL string) error { log.Println("[INFO] Starting the Report Progress request.") - url := strings.ReplaceAll(a.GetBootstrapURL(), "get-bootstrapping-data", "report-progress") + url := strings.ReplaceAll(bootstrapURL, "get-bootstrapping-data", "report-progress") var p ProgressJSON p.IetfSztpBootstrapServerInput.ProgressType = s.String() p.IetfSztpBootstrapServerInput.Message = message diff --git a/sztp-agent/pkg/secureagent/progress_test.go b/sztp-agent/pkg/secureagent/progress_test.go index 7a55c0c..257936c 100644 --- a/sztp-agent/pkg/secureagent/progress_test.go +++ b/sztp-agent/pkg/secureagent/progress_test.go @@ -96,7 +96,7 @@ func TestAgent_doReportProgress(t *testing.T) { })) defer svr.Close() type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -115,7 +115,7 @@ func TestAgent_doReportProgress(t *testing.T) { { name: "OK", fields: fields{ - BootstrapURL: svr.URL, + BootstrapURL: []string{svr.URL}, SerialNumber: "USER", DevicePassword: "PASS", DevicePrivateKey: "PRIVATEKEY", @@ -131,7 +131,7 @@ func TestAgent_doReportProgress(t *testing.T) { { name: "KO", fields: fields{ - BootstrapURL: svr.URL, + BootstrapURL: []string{svr.URL}, SerialNumber: "USER", DevicePassword: "PASSWORDWRONG", DevicePrivateKey: "PRIVATEKEY", @@ -159,7 +159,7 @@ func TestAgent_doReportProgress(t *testing.T) { DhcpLeaseFile: tt.fields.DhcpLeaseFile, ProgressJSON: tt.fields.ProgressJSON, } - if err := a.doReportProgress(ProgressTypeBootstrapInitiated, "Bootstrap Initiated"); (err != nil) != tt.wantErr { + if err := a.doReportProgress(ProgressTypeBootstrapInitiated, "Bootstrap Initiated", tt.fields.BootstrapURL[0]); (err != nil) != tt.wantErr { t.Errorf("doReportProgress() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/sztp-agent/pkg/secureagent/status_test.go b/sztp-agent/pkg/secureagent/status_test.go index 2aa1133..63435eb 100644 --- a/sztp-agent/pkg/secureagent/status_test.go +++ b/sztp-agent/pkg/secureagent/status_test.go @@ -8,7 +8,7 @@ import "testing" func TestAgent_RunCommandStatus(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -29,7 +29,7 @@ func TestAgent_RunCommandStatus(t *testing.T) { { name: "TestAgent_RunCommandStatus", fields: fields{ - BootstrapURL: "https://localhost:8443", + BootstrapURL: []string{"https://localhost:8443"}, SerialNumber: "1234567890", DevicePassword: "password", DevicePrivateKey: "privateKey", diff --git a/sztp-agent/pkg/secureagent/tls_test.go b/sztp-agent/pkg/secureagent/tls_test.go index b0c4c9a..d9a60ff 100644 --- a/sztp-agent/pkg/secureagent/tls_test.go +++ b/sztp-agent/pkg/secureagent/tls_test.go @@ -11,7 +11,7 @@ import ( func TestAgent_doTLSRequest(t *testing.T) { type fields struct { - BootstrapURL string + BootstrapURL []string SerialNumber string DevicePassword string DevicePrivateKey string @@ -40,7 +40,7 @@ func TestAgent_doTLSRequest(t *testing.T) { InputJSONContent: tt.fields.InputJSONContent, DhcpLeaseFile: tt.fields.DhcpLeaseFile, } - got, err := a.doTLSRequest(a.GetInputJSONContent(), a.GetBootstrapURL(), false) + got, err := a.doTLSRequest(a.GetInputJSONContent(), tt.fields.BootstrapURL[0], false) if (err != nil) != tt.wantErr { t.Errorf("doTLSRequest() error = %v, wantErr %v", err, tt.wantErr) return