Files
talos-cloud-controller-manager/pkg/talos/cloud.go
Serge Logvinov 4b4c7587eb fix: service account name
Redefine the default service account name using environment variables.

Signed-off-by: Serge Logvinov <serge.logvinov@sinextra.dev>
2025-09-16 07:03:17 +07:00

166 lines
4.6 KiB
Go

// Package talos is an implementation of Interface and InstancesV2 for Talos.
package talos
import (
"context"
"fmt"
"io"
"os"
"github.com/siderolabs/talos-cloud-controller-manager/pkg/talosclient"
clientkubernetes "k8s.io/client-go/kubernetes"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/klog/v2"
)
const (
// ProviderName is the name of the Talos provider.
ProviderName = "talos"
// ServiceAccountName is the service account name used in kube-system namespace.
ServiceAccountName = "talos-cloud-controller-manager"
// ServiceAccountNameEnv is the environment variable for the service account name.
ServiceAccountNameEnv = "SERVICE_ACCOUNT"
// ClusterNameNodeLabel is the node label of cluster-name.
ClusterNameNodeLabel = "node.cloudprovider.kubernetes.io/clustername"
// ClusterNodePlatformLabel is the node label of platform name.
ClusterNodePlatformLabel = "node.cloudprovider.kubernetes.io/platform"
// ClusterNodeLifeCycleLabel is a life cycle type of compute node.
ClusterNodeLifeCycleLabel = "node.cloudprovider.kubernetes.io/lifecycle"
)
// Cloud is an implementation of cloudprovider interface for Talos CCM.
type Cloud struct {
client *client
instancesV2 cloudprovider.InstancesV2
ctx context.Context //nolint:containedctx
stop func()
}
type client struct {
config *cloudConfig
talos *talosclient.Client
kclient clientkubernetes.Interface
}
func init() {
cloudprovider.RegisterCloudProvider(ProviderName, func(config io.Reader) (cloudprovider.Interface, error) {
cfg, err := readCloudConfig(config)
if err != nil {
klog.ErrorS(err, "failed to read config")
return nil, err
}
return newCloud(&cfg)
})
}
func newCloud(config *cloudConfig) (cloudprovider.Interface, error) {
client, err := newClient(context.Background(), config)
if err != nil {
return nil, err
}
instancesInterface := newInstances(client)
return &Cloud{
client: client,
instancesV2: instancesInterface,
}, nil
}
func newClient(ctx context.Context, config *cloudConfig) (*client, error) {
if config == nil {
return nil, fmt.Errorf("talos cloudConfig is nil")
}
talos, err := talosclient.New(ctx)
if err != nil {
return nil, err
}
return &client{
config: config,
talos: talos,
}, nil
}
// Initialize provides the cloud with a kubernetes client builder and may spawn goroutines
// to perform housekeeping or run custom controllers specific to the cloud provider.
// Any tasks started here should be cleaned up when the stop channel closes.
func (c *Cloud) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stop <-chan struct{}) {
serviceAccountName := os.Getenv(ServiceAccountNameEnv)
if serviceAccountName == "" {
serviceAccountName = ServiceAccountName
}
c.client.kclient = clientBuilder.ClientOrDie(serviceAccountName)
klog.InfoS("clientset initialized")
ctx, cancel := context.WithCancel(context.Background())
c.ctx = ctx
c.stop = cancel
// Broadcast the upstream stop signal to all provider-level goroutines
// watching the provider's context for cancellation.
go func(provider *Cloud) {
<-stop
klog.V(3).InfoS("received cloud provider termination signal")
provider.stop()
}(c)
klog.InfoS("talos initialized")
}
// LoadBalancer returns a balancer interface.
// Also returns true if the interface is supported, false otherwise.
func (c *Cloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) {
return nil, false
}
// Instances returns an instances interface.
// Also returns true if the interface is supported, false otherwise.
func (c *Cloud) Instances() (cloudprovider.Instances, bool) {
return nil, false
}
// InstancesV2 is an implementation for instances and should only be implemented by external cloud providers.
// Implementing InstancesV2 is behaviorally identical to Instances but is optimized to significantly reduce
// API calls to the cloud provider when registering and syncing nodes.
// Also returns true if the interface is supported, false otherwise.
func (c *Cloud) InstancesV2() (cloudprovider.InstancesV2, bool) {
return c.instancesV2, c.instancesV2 != nil
}
// Zones returns a zones interface.
// Also returns true if the interface is supported, false otherwise.
func (c *Cloud) Zones() (cloudprovider.Zones, bool) {
return nil, false
}
// Clusters is not implemented.
func (c *Cloud) Clusters() (cloudprovider.Clusters, bool) {
return nil, false
}
// Routes is not implemented.
func (c *Cloud) Routes() (cloudprovider.Routes, bool) {
return nil, false
}
// ProviderName returns the cloud provider ID.
func (c *Cloud) ProviderName() string {
return ProviderName
}
// HasClusterID is not implemented.
func (c *Cloud) HasClusterID() bool {
return true
}