Skip to content

Commit

Permalink
Allow CNF Cert Suite app's go-clients to work in a k8s pod. (#1543)
Browse files Browse the repository at this point in the history
This change will allow the go-clients to be initialized properly in case
the app is running inside a pod in a k8s/OCP cluster.

The method rest.InClusterConfig() reads the pod's SA tokens/creentials
and returns a rest.Config struct that can be used to initialize all the
go-clients.

If that method returns an error, it assumes it's running outside a
cluster, using the provided filenames to create the rest.Config.
  • Loading branch information
greyerof authored Oct 20, 2023
1 parent 5873d16 commit 5e3f749
Showing 1 changed file with 72 additions and 16 deletions.
88 changes: 72 additions & 16 deletions internal/clientsholder/clientsholder.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package clientsholder

import (
"errors"
"fmt"
"time"

Expand Down Expand Up @@ -164,29 +165,66 @@ func createByteArrayKubeConfig(kubeConfig *clientcmdapi.Config) ([]byte, error)
return yamlBytes, nil
}

// GetClientsHolder instantiate an ocp client
func newClientsHolder(filenames ...string) (*ClientsHolder, error) { //nolint:funlen // this is a special function with lots of assignments
logrus.Infof("Creating k8s go-clients holder.")
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
// Creates a clientcmdapi.Config object from a rest.Config.
// Based on https://github.com/kubernetes/client-go/issues/711#issuecomment-1666075787
func GetClientConfigFromRestConfig(restConfig *rest.Config) *clientcmdapi.Config {
return &clientcmdapi.Config{
Kind: "Config",
APIVersion: "v1",
Clusters: map[string]*clientcmdapi.Cluster{
"default-cluster": {
Server: restConfig.Host,
CertificateAuthority: restConfig.TLSClientConfig.CAFile,
},
},
Contexts: map[string]*clientcmdapi.Context{
"default-context": {
Cluster: "default-cluster",
AuthInfo: "default-user",
},
},
CurrentContext: "default-context",
AuthInfos: map[string]*clientcmdapi.AuthInfo{
"default-user": {
Token: restConfig.BearerToken,
},
},
}
}

precedence := []string{}
if len(filenames) > 0 {
precedence = append(precedence, filenames...)
func getClusterRestConfig(filenames ...string) (*rest.Config, error) {
restConfig, err := rest.InClusterConfig()
if err == nil {
logrus.Infof("CNF Cert Suite is running inside a cluster.")

// Convert restConfig to clientcmdapi.Config so we can get the kubeconfig "file" bytes
// needed by preflight's operator checks.
clientConfig := GetClientConfigFromRestConfig(restConfig)
clientsHolder.KubeConfig, err = createByteArrayKubeConfig(clientConfig)
if err != nil {
return nil, fmt.Errorf("failed to create byte array from kube config reference: %v", err)
}

// No error: we're inside a cluster.
return restConfig, nil
}

logrus.Infof("Running outside a cluster. Parsing kubeconfig file/s %+v", filenames)
if len(filenames) == 0 {
return nil, errors.New("no kubeconfig files set")
}

// Get the rest.Config from the kubeconfig file/s.
precedence := []string{}
precedence = append(precedence, filenames...)

loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
loadingRules.Precedence = precedence
configOverrides := &clientcmd.ConfigOverrides{}

kubeconfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
loadingRules,
configOverrides,
&clientcmd.ConfigOverrides{},
)
// Get a rest.Config from the kubeconfig file. This will be passed into all
// the client objects we create.
var err error
clientsHolder.RestConfig, err = kubeconfig.ClientConfig()
if err != nil {
return nil, fmt.Errorf("cannot instantiate rest config: %s", err)
}

// Save merged config to temporary kubeconfig file.
kubeRawConfig, err := kubeconfig.RawConfig()
Expand All @@ -199,6 +237,24 @@ func newClientsHolder(filenames ...string) (*ClientsHolder, error) { //nolint:fu
return nil, fmt.Errorf("failed to byte array kube config reference: %w", err)
}

restConfig, err = kubeconfig.ClientConfig()
if err != nil {
return nil, fmt.Errorf("cannot instantiate rest config: %s", err)
}

return restConfig, nil
}

// GetClientsHolder instantiate an ocp client
func newClientsHolder(filenames ...string) (*ClientsHolder, error) { //nolint:funlen // this is a special function with lots of assignments
logrus.Infof("Creating k8s go-clients holder.")

var err error
clientsHolder.RestConfig, err = getClusterRestConfig(filenames...)
if err != nil {
return nil, fmt.Errorf("failed to get rest.Config: %v", err)
}

DefaultTimeout := 10 * time.Second
clientsHolder.RestConfig.Timeout = DefaultTimeout

Expand Down

0 comments on commit 5e3f749

Please sign in to comment.