From 3637909a46c055b82fcf86fbfd9a996691480051 Mon Sep 17 00:00:00 2001 From: Leonard Cohnen Date: Fri, 6 Jan 2023 12:04:36 +0100 Subject: [PATCH] internal: move components into their own package --- bootstrapper/cmd/bootstrapper/test.go | 6 +- .../internal/initserver/initserver.go | 6 +- .../internal/initserver/initserver_test.go | 4 +- bootstrapper/internal/joinclient/client.go | 6 +- .../internal/joinclient/client_test.go | 4 +- .../internal/kubernetes/k8sapi/k8sutil.go | 6 +- bootstrapper/internal/kubernetes/k8sutil.go | 4 +- .../internal/kubernetes/kubernetes.go | 8 +- .../internal/kubernetes/kubernetes_test.go | 7 +- internal/installer/install.go | 4 +- internal/installer/install_test.go | 12 +-- internal/versions/components/components.go | 90 +++++++++++++++++++ internal/versions/versions.go | 77 ++-------------- joinservice/internal/kubernetes/kubernetes.go | 14 +-- joinservice/internal/server/server.go | 4 +- joinservice/internal/server/server_test.go | 24 ++--- upgrade-agent/server.go | 11 +-- upgrade-agent/server_test.go | 4 +- 18 files changed, 156 insertions(+), 135 deletions(-) create mode 100644 internal/versions/components/components.go diff --git a/bootstrapper/cmd/bootstrapper/test.go b/bootstrapper/cmd/bootstrapper/test.go index 0d9917350..774e22d3c 100644 --- a/bootstrapper/cmd/bootstrapper/test.go +++ b/bootstrapper/cmd/bootstrapper/test.go @@ -12,7 +12,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/cloud/metadata" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/role" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" ) @@ -22,13 +22,13 @@ type clusterFake struct{} // InitCluster fakes bootstrapping a new cluster with the current node being the master, returning the arguments required to join the cluster. func (c *clusterFake) InitCluster( context.Context, string, string, []byte, []uint32, bool, []byte, bool, - []byte, bool, versions.ComponentVersions, *logger.Logger, + []byte, bool, components.Components, *logger.Logger, ) ([]byte, error) { return []byte{}, nil } // JoinCluster will fake joining the current node to an existing cluster. -func (c *clusterFake) JoinCluster(context.Context, *kubeadm.BootstrapTokenDiscovery, role.Role, string, versions.ComponentVersions, *logger.Logger) error { +func (c *clusterFake) JoinCluster(context.Context, *kubeadm.BootstrapTokenDiscovery, role.Role, string, components.Components, *logger.Logger) error { return nil } diff --git a/bootstrapper/internal/initserver/initserver.go b/bootstrapper/internal/initserver/initserver.go index fb01b000f..3ba282412 100644 --- a/bootstrapper/internal/initserver/initserver.go +++ b/bootstrapper/internal/initserver/initserver.go @@ -25,7 +25,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/nodestate" "github.com/edgelesssys/constellation/v2/internal/role" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "go.uber.org/zap" "golang.org/x/crypto/bcrypt" "google.golang.org/grpc" @@ -150,7 +150,7 @@ func (s *Server) Init(ctx context.Context, req *initproto.InitRequest) (*initpro s.issuerWrapper.VMType() == vmtype.AzureCVM, req.HelmDeployments, req.ConformanceMode, - versions.NewComponentVersionsFromInitProto(req.KubernetesComponents), + components.NewComponentsFromInitProto(req.KubernetesComponents), s.log, ) if err != nil { @@ -251,7 +251,7 @@ type ClusterInitializer interface { azureCVM bool, helmDeployments []byte, conformanceMode bool, - kubernetesComponents versions.ComponentVersions, + kubernetesComponents components.Components, log *logger.Logger, ) ([]byte, error) } diff --git a/bootstrapper/internal/initserver/initserver_test.go b/bootstrapper/internal/initserver/initserver_test.go index 85b8b2f36..0e493890f 100644 --- a/bootstrapper/internal/initserver/initserver_test.go +++ b/bootstrapper/internal/initserver/initserver_test.go @@ -19,7 +19,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/crypto/testvector" "github.com/edgelesssys/constellation/v2/internal/file" "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -302,7 +302,7 @@ type stubClusterInitializer struct { func (i *stubClusterInitializer) InitCluster( context.Context, string, string, []byte, []uint32, bool, []byte, bool, - []byte, bool, versions.ComponentVersions, *logger.Logger, + []byte, bool, components.Components, *logger.Logger, ) ([]byte, error) { return i.initClusterKubeconfig, i.initClusterErr } diff --git a/bootstrapper/internal/joinclient/client.go b/bootstrapper/internal/joinclient/client.go index 3e974acd8..8c96dfaa2 100644 --- a/bootstrapper/internal/joinclient/client.go +++ b/bootstrapper/internal/joinclient/client.go @@ -25,7 +25,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/nodestate" "github.com/edgelesssys/constellation/v2/internal/role" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/edgelesssys/constellation/v2/joinservice/joinproto" "github.com/spf13/afero" "go.uber.org/zap" @@ -287,7 +287,7 @@ func (c *JoinClient) startNodeAndJoin(ticket *joinproto.IssueJoinTicketResponse, Token: ticket.Token, CACertHashes: []string{ticket.DiscoveryTokenCaCertHash}, } - k8sComponents := versions.NewComponentVersionsFromJoinProto(ticket.KubernetesComponents) + k8sComponents := components.NewComponentsFromJoinProto(ticket.KubernetesComponents) if err := c.joiner.JoinCluster(ctx, btd, c.role, ticket.KubernetesVersion, k8sComponents, c.log); err != nil { return fmt.Errorf("joining Kubernetes cluster: %w", err) @@ -402,7 +402,7 @@ type ClusterJoiner interface { args *kubeadm.BootstrapTokenDiscovery, peerRole role.Role, k8sVersion string, - k8sComponents versions.ComponentVersions, + k8sComponents components.Components, log *logger.Logger, ) error } diff --git a/bootstrapper/internal/joinclient/client_test.go b/bootstrapper/internal/joinclient/client_test.go index 61d78a820..81dad0f8f 100644 --- a/bootstrapper/internal/joinclient/client_test.go +++ b/bootstrapper/internal/joinclient/client_test.go @@ -23,7 +23,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/grpc/testdialer" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/role" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/edgelesssys/constellation/v2/joinservice/joinproto" "github.com/spf13/afero" "github.com/stretchr/testify/assert" @@ -393,7 +393,7 @@ type stubClusterJoiner struct { joinClusterErr error } -func (j *stubClusterJoiner) JoinCluster(context.Context, *kubeadm.BootstrapTokenDiscovery, role.Role, string, versions.ComponentVersions, *logger.Logger) error { +func (j *stubClusterJoiner) JoinCluster(context.Context, *kubeadm.BootstrapTokenDiscovery, role.Role, string, components.Components, *logger.Logger) error { j.joinClusterCalled = true return j.joinClusterErr } diff --git a/bootstrapper/internal/kubernetes/k8sapi/k8sutil.go b/bootstrapper/internal/kubernetes/k8sapi/k8sutil.go index 7eae067f0..916dc7366 100644 --- a/bootstrapper/internal/kubernetes/k8sapi/k8sutil.go +++ b/bootstrapper/internal/kubernetes/k8sapi/k8sutil.go @@ -26,6 +26,7 @@ import ( "github.com/edgelesssys/constellation/v2/bootstrapper/internal/kubernetes/k8sapi/resources" "github.com/edgelesssys/constellation/v2/internal/constants" "github.com/edgelesssys/constellation/v2/internal/role" + "github.com/edgelesssys/constellation/v2/internal/versions/components" corev1 "k8s.io/api/core/v1" kubeconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" @@ -33,7 +34,6 @@ import ( "github.com/edgelesssys/constellation/v2/internal/file" "github.com/edgelesssys/constellation/v2/internal/installer" "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/edgelesssys/constellation/v2/internal/versions" "github.com/spf13/afero" "go.uber.org/zap" ) @@ -57,7 +57,7 @@ type Client interface { type componentsInstaller interface { Install( - ctx context.Context, kubernetesComponent versions.ComponentVersion, + ctx context.Context, kubernetesComponent components.Component, ) error } @@ -76,7 +76,7 @@ func NewKubernetesUtil() *KubernetesUtil { } // InstallComponents installs the kubernetes components passed from the CLI. -func (k *KubernetesUtil) InstallComponents(ctx context.Context, kubernetesComponents versions.ComponentVersions) error { +func (k *KubernetesUtil) InstallComponents(ctx context.Context, kubernetesComponents components.Components) error { for _, component := range kubernetesComponents { if err := k.inst.Install(ctx, component); err != nil { return fmt.Errorf("installing kubernetes component from URL %s: %w", component.URL, err) diff --git a/bootstrapper/internal/kubernetes/k8sutil.go b/bootstrapper/internal/kubernetes/k8sutil.go index 52d733d1a..0ed17e0da 100644 --- a/bootstrapper/internal/kubernetes/k8sutil.go +++ b/bootstrapper/internal/kubernetes/k8sutil.go @@ -14,11 +14,11 @@ import ( "github.com/edgelesssys/constellation/v2/internal/deploy/helm" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/role" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" ) type clusterUtil interface { - InstallComponents(ctx context.Context, kubernetesComponents versions.ComponentVersions) error + InstallComponents(ctx context.Context, kubernetesComponents components.Components) error InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) error JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error FixCilium(log *logger.Logger) diff --git a/bootstrapper/internal/kubernetes/kubernetes.go b/bootstrapper/internal/kubernetes/kubernetes.go index e24323d8f..32a0ab62b 100644 --- a/bootstrapper/internal/kubernetes/kubernetes.go +++ b/bootstrapper/internal/kubernetes/kubernetes.go @@ -29,7 +29,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/deploy/helm" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/role" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/spf13/afero" "go.uber.org/zap" corev1 "k8s.io/api/core/v1" @@ -90,7 +90,7 @@ func New(cloudProvider string, clusterUtil clusterUtil, configProvider configura func (k *KubeWrapper) InitCluster( ctx context.Context, cloudServiceAccountURI, versionString string, measurementSalt []byte, enforcedPCRs []uint32, enforceIDKeyDigest bool, idKeyDigest []byte, azureCVM bool, - helmReleasesRaw []byte, conformanceMode bool, kubernetesComponents versions.ComponentVersions, log *logger.Logger, + helmReleasesRaw []byte, conformanceMode bool, kubernetesComponents components.Components, log *logger.Logger, ) ([]byte, error) { log.With(zap.String("version", versionString)).Infof("Installing Kubernetes components") if err := k.clusterUtil.InstallComponents(ctx, kubernetesComponents); err != nil { @@ -255,7 +255,7 @@ func (k *KubeWrapper) InitCluster( } // JoinCluster joins existing Kubernetes cluster. -func (k *KubeWrapper) JoinCluster(ctx context.Context, args *kubeadm.BootstrapTokenDiscovery, peerRole role.Role, versionString string, k8sComponents versions.ComponentVersions, log *logger.Logger) error { +func (k *KubeWrapper) JoinCluster(ctx context.Context, args *kubeadm.BootstrapTokenDiscovery, peerRole role.Role, versionString string, k8sComponents components.Components, log *logger.Logger) error { log.With("k8sComponents", k8sComponents).Infof("Installing provided kubernetes components") if err := k.clusterUtil.InstallComponents(ctx, k8sComponents); err != nil { return fmt.Errorf("installing kubernetes components: %w", err) @@ -319,7 +319,7 @@ func (k *KubeWrapper) GetKubeconfig() ([]byte, error) { // setupK8sComponentsConfigMap applies a ConfigMap (cf. server-side apply) to store the installed k8s components. // It returns the name of the ConfigMap. -func (k *KubeWrapper) setupK8sComponentsConfigMap(ctx context.Context, components versions.ComponentVersions, clusterVersion string) (string, error) { +func (k *KubeWrapper) setupK8sComponentsConfigMap(ctx context.Context, components components.Components, clusterVersion string) (string, error) { componentsMarshalled, err := json.Marshal(components) if err != nil { return "", fmt.Errorf("marshalling component versions: %w", err) diff --git a/bootstrapper/internal/kubernetes/kubernetes_test.go b/bootstrapper/internal/kubernetes/kubernetes_test.go index 63adda648..ce36e51ce 100644 --- a/bootstrapper/internal/kubernetes/kubernetes_test.go +++ b/bootstrapper/internal/kubernetes/kubernetes_test.go @@ -22,6 +22,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/role" "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/goleak" @@ -284,7 +285,7 @@ func TestJoinCluster(t *testing.T) { privateIP := "192.0.2.1" k8sVersion := versions.Default - k8sComponents := versions.ComponentVersions{ + k8sComponents := components.Components{ { URL: "URL", Hash: "Hash", @@ -298,7 +299,7 @@ func TestJoinCluster(t *testing.T) { providerMetadata ProviderMetadata wantConfig kubeadm.JoinConfiguration role role.Role - k8sComponents versions.ComponentVersions + k8sComponents components.Components wantErr bool }{ "kubeadm join worker works with metadata and remote Kubernetes Components": { @@ -510,7 +511,7 @@ func (s *stubClusterUtil) SetupKonnectivity(kubectl k8sapi.Client, konnectivityA return s.setupKonnectivityError } -func (s *stubClusterUtil) InstallComponents(ctx context.Context, kubernetesComponents versions.ComponentVersions) error { +func (s *stubClusterUtil) InstallComponents(ctx context.Context, kubernetesComponents components.Components) error { return s.installComponentsErr } diff --git a/internal/installer/install.go b/internal/installer/install.go index cfcffa04d..6fb5f3c73 100644 --- a/internal/installer/install.go +++ b/internal/installer/install.go @@ -21,7 +21,7 @@ import ( "time" "github.com/edgelesssys/constellation/v2/internal/retry" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/spf13/afero" "k8s.io/utils/clock" ) @@ -54,7 +54,7 @@ func NewOSInstaller() *OsInstaller { // Install downloads a resource from a URL, applies any given text transformations and extracts the resulting file if required. // The resulting file(s) are copied to the destination. It also verifies the sha256 hash of the downloaded file. -func (i *OsInstaller) Install(ctx context.Context, kubernetesComponent versions.ComponentVersion) error { +func (i *OsInstaller) Install(ctx context.Context, kubernetesComponent components.Component) error { tempPath, err := i.retryDownloadToTempDir(ctx, kubernetesComponent.URL) if err != nil { return err diff --git a/internal/installer/install_test.go b/internal/installer/install_test.go index f81ff93ba..ebd2d305e 100644 --- a/internal/installer/install_test.go +++ b/internal/installer/install_test.go @@ -22,7 +22,7 @@ import ( "testing" "time" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -35,7 +35,7 @@ func TestInstall(t *testing.T) { serverURL := "http://server/path" testCases := map[string]struct { server httpBufconnServer - component versions.ComponentVersion + component components.Component hash string destination string extract bool @@ -44,7 +44,7 @@ func TestInstall(t *testing.T) { }{ "download works": { server: newHTTPBufconnServerWithBody([]byte("file-contents")), - component: versions.ComponentVersion{ + component: components.Component{ URL: serverURL, Hash: "sha256:f03779b36bece74893fd6533a67549675e21573eb0e288d87158738f9c24594e", InstallPath: "/destination", @@ -53,7 +53,7 @@ func TestInstall(t *testing.T) { }, "download with extract works": { server: newHTTPBufconnServerWithBody(createTarGz([]byte("file-contents"), "/destination")), - component: versions.ComponentVersion{ + component: components.Component{ URL: serverURL, Hash: "sha256:a52a1664ca0a6ec9790384e3d058852ab8b3a8f389a9113d150fdc6ab308d949", InstallPath: "/prefix", @@ -63,7 +63,7 @@ func TestInstall(t *testing.T) { }, "hash validation fails": { server: newHTTPBufconnServerWithBody([]byte("file-contents")), - component: versions.ComponentVersion{ + component: components.Component{ URL: serverURL, Hash: "sha256:abc", InstallPath: "/destination", @@ -72,7 +72,7 @@ func TestInstall(t *testing.T) { }, "download fails": { server: newHTTPBufconnServer(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) }), - component: versions.ComponentVersion{ + component: components.Component{ URL: serverURL, Hash: "sha256:abc", InstallPath: "/destination", diff --git a/internal/versions/components/components.go b/internal/versions/components/components.go new file mode 100644 index 000000000..122e66250 --- /dev/null +++ b/internal/versions/components/components.go @@ -0,0 +1,90 @@ +/* +Copyright (c) Edgeless Systems GmbH + +SPDX-License-Identifier: AGPL-3.0-only +*/ + +package components + +import ( + "crypto/sha256" + "errors" + "fmt" + "strings" + + "github.com/edgelesssys/constellation/v2/bootstrapper/initproto" + "github.com/edgelesssys/constellation/v2/joinservice/joinproto" +) + +// Component is a Kubernetes component. +type Component struct { + URL string + Hash string + InstallPath string + Extract bool +} + +// Components is a list of Kubernetes components. +type Components []Component + +// NewComponentsFromInitProto converts a protobuf KubernetesVersion to Components. +func NewComponentsFromInitProto(protoComponents []*initproto.KubernetesComponent) Components { + components := Components{} + for _, protoComponent := range protoComponents { + if protoComponent == nil { + continue + } + components = append(components, Component{URL: protoComponent.Url, Hash: protoComponent.Hash, InstallPath: protoComponent.InstallPath, Extract: protoComponent.Extract}) + } + return components +} + +// NewComponentsFromJoinProto converts a protobuf KubernetesVersion to Components. +func NewComponentsFromJoinProto(protoComponents []*joinproto.KubernetesComponent) Components { + components := Components{} + for _, protoComponent := range protoComponents { + if protoComponent == nil { + continue + } + components = append(components, Component{URL: protoComponent.Url, Hash: protoComponent.Hash, InstallPath: protoComponent.InstallPath, Extract: protoComponent.Extract}) + } + return components +} + +// ToInitProto converts Components to a protobuf KubernetesVersion. +func (c Components) ToInitProto() []*initproto.KubernetesComponent { + protoComponents := []*initproto.KubernetesComponent{} + for _, component := range c { + protoComponents = append(protoComponents, &initproto.KubernetesComponent{Url: component.URL, Hash: component.Hash, InstallPath: component.InstallPath, Extract: component.Extract}) + } + return protoComponents +} + +// ToJoinProto converts Components to a protobuf KubernetesVersion. +func (c Components) ToJoinProto() []*joinproto.KubernetesComponent { + protoComponents := []*joinproto.KubernetesComponent{} + for _, component := range c { + protoComponents = append(protoComponents, &joinproto.KubernetesComponent{Url: component.URL, Hash: component.Hash, InstallPath: component.InstallPath, Extract: component.Extract}) + } + return protoComponents +} + +// GetHash returns the hash over all component hashes. +func (c Components) GetHash() string { + sha := sha256.New() + for _, component := range c { + sha.Write([]byte(component.Hash)) + } + + return fmt.Sprintf("sha256:%x", sha.Sum(nil)) +} + +// GetKubeadmComponent returns the kubeadm component. +func (c Components) GetKubeadmComponent() (Component, error) { + for _, component := range c { + if strings.Contains(component.URL, "kubeadm") { + return component, nil + } + } + return Component{}, errors.New("kubeadm component not found") +} diff --git a/internal/versions/versions.go b/internal/versions/versions.go index 002273c1a..9245d390a 100644 --- a/internal/versions/versions.go +++ b/internal/versions/versions.go @@ -7,13 +7,11 @@ SPDX-License-Identifier: AGPL-3.0-only package versions import ( - "crypto/sha256" "fmt" "strings" - "github.com/edgelesssys/constellation/v2/bootstrapper/initproto" "github.com/edgelesssys/constellation/v2/internal/constants" - "github.com/edgelesssys/constellation/v2/joinservice/joinproto" + "github.com/edgelesssys/constellation/v2/internal/versions/components" ) // ValidK8sVersion represents any of the three currently supported k8s versions. @@ -104,7 +102,7 @@ const ( var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{ V1_23: { ClusterVersion: "v1.23.15", // renovate:kubernetes-release - KubernetesComponents: ComponentVersions{ + KubernetesComponents: components.Components{ { URL: "https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz", // renovate:cni-plugins-release Hash: "sha256:b275772da4026d2161bf8a8b41ed4786754c8a93ebfb6564006d5da7f23831e5", @@ -150,7 +148,7 @@ var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{ }, V1_24: { ClusterVersion: "v1.24.9", // renovate:kubernetes-release - KubernetesComponents: ComponentVersions{ + KubernetesComponents: components.Components{ { URL: "https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz", // renovate:cni-plugins-release Hash: "sha256:b275772da4026d2161bf8a8b41ed4786754c8a93ebfb6564006d5da7f23831e5", @@ -196,7 +194,7 @@ var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{ }, V1_25: { ClusterVersion: "v1.25.5", // renovate:kubernetes-release - KubernetesComponents: ComponentVersions{ + KubernetesComponents: components.Components{ { URL: "https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz", // renovate:cni-plugins-release Hash: "sha256:b275772da4026d2161bf8a8b41ed4786754c8a93ebfb6564006d5da7f23831e5", @@ -245,7 +243,7 @@ var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{ }, V1_26: { ClusterVersion: "v1.26.0", // renovate:kubernetes-release - KubernetesComponents: ComponentVersions{ + KubernetesComponents: components.Components{ { URL: "https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz", // renovate:cni-plugins-release Hash: "sha256:b275772da4026d2161bf8a8b41ed4786754c8a93ebfb6564006d5da7f23831e5", @@ -297,7 +295,7 @@ var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{ // KubernetesVersion bundles download URLs to all version-releated binaries necessary for installing/deploying a particular Kubernetes version. type KubernetesVersion struct { ClusterVersion string - KubernetesComponents ComponentVersions + KubernetesComponents components.Components CloudControllerManagerImageAWS string // k8s version dependency. CloudControllerManagerImageGCP string // Using self-built image until resolved: https://github.com/kubernetes/cloud-provider-gcp/issues/289 CloudControllerManagerImageAzure string // k8s version dependency. @@ -305,69 +303,6 @@ type KubernetesVersion struct { ClusterAutoscalerImage string // Matches k8s versioning scheme. } -// ComponentVersion is a version of a particular artifact. -type ComponentVersion struct { - URL string - Hash string - InstallPath string - Extract bool -} - -// ComponentVersions is a list of ComponentVersion. -type ComponentVersions []ComponentVersion - -// NewComponentVersionsFromInitProto converts a protobuf KubernetesVersion to ComponentVersions. -func NewComponentVersionsFromInitProto(protoComponents []*initproto.KubernetesComponent) ComponentVersions { - components := ComponentVersions{} - for _, protoComponent := range protoComponents { - if protoComponent == nil { - continue - } - components = append(components, ComponentVersion{URL: protoComponent.Url, Hash: protoComponent.Hash, InstallPath: protoComponent.InstallPath, Extract: protoComponent.Extract}) - } - return components -} - -// NewComponentVersionsFromJoinProto converts a protobuf KubernetesVersion to ComponentVersions. -func NewComponentVersionsFromJoinProto(protoComponents []*joinproto.KubernetesComponent) ComponentVersions { - components := ComponentVersions{} - for _, protoComponent := range protoComponents { - if protoComponent == nil { - continue - } - components = append(components, ComponentVersion{URL: protoComponent.Url, Hash: protoComponent.Hash, InstallPath: protoComponent.InstallPath, Extract: protoComponent.Extract}) - } - return components -} - -// ToInitProto converts a ComponentVersions to a protobuf KubernetesVersion. -func (c ComponentVersions) ToInitProto() []*initproto.KubernetesComponent { - protoComponents := []*initproto.KubernetesComponent{} - for _, component := range c { - protoComponents = append(protoComponents, &initproto.KubernetesComponent{Url: component.URL, Hash: component.Hash, InstallPath: component.InstallPath, Extract: component.Extract}) - } - return protoComponents -} - -// ToJoinProto converts a ComponentVersions to a protobuf KubernetesVersion. -func (c ComponentVersions) ToJoinProto() []*joinproto.KubernetesComponent { - protoComponents := []*joinproto.KubernetesComponent{} - for _, component := range c { - protoComponents = append(protoComponents, &joinproto.KubernetesComponent{Url: component.URL, Hash: component.Hash, InstallPath: component.InstallPath, Extract: component.Extract}) - } - return protoComponents -} - -// GetHash returns the hash over all component hashes. -func (c ComponentVersions) GetHash() string { - sha := sha256.New() - for _, component := range c { - sha.Write([]byte(component.Hash)) - } - - return fmt.Sprintf("sha256:%x", sha.Sum(nil)) -} - // versionFromDockerImage returns the version tag from the image name, e.g. "v1.22.2" from "foocr.io/org/repo:v1.22.2@sha256:3009fj0...". func versionFromDockerImage(imageName string) string { beforeAt, _, _ := strings.Cut(imageName, "@") diff --git a/joinservice/internal/kubernetes/kubernetes.go b/joinservice/internal/kubernetes/kubernetes.go index 7d4030c6c..5b00762f0 100644 --- a/joinservice/internal/kubernetes/kubernetes.go +++ b/joinservice/internal/kubernetes/kubernetes.go @@ -15,7 +15,7 @@ import ( "time" "github.com/edgelesssys/constellation/v2/internal/constants" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -52,16 +52,16 @@ func New() (*Client, error) { } // GetComponents returns the components of the cluster. -func (c *Client) GetComponents(ctx context.Context, configMapName string) (versions.ComponentVersions, error) { +func (c *Client) GetComponents(ctx context.Context, configMapName string) (components.Components, error) { componentsRaw, err := c.getConfigMapData(ctx, configMapName, constants.ComponentsListKey) if err != nil { - return versions.ComponentVersions{}, fmt.Errorf("failed to get components: %w", err) + return components.Components{}, fmt.Errorf("failed to get components: %w", err) } - var components versions.ComponentVersions - if err := json.Unmarshal([]byte(componentsRaw), &components); err != nil { - return versions.ComponentVersions{}, fmt.Errorf("failed to unmarshal components %s: %w", componentsRaw, err) + var clusterComponents components.Components + if err := json.Unmarshal([]byte(componentsRaw), &clusterComponents); err != nil { + return components.Components{}, fmt.Errorf("failed to unmarshal components %s: %w", componentsRaw, err) } - return components, nil + return clusterComponents, nil } func (c *Client) getConfigMapData(ctx context.Context, name, key string) (string, error) { diff --git a/joinservice/internal/server/server.go b/joinservice/internal/server/server.go index c50188a25..bbc3fc3b6 100644 --- a/joinservice/internal/server/server.go +++ b/joinservice/internal/server/server.go @@ -17,7 +17,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/crypto" "github.com/edgelesssys/constellation/v2/internal/grpc/grpclog" "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/edgelesssys/constellation/v2/joinservice/internal/kubernetes" "github.com/edgelesssys/constellation/v2/joinservice/joinproto" "go.uber.org/zap" @@ -224,6 +224,6 @@ type certificateAuthority interface { type kubeClient interface { GetK8sComponentsRefFromNodeVersionCRD(ctx context.Context, nodeName string) (string, error) - GetComponents(ctx context.Context, configMapName string) (versions.ComponentVersions, error) + GetComponents(ctx context.Context, configMapName string) (components.Components, error) AddNodeToJoiningNodes(ctx context.Context, nodeName string, componentsHash string, isControlPlane bool) error } diff --git a/joinservice/internal/server/server_test.go b/joinservice/internal/server/server_test.go index 9e59e6312..3fed42143 100644 --- a/joinservice/internal/server/server_test.go +++ b/joinservice/internal/server/server_test.go @@ -14,7 +14,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/attestation" "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/edgelesssys/constellation/v2/joinservice/joinproto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -39,7 +39,7 @@ func TestIssueJoinTicket(t *testing.T) { Token: "token", } - components := versions.ComponentVersions{ + clusterComponents := components.Components{ { URL: "URL", Hash: "hash", @@ -64,7 +64,7 @@ func TestIssueJoinTicket(t *testing.T) { attestation.MeasurementSecretContext: measurementSecret, }}, ca: stubCA{cert: testCert, nodeName: "node"}, - kubeClient: stubKubeClient{getComponentsVal: components, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, + kubeClient: stubKubeClient{getComponentsVal: clusterComponents, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, }, "kubeclient fails": { kubeadm: stubTokenGetter{token: testJoinToken}, @@ -83,7 +83,7 @@ func TestIssueJoinTicket(t *testing.T) { attestation.MeasurementSecretContext: measurementSecret, }}, ca: stubCA{cert: testCert, nodeName: "node", getNameErr: someErr}, - kubeClient: stubKubeClient{getComponentsVal: components, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, + kubeClient: stubKubeClient{getComponentsVal: clusterComponents, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, wantErr: true, }, "Cannot add node to JoiningNode CRD": { @@ -93,14 +93,14 @@ func TestIssueJoinTicket(t *testing.T) { attestation.MeasurementSecretContext: measurementSecret, }}, ca: stubCA{cert: testCert, nodeName: "node"}, - kubeClient: stubKubeClient{getComponentsVal: components, addNodeToJoiningNodesErr: someErr, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, + kubeClient: stubKubeClient{getComponentsVal: clusterComponents, addNodeToJoiningNodesErr: someErr, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, wantErr: true, }, "GetDataKey fails": { kubeadm: stubTokenGetter{token: testJoinToken}, kms: stubKeyGetter{dataKeys: make(map[string][]byte), getDataKeyErr: someErr}, ca: stubCA{cert: testCert, nodeName: "node"}, - kubeClient: stubKubeClient{getComponentsVal: components, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, + kubeClient: stubKubeClient{getComponentsVal: clusterComponents, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, wantErr: true, }, "GetJoinToken fails": { @@ -110,7 +110,7 @@ func TestIssueJoinTicket(t *testing.T) { attestation.MeasurementSecretContext: measurementSecret, }}, ca: stubCA{cert: testCert, nodeName: "node"}, - kubeClient: stubKubeClient{getComponentsVal: components, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, + kubeClient: stubKubeClient{getComponentsVal: clusterComponents, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, wantErr: true, }, "GetCertificate fails": { @@ -120,7 +120,7 @@ func TestIssueJoinTicket(t *testing.T) { attestation.MeasurementSecretContext: measurementSecret, }}, ca: stubCA{getCertErr: someErr, nodeName: "node"}, - kubeClient: stubKubeClient{getComponentsVal: components, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, + kubeClient: stubKubeClient{getComponentsVal: clusterComponents, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, wantErr: true, }, "control plane": { @@ -134,7 +134,7 @@ func TestIssueJoinTicket(t *testing.T) { attestation.MeasurementSecretContext: measurementSecret, }}, ca: stubCA{cert: testCert, nodeName: "node"}, - kubeClient: stubKubeClient{getComponentsVal: components, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, + kubeClient: stubKubeClient{getComponentsVal: clusterComponents, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, }, "GetControlPlaneCertificateKey fails": { isControlPlane: true, @@ -144,7 +144,7 @@ func TestIssueJoinTicket(t *testing.T) { attestation.MeasurementSecretContext: measurementSecret, }}, ca: stubCA{cert: testCert, nodeName: "node"}, - kubeClient: stubKubeClient{getComponentsVal: components, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, + kubeClient: stubKubeClient{getComponentsVal: clusterComponents, getK8sComponentsRefFromNodeVersionCRDVal: "k8s-components-ref"}, wantErr: true, }, } @@ -286,7 +286,7 @@ func (f stubCA) GetNodeNameFromCSR(csr []byte) (string, error) { } type stubKubeClient struct { - getComponentsVal versions.ComponentVersions + getComponentsVal components.Components getComponentsErr error getK8sComponentsRefFromNodeVersionCRDErr error @@ -301,7 +301,7 @@ func (s *stubKubeClient) GetK8sComponentsRefFromNodeVersionCRD(ctx context.Conte return s.getK8sComponentsRefFromNodeVersionCRDVal, s.getK8sComponentsRefFromNodeVersionCRDErr } -func (s *stubKubeClient) GetComponents(ctx context.Context, configMapName string) (versions.ComponentVersions, error) { +func (s *stubKubeClient) GetComponents(ctx context.Context, configMapName string) (components.Components, error) { return s.getComponentsVal, s.getComponentsErr } diff --git a/upgrade-agent/server.go b/upgrade-agent/server.go index 276d3b2ab..585dfd560 100644 --- a/upgrade-agent/server.go +++ b/upgrade-agent/server.go @@ -19,7 +19,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/file" "github.com/edgelesssys/constellation/v2/internal/installer" "github.com/edgelesssys/constellation/v2/internal/logger" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/edgelesssys/constellation/v2/upgrade-agent/upgradeproto" "golang.org/x/mod/semver" "google.golang.org/grpc" @@ -127,17 +127,12 @@ func prepareUpdate(ctx context.Context, installer osInstaller, updateRequest *up } // download & install the kubeadm binary - err = installer.Install(ctx, versions.ComponentVersion{ + return installer.Install(ctx, components.Component{ URL: updateRequest.KubeadmUrl, Hash: updateRequest.KubeadmHash, InstallPath: constants.KubeadmPath, Extract: false, }) - if err != nil { - return err - } - - return nil } // verifyVersion verifies the provided Kubernetes version. @@ -150,7 +145,7 @@ func verifyVersion(version string) error { type osInstaller interface { // Install downloads, installs and verifies the kubernetes component. - Install(ctx context.Context, kubernetesComponent versions.ComponentVersion) error + Install(ctx context.Context, kubernetesComponent components.Component) error } type serveStopper interface { diff --git a/upgrade-agent/server_test.go b/upgrade-agent/server_test.go index 3878d3a1d..db15d6c6d 100644 --- a/upgrade-agent/server_test.go +++ b/upgrade-agent/server_test.go @@ -11,7 +11,7 @@ import ( "fmt" "testing" - "github.com/edgelesssys/constellation/v2/internal/versions" + "github.com/edgelesssys/constellation/v2/internal/versions/components" "github.com/edgelesssys/constellation/v2/upgrade-agent/upgradeproto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -100,6 +100,6 @@ type stubOsInstaller struct { InstallErr error } -func (s stubOsInstaller) Install(ctx context.Context, kubernetesComponent versions.ComponentVersion) error { +func (s stubOsInstaller) Install(ctx context.Context, kubernetesComponent components.Component) error { return s.InstallErr }