diff --git a/.gitlab/ci/.test.yml b/.gitlab/ci/.test.yml index 99ea33631f607a038a048980053d81213e401721..7bc08f6a1fd374b8020e524c6a5a65574bd5e356 100644 --- a/.gitlab/ci/.test.yml +++ b/.gitlab/ci/.test.yml @@ -39,3 +39,11 @@ integration-test-gosdn: script: - go test -p 1 ./integration-tests/* <<: *test + +unit-test: + image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/golang:$GOLANG_VERSION-bookworm + before_script: + - apt update && apt install -y make + script: + - make unit-test-new + <<: *test diff --git a/Makefile b/Makefile index 0a27ad738954590c14fa0d9c3785e88a80921998..bdd980b1c2536c0635118a9dee2dbb5c50307afc 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,9 @@ integration-tests-debug-up: generate-certs containerize-gosdn containerize-plugi integration-tests-debug-down: docker-compose -f dev_env_data/docker-compose/integration-test_docker-compose.yml down +unit-test-new: install-tools + go test ./cli/... + # Warning: Depending on your go and development configuration might also clean caches, modules and docker containers from your other projects. clean: rm -rf $(BUILD_ARTIFACTS_PATH) diff --git a/cli/cmd/networkElementCreate.go b/cli/cmd/networkElementCreate.go index 121c732388818ed247e17d19096fb53277b65966..5aa2397bc9531fb999981ba807078ee00d068861 100644 --- a/cli/cmd/networkElementCreate.go +++ b/cli/cmd/networkElementCreate.go @@ -49,7 +49,7 @@ if they diverge from the default credentials (user:'admin' and pw:'arista').`, Run: func(cmd *cobra.Command, args []string) { spinner, _ := pterm.DefaultSpinner.Start("Creating new network element") - err := checkIPPort(address) + err := checkIPorHostnameAndPort(address) if err != nil { spinner.Fail(err) return diff --git a/cli/cmd/utils.go b/cli/cmd/utils.go index ca51618da5b45ff5fde1c0691adeab6c9664498e..cbf9a81df5f3834c5c79ae793d83e61be8e1d21e 100644 --- a/cli/cmd/utils.go +++ b/cli/cmd/utils.go @@ -41,19 +41,27 @@ import ( gpb "github.com/openconfig/gnmi/proto/gnmi" gnmiv "github.com/openconfig/gnmi/value" "github.com/openconfig/goyang/pkg/yang" + "golang.org/x/net/idna" "google.golang.org/grpc/metadata" ) -func checkIPPort(string) error { +func checkIPorHostnameAndPort(address string) error { // check if address is in the format <IP>:<port> - ip, _, err := net.SplitHostPort(address) - if err != nil { - return err + ipOrHostname, _, err := net.SplitHostPort(address) + if err != nil || ipOrHostname == "" { + errorMessage := fmt.Sprintf("address '%s' is not in the format <IP/Hostname>:<port>", address) + return errors.New(errorMessage) } - // Check IP - ip2 := net.ParseIP(ip) - if ip2 == nil { - return errors.New("invalid IP") + + // If not IP, check if valid Hostname + _, err = idna.Lookup.ToASCII(ipOrHostname) + if err != nil { + // Check if valid ipIP + ip2 := net.ParseIP(ipOrHostname) + if ip2 == nil { + errorMessage := fmt.Sprintf("address '%s' is neither a valid IP nor a hostname", ipOrHostname) + return errors.New(errorMessage) + } } return nil } diff --git a/cli/cmd/utils_test.go b/cli/cmd/utils_test.go new file mode 100644 index 0000000000000000000000000000000000000000..72fa690d9f96d7f72f411efb8e212ff006240715 --- /dev/null +++ b/cli/cmd/utils_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "testing" +) + +func TestCheckIPorHostnameAndPort(t *testing.T) { + // Test cases for valid IP addresses or hostnames with ports + validCases := []string{ + "127.0.0.1:8080", + "localhost:8080", + "example.com:8080", + "[::1]:8080", + "[2001:db8::1]:1234", + "256.256.256.900:1234", // Looks weird, but is valid as a hostname. + } + + for _, addr := range validCases { + err := checkIPorHostnameAndPort(addr) + if err != nil { + t.Errorf("Expected no error for address %s, but got: %v", addr, err) + } + } +} + +func TestCheckIPorHostnameAndPortInvalid(t *testing.T) { + // Test cases for invalid IP addresses or hostnames with ports + invalidCases := []string{ + ":8080", // Missing IP address or hostname + "example.com", // Missing port + } + + for _, addr := range invalidCases { + err := checkIPorHostnameAndPort(addr) + if err == nil { + t.Errorf("Expected error for address %s, but got no error", addr) + } + } +}