Repository: argoproj/argo-cd (Go)

Issue:
Unable to add multi cluster with IPv6 , secret name appending "[" with metadata.name from the server url
I am trying ArgoCD to add multiple IPv6 clusters for my POC. I followed the instructions from the docs page.
I ran the below commad
./cli-argocd cluster add  cntxtname  --name sp2 --kubeconfig sp2

I got below error
INFO[0002] ServiceAccount "argocd-manager" created in namespace "kube-system"
INFO[0002] ClusterRole "argocd-manager-role" created
INFO[0002] ClusterRoleBinding "argocd-manager-role-binding" created 
FATA[0003] rpc error: code = InvalidArgument desc = Secret "cluster-[240b-2849613443" is invalid: metadata.name: Invalid value: "cluster-[240b-2849613443": a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*') 

I could see  service account, cluster-role, cluster-role bindings are created in the target cluster.

Its very clear  bug is  with IPv6 when constructing secret name.

i could see the function URIToSecretName at util/db/secrets.go -> that is taking  input ("cluster", "http://foo") and converting to secretName like "cluster-foo-752281925"
![image](https://user-images.githubusercontent.com/30072921/149877346-5f6e777d-e024-4b71-a53b-97b555f24e4c.png)


In IPv6 case server url will be [240b:x:x:x:x:x:x:x] , its parsing with [240b which causing probelm.

here we need to replace "[" brackets for ipv6 cluster. 
I tried to change the code but it's not reflecting when i tested it. 



I could see one more function for appending "cluster-"
GenerateNewClusterManagerSecret function at /util/clusterauth/clusterauth.go line no 328.


![image](https://user-images.githubusercontent.com/30072921/149876349-3df4e9aa-08b5-4018-9a6e-e85a15c52f83.png)


**To Reproduce**
- one k8s ipv6 cluster where argocd is deployed.  no problem here. I am able to deploy applications.
- setup another  ipv6 k8s cluster
- download argocd cli 
- run ->  ./argocd-linux-amd64 cluster add  cntxtname  --name sp2 --kubeconfig sp2
- you will get below 
![image](https://user-images.githubusercontent.com/30072921/149875954-3e92d95a-16bf-4c18-a35d-2279243df289.png)



**Expected behavior**

Cluster added successfully.

**Screenshots**



**Version**

```shell
![image](https://user-images.githubusercontent.com/30072921/149876120-5196ab7a-f61b-48f9-b18c-2fbbc0669a54.png)

```
OS:
Red Hat Enterprise Linux 7"
argocd: v2.3.0+41fc70d.dirty
argocd-server: v2.2.2+03b17e0


```



Discussion:
I changed domain name in my kubeconfig instead of ipv6 IP [::] . able to add the cluster



Patch:
diff --git a/util/db/secrets.go b/util/db/secrets.go
index 8ff4721e22ab8..7021226c4bf4c 100644
--- a/util/db/secrets.go
+++ b/util/db/secrets.go
@@ -3,12 +3,14 @@ package db
 import (
 	"fmt"
 	"hash/fnv"
+	"net/netip"
 	"net/url"
 	"strconv"
 	"strings"
 	"time"
 
 	"context"
+
 	log "github.com/sirupsen/logrus"
 	apiv1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -155,8 +157,24 @@ func URIToSecretName(uriType, uri string) (string, error) {
 	if err != nil {
 		return "", err
 	}
+	host := parsedURI.Host
+	if strings.HasPrefix(host, "[") {
+		last := strings.Index(host, "]")
+		if last >= 0 {
+			addr, err := netip.ParseAddr(host[1:last])
+			if err != nil {
+				return "", err
+			}
+			host = strings.ReplaceAll(addr.String(), ":", "-")
+		}
+	} else {
+		last := strings.Index(host, ":")
+		if last >= 0 {
+			host = host[0:last]
+		}
+	}
 	h := fnv.New32a()
 	_, _ = h.Write([]byte(uri))
-	host := strings.ToLower(strings.Split(parsedURI.Host, ":")[0])
+	host = strings.ToLower(host)
 	return fmt.Sprintf("%s-%s-%v", uriType, host, h.Sum32()), nil
 }


Test patch:
diff --git a/util/db/cluster_test.go b/util/db/cluster_test.go
index 5d99edf83d05b..f2f3761318965 100644
--- a/util/db/cluster_test.go
+++ b/util/db/cluster_test.go
@@ -27,6 +27,26 @@ func Test_URIToSecretName(t *testing.T) {
 	name, err := URIToSecretName("cluster", "http://foo")
 	assert.NoError(t, err)
 	assert.Equal(t, "cluster-foo-752281925", name)
+
+	name, err = URIToSecretName("cluster", "http://thelongestdomainnameintheworld.argocd-project.com:3000")
+	assert.NoError(t, err)
+	assert.Equal(t, "cluster-thelongestdomainnameintheworld.argocd-project.com-2721640553", name)
+
+	name, err = URIToSecretName("cluster", "http://[fe80::1ff:fe23:4567:890a]")
+	assert.NoError(t, err)
+	assert.Equal(t, "cluster-fe80--1ff-fe23-4567-890a-3877258831", name)
+
+	name, err = URIToSecretName("cluster", "http://[fe80::1ff:fe23:4567:890a]:8000")
+	assert.NoError(t, err)
+	assert.Equal(t, "cluster-fe80--1ff-fe23-4567-890a-664858999", name)
+
+	name, err = URIToSecretName("cluster", "http://[FE80::1FF:FE23:4567:890A]:8000")
+	assert.NoError(t, err)
+	assert.Equal(t, "cluster-fe80--1ff-fe23-4567-890a-682802007", name)
+
+	name, err = URIToSecretName("cluster", "http://:/abc")
+	assert.NoError(t, err)
+	assert.Equal(t, "cluster--1969338796", name)
 }
 
 func Test_secretToCluster(t *testing.T) {