Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions cmd/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"log"
"maps"
Expand Down Expand Up @@ -154,10 +155,24 @@ func buildIncomingKubeconfig(items []v1alpha1.ClusterKubeconfig) (*clientcmdapi.

if len(ckc.Spec.Kubeconfig.Clusters) > 0 {
clusterItem := ckc.Spec.Kubeconfig.Clusters[0]

kubeconfig.Clusters[clusterItem.Name] = &clientcmdapi.Cluster{
Server: clusterItem.Cluster.Server,
CertificateAuthorityData: clusterItem.Cluster.CertificateAuthorityData,
}

// Add/overwrite a "labels" named extension with the labels from the ClusterKubeconfig metadata.
if len(ckc.Labels) > 0 {
labelsJSON, err := json.Marshal(ckc.Labels)
if err != nil {
return nil, fmt.Errorf("failed to marshal labels for cluster %q: %w", clusterItem.Name, err)
}
if kubeconfig.Clusters[clusterItem.Name].Extensions == nil {
kubeconfig.Clusters[clusterItem.Name].Extensions = map[string]runtime.Object{}
}
kubeconfig.Clusters[clusterItem.Name].Extensions["labels"] = &runtime.Unknown{Raw: labelsJSON}
}

}
}

Expand Down Expand Up @@ -267,9 +282,10 @@ func mergeKubeconfig(localConfig *clientcmdapi.Config, serverConfig *clientcmdap
// Add the managed cluster from serverConfig to localConfig
localConfig.Clusters[managedName] = serverCluster
} else {
// Check if Server or CertificateAuthorityData has changed
// Check if Server, CertificateAuthorityData or the labels extension has changed
if localCluster.Server != serverCluster.Server ||
!bytes.Equal(localCluster.CertificateAuthorityData, serverCluster.CertificateAuthorityData) {
!bytes.Equal(localCluster.CertificateAuthorityData, serverCluster.CertificateAuthorityData) ||
!labelsExtensionEqual(localCluster.Extensions, serverCluster.Extensions) {
localConfig.Clusters[managedName] = serverCluster
}
}
Expand Down Expand Up @@ -468,6 +484,34 @@ func mergeAuthInfo(serverAuth, localAuth *clientcmdapi.AuthInfo) *clientcmdapi.A
return mergedAuth
}

// labelsExtensionEqual returns true if the \"labels\" named extension is equal in both maps.
func labelsExtensionEqual(a, b map[string]runtime.Object) bool {
ar := extensionRaw(a, "labels")
br := extensionRaw(b, "labels")
return bytes.Equal(ar, br)
}

// extensionRaw extracts the raw JSON bytes for the given extension name, if present.
func extensionRaw(m map[string]runtime.Object, name string) []byte {
if m == nil {
return nil
}
obj, ok := m[name]
if !ok || obj == nil {
return nil
}
switch t := obj.(type) {
case *runtime.Unknown:
return bytes.TrimSpace(t.Raw)
default:
b, err := json.Marshal(t)
if err != nil {
return nil
}
return bytes.TrimSpace(b)
}
}

func configWithContext(context, kubeconfigPath string) (*rest.Config, error) {
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
Expand Down
Loading