mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-06-06 21:59:12 -04:00
Create Kubernetes clients from bytes instead of filepath (#2663)
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
4d6a7fa759
commit
a9cc9d8bbc
9 changed files with 94 additions and 33 deletions
|
@ -224,10 +224,18 @@ func runApply(cmd *cobra.Command, _ []string) error {
|
||||||
return dialer.New(nil, validator, &net.Dialer{})
|
return dialer.New(nil, validator, &net.Dialer{})
|
||||||
}
|
}
|
||||||
newKubeUpgrader := func(w io.Writer, kubeConfigPath string, log debugLog) (kubernetesUpgrader, error) {
|
newKubeUpgrader := func(w io.Writer, kubeConfigPath string, log debugLog) (kubernetesUpgrader, error) {
|
||||||
return kubecmd.New(w, kubeConfigPath, fileHandler, log)
|
kubeConfig, err := fileHandler.Read(kubeConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("reading kubeconfig: %w", err)
|
||||||
|
}
|
||||||
|
return kubecmd.New(w, kubeConfig, fileHandler, log)
|
||||||
}
|
}
|
||||||
newHelmClient := func(kubeConfigPath string, log debugLog) (helmApplier, error) {
|
newHelmClient := func(kubeConfigPath string, log debugLog) (helmApplier, error) {
|
||||||
return helm.NewClient(kubeConfigPath, log)
|
kubeConfig, err := fileHandler.Read(kubeConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("reading kubeconfig: %w", err)
|
||||||
|
}
|
||||||
|
return helm.NewClient(kubeConfig, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeID := generateUpgradeID(upgradeCmdKindApply)
|
upgradeID := generateUpgradeID(upgradeCmdKindApply)
|
||||||
|
|
|
@ -47,7 +47,12 @@ func runStatus(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
||||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||||
|
|
||||||
helmClient, err := helm.NewReleaseVersionClient(constants.AdminConfFilename, log)
|
kubeConfig, err := fileHandler.Read(constants.AdminConfFilename)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("reading kubeconfig: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
helmClient, err := helm.NewReleaseVersionClient(kubeConfig, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("setting up helm client: %w", err)
|
return fmt.Errorf("setting up helm client: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +61,7 @@ func runStatus(cmd *cobra.Command, _ []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
fetcher := attestationconfigapi.NewFetcher()
|
fetcher := attestationconfigapi.NewFetcher()
|
||||||
kubeClient, err := kubecmd.New(cmd.OutOrStdout(), constants.AdminConfFilename, fileHandler, log)
|
kubeClient, err := kubecmd.New(cmd.OutOrStdout(), kubeConfig, fileHandler, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("setting up kubernetes client: %w", err)
|
return fmt.Errorf("setting up kubernetes client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,10 +116,18 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
||||||
}
|
}
|
||||||
defer cleanUp()
|
defer cleanUp()
|
||||||
|
|
||||||
kubeChecker, err := kubecmd.New(cmd.OutOrStdout(), constants.AdminConfFilename, fileHandler, log)
|
kubeConfig, err := fileHandler.Read(constants.AdminConfFilename)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("reading kubeconfig: %w", err)
|
||||||
|
}
|
||||||
|
kubeChecker, err := kubecmd.New(cmd.OutOrStdout(), kubeConfig, fileHandler, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("setting up Kubernetes upgrader: %w", err)
|
return fmt.Errorf("setting up Kubernetes upgrader: %w", err)
|
||||||
}
|
}
|
||||||
|
helmClient, err := helm.NewReleaseVersionClient(kubeConfig, log)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("setting up helm client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
versionfetcher := versionsapi.NewFetcher()
|
versionfetcher := versionsapi.NewFetcher()
|
||||||
rekor, err := sigstore.NewRekor()
|
rekor, err := sigstore.NewRekor()
|
||||||
|
@ -137,6 +145,7 @@ func runUpgradeCheck(cmd *cobra.Command, _ []string) error {
|
||||||
rekor: rekor,
|
rekor: rekor,
|
||||||
flags: flags,
|
flags: flags,
|
||||||
cliVersion: constants.BinaryVersion(),
|
cliVersion: constants.BinaryVersion(),
|
||||||
|
helmClient: helmClient,
|
||||||
log: log,
|
log: log,
|
||||||
versionsapi: versionfetcher,
|
versionsapi: versionfetcher,
|
||||||
},
|
},
|
||||||
|
@ -327,6 +336,7 @@ type versionCollector struct {
|
||||||
flags upgradeCheckFlags
|
flags upgradeCheckFlags
|
||||||
versionsapi versionFetcher
|
versionsapi versionFetcher
|
||||||
cliVersion consemver.Semver
|
cliVersion consemver.Semver
|
||||||
|
helmClient *helm.ReleaseVersionClient
|
||||||
log debugLog
|
log debugLog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,12 +378,7 @@ type currentVersionInfo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *versionCollector) currentVersions(ctx context.Context) (currentVersionInfo, error) {
|
func (v *versionCollector) currentVersions(ctx context.Context) (currentVersionInfo, error) {
|
||||||
helmClient, err := helm.NewReleaseVersionClient(constants.AdminConfFilename, v.log)
|
serviceVersions, err := v.helmClient.Versions()
|
||||||
if err != nil {
|
|
||||||
return currentVersionInfo{}, fmt.Errorf("setting up helm client: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceVersions, err := helmClient.Versions()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentVersionInfo{}, fmt.Errorf("getting service versions: %w", err)
|
return currentVersionInfo{}, fmt.Errorf("getting service versions: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,13 +473,18 @@ go_library(
|
||||||
"//internal/state",
|
"//internal/state",
|
||||||
"//internal/versions",
|
"//internal/versions",
|
||||||
"@com_github_pkg_errors//:errors",
|
"@com_github_pkg_errors//:errors",
|
||||||
|
"@io_k8s_apimachinery//pkg/api/meta",
|
||||||
|
"@io_k8s_client_go//discovery",
|
||||||
|
"@io_k8s_client_go//discovery/cached/memory",
|
||||||
|
"@io_k8s_client_go//rest",
|
||||||
|
"@io_k8s_client_go//restmapper",
|
||||||
|
"@io_k8s_client_go//tools/clientcmd",
|
||||||
"@io_k8s_client_go//util/retry",
|
"@io_k8s_client_go//util/retry",
|
||||||
"@sh_helm_helm//pkg/ignore",
|
"@sh_helm_helm//pkg/ignore",
|
||||||
"@sh_helm_helm_v3//pkg/action",
|
"@sh_helm_helm_v3//pkg/action",
|
||||||
"@sh_helm_helm_v3//pkg/chart",
|
"@sh_helm_helm_v3//pkg/chart",
|
||||||
"@sh_helm_helm_v3//pkg/chart/loader",
|
"@sh_helm_helm_v3//pkg/chart/loader",
|
||||||
"@sh_helm_helm_v3//pkg/chartutil",
|
"@sh_helm_helm_v3//pkg/chartutil",
|
||||||
"@sh_helm_helm_v3//pkg/cli",
|
|
||||||
"@sh_helm_helm_v3//pkg/release",
|
"@sh_helm_helm_v3//pkg/release",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,9 +14,14 @@ import (
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
|
"k8s.io/client-go/discovery"
|
||||||
|
"k8s.io/client-go/discovery/cached/memory"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
"k8s.io/client-go/restmapper"
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
|
||||||
"helm.sh/helm/v3/pkg/action"
|
"helm.sh/helm/v3/pkg/action"
|
||||||
"helm.sh/helm/v3/pkg/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const applyRetryInterval = 30 * time.Second
|
const applyRetryInterval = 30 * time.Second
|
||||||
|
@ -29,12 +34,9 @@ type applyAction interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newActionConfig creates a new action configuration for helm actions.
|
// newActionConfig creates a new action configuration for helm actions.
|
||||||
func newActionConfig(kubeconfig string, logger debugLog) (*action.Configuration, error) {
|
func newActionConfig(kubeConfig []byte, logger debugLog) (*action.Configuration, error) {
|
||||||
settings := cli.New()
|
|
||||||
settings.KubeConfig = kubeconfig
|
|
||||||
|
|
||||||
actionConfig := &action.Configuration{}
|
actionConfig := &action.Configuration{}
|
||||||
if err := actionConfig.Init(settings.RESTClientGetter(), constants.HelmNamespace,
|
if err := actionConfig.Init(&clientGetter{kubeConfig: kubeConfig}, constants.HelmNamespace,
|
||||||
"secret", logger.Debugf); err != nil {
|
"secret", logger.Debugf); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -180,3 +182,43 @@ func saveChart(release release, chartsDir string, fileHandler file.Handler) erro
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clientGetter implements the genericclioptions.RESTClientGetter interface.
|
||||||
|
// We implement our own to allow creating clients from an in-memory kubeconfig.
|
||||||
|
type clientGetter struct {
|
||||||
|
kubeConfig []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRESTConfig implements the genericclioptions.RESTClientGetter interface.
|
||||||
|
func (c *clientGetter) ToRESTConfig() (*rest.Config, error) {
|
||||||
|
return clientcmd.RESTConfigFromKubeConfig(c.kubeConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDiscoveryClient implements the genericclioptions.RESTClientGetter interface.
|
||||||
|
func (c *clientGetter) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
|
||||||
|
config, err := c.ToRESTConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return memory.NewMemCacheClient(discoveryClient), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRESTMapper implements the genericclioptions.RESTClientGetter interface.
|
||||||
|
func (c *clientGetter) ToRESTMapper() (meta.RESTMapper, error) {
|
||||||
|
discoveryClient, err := c.ToDiscoveryClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient)
|
||||||
|
expander := restmapper.NewShortcutExpander(mapper, discoveryClient)
|
||||||
|
return expander, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRawKubeConfigLoader implements the genericclioptions.RESTClientGetter interface.
|
||||||
|
func (c *clientGetter) ToRawKubeConfigLoader() clientcmd.ClientConfig {
|
||||||
|
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(&clientcmd.ClientConfigLoadingRules{}, &clientcmd.ConfigOverrides{})
|
||||||
|
}
|
||||||
|
|
|
@ -61,12 +61,12 @@ type Client struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient returns a new Helm client.
|
// NewClient returns a new Helm client.
|
||||||
func NewClient(kubeConfigPath string, log debugLog) (*Client, error) {
|
func NewClient(kubeConfig []byte, log debugLog) (*Client, error) {
|
||||||
kubeClient, err := kubectl.NewFromConfig(kubeConfigPath)
|
kubeClient, err := kubectl.NewFromConfig(kubeConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("initializing kubectl: %w", err)
|
return nil, fmt.Errorf("initializing kubectl: %w", err)
|
||||||
}
|
}
|
||||||
actionConfig, err := newActionConfig(kubeConfigPath, log)
|
actionConfig, err := newActionConfig(kubeConfig, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating action config: %w", err)
|
return nil, fmt.Errorf("creating action config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ type ReleaseVersionClient struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReleaseVersionClient creates a new ReleaseVersionClient.
|
// NewReleaseVersionClient creates a new ReleaseVersionClient.
|
||||||
func NewReleaseVersionClient(kubeConfigPath string, log debugLog) (*ReleaseVersionClient, error) {
|
func NewReleaseVersionClient(kubeConfig []byte, log debugLog) (*ReleaseVersionClient, error) {
|
||||||
config, err := newActionConfig(kubeConfigPath, log)
|
config, err := newActionConfig(kubeConfig, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,8 +81,8 @@ type KubeCmd struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new KubeCmd.
|
// New returns a new KubeCmd.
|
||||||
func New(outWriter io.Writer, kubeConfigPath string, fileHandler file.Handler, log debugLog) (*KubeCmd, error) {
|
func New(outWriter io.Writer, kubeConfig []byte, fileHandler file.Handler, log debugLog) (*KubeCmd, error) {
|
||||||
client, err := kubectl.NewFromConfig(kubeConfigPath)
|
client, err := kubectl.NewFromConfig(kubeConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating kubectl client: %w", err)
|
return nil, fmt.Errorf("creating kubectl client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,14 +48,10 @@ func NewUninitialized() *Kubectl {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFromConfig returns a Kubectl client using the given kubeconfig.
|
// NewFromConfig returns a Kubectl client using the given kubeconfig.
|
||||||
func NewFromConfig(kubeconfigPath string) (*Kubectl, error) {
|
func NewFromConfig(kubeconfig []byte) (*Kubectl, error) {
|
||||||
clientConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
|
k := NewUninitialized()
|
||||||
if err != nil {
|
if err := k.Initialize(kubeconfig); err != nil {
|
||||||
return nil, fmt.Errorf("creating k8s client from kubeconfig: %w", err)
|
return nil, err
|
||||||
}
|
|
||||||
k := &Kubectl{}
|
|
||||||
if err := k.initialize(clientConfig); err != nil {
|
|
||||||
return nil, fmt.Errorf("initializing kubectl: %w", err)
|
|
||||||
}
|
}
|
||||||
return k, nil
|
return k, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue