pkg/controller/elasticsearch/client/remote_cluster.go (122 lines of code) (raw):

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one // or more contributor license agreements. Licensed under the Elastic License 2.0; // you may not use this file except in compliance with the Elastic License 2.0. package client import ( "context" "fmt" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" esv1 "github.com/elastic/cloud-on-k8s/v3/pkg/apis/elasticsearch/v1" ) type RemoteClusterClient interface { // UpdateRemoteClusterSettings updates the remote clusters of a cluster. UpdateRemoteClusterSettings(context.Context, RemoteClustersSettings) error // GetRemoteClusterSettings retrieves the remote clusters of a cluster. GetRemoteClusterSettings(context.Context) (RemoteClustersSettings, error) // CreateCrossClusterAPIKey creates a new cross cluster API Key using the provided cross cluster API key request. CreateCrossClusterAPIKey(context.Context, CrossClusterAPIKeyCreateRequest) (CrossClusterAPIKeyCreateResponse, error) // UpdateCrossClusterAPIKey updates the cluster API Key which matches the provided ID using the provided update request. UpdateCrossClusterAPIKey(context.Context, string, CrossClusterAPIKeyUpdateRequest) (CrossClusterAPIKeyUpdateResponse, error) // InvalidateCrossClusterAPIKey invalidates a cluster API Key by its name. InvalidateCrossClusterAPIKey(context.Context, string) error // GetCrossClusterAPIKeys attempts to retrieve active Cross Cluster API Keys. // The provided string is used as the "name" parameter in the HTTP query. // Relies on the active_only parameter to only include active API Keys in the response. GetCrossClusterAPIKeys(context.Context, string) (CrossClusterAPIKeyList, error) } type CrossClusterAPIKeyInvalidateRequest struct { Name string `json:"name,omitempty"` } type CrossClusterAPIKeyCreateRequest struct { Name string `json:"name,omitempty"` CrossClusterAPIKeyUpdateRequest } type CrossClusterAPIKeyUpdateRequest struct { esv1.RemoteClusterAPIKey Metadata map[string]interface{} `json:"metadata,omitempty"` } type CrossClusterAPIKeyCreateResponse struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` APIKey string `json:"api_key,omitempty"` Encoded string `json:"encoded,omitempty"` } type CrossClusterAPIKeyUpdateResponse struct { Update string `json:"string,omitempty"` } type CrossClusterAPIKeyList struct { APIKeys []CrossClusterAPIKey `json:"api_keys,omitempty"` } func (cl *CrossClusterAPIKeyList) Len() int { if cl == nil { return 0 } return len(cl.APIKeys) } // GetActiveKeyWithName returns the first active key that matches the provided name or pattern. func (cl *CrossClusterAPIKeyList) GetActiveKeyWithName(name string) *CrossClusterAPIKey { if cl == nil || cl.Len() == 0 { return nil } for _, key := range cl.APIKeys { if key.Name == name { return &key } } return nil } // KeyNames extracts the key names from a list of keys. func (cl *CrossClusterAPIKeyList) KeyNames() sets.Set[string] { if cl == nil || cl.Len() == 0 { return nil } result := sets.New[string]() for _, key := range cl.APIKeys { result.Insert(key.Name) } return result } // ForCluster returns all the API keys related to a specific client cluster. func (cl *CrossClusterAPIKeyList) ForCluster(namespace string, name string) (*CrossClusterAPIKeyList, error) { if cl == nil || cl.APIKeys == nil { return nil, nil } crossClusterAPIKeyList := &CrossClusterAPIKeyList{ APIKeys: make([]CrossClusterAPIKey, 0, len(cl.APIKeys)), } for _, apiKey := range cl.APIKeys { elasticsearchName, err := apiKey.GetElasticsearchName() if err != nil { return nil, err } if elasticsearchName.Namespace == namespace && elasticsearchName.Name == name { crossClusterAPIKeyList.APIKeys = append(crossClusterAPIKeyList.APIKeys, apiKey) } } return crossClusterAPIKeyList, nil } type CrossClusterAPIKey struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` Metadata map[string]interface{} `json:"metadata,omitempty"` } // GetElasticsearchName returns the name of the client cluster for which this key has been created. func (c *CrossClusterAPIKey) GetElasticsearchName() (types.NamespacedName, error) { if c == nil { return types.NamespacedName{}, nil } esNameInMetadata, ok := c.Metadata["elasticsearch.k8s.elastic.co/name"] if !ok { return types.NamespacedName{}, fmt.Errorf("missing metadata in cross cluster API key: elasticsearch.k8s.elastic.co/name") } esNamespaceInMetadata, ok := c.Metadata["elasticsearch.k8s.elastic.co/namespace"] if !ok { return types.NamespacedName{}, fmt.Errorf("missing metadata in cross cluster API key: elasticsearch.k8s.elastic.co/namespace") } namespacedName := types.NamespacedName{} if esName, ok := esNameInMetadata.(string); ok { namespacedName.Name = esName } if esNamespace, ok := esNamespaceInMetadata.(string); ok { namespacedName.Namespace = esNamespace } return namespacedName, nil } // RemoteClustersSettings is used to build a request to update remote clusters. type RemoteClustersSettings struct { PersistentSettings *SettingsGroup `json:"persistent,omitempty"` } // SettingsGroup is a group of persistent settings. type SettingsGroup struct { Cluster RemoteClusters `json:"cluster,omitempty"` } // RemoteClusters models the configuration of the remote clusters. type RemoteClusters struct { RemoteClusters map[string]RemoteCluster `json:"remote,omitempty"` } // RemoteCluster is the set of seeds to use in a remote cluster setting. type RemoteCluster struct { Seeds []string `json:"seeds"` }