kubernetes: verify Kubernetes components

This commit is contained in:
Leonard Cohnen 2022-11-14 19:09:49 +01:00 committed by 3u13r
parent 2c9ddbc6e7
commit 1e98b686b6
17 changed files with 439 additions and 229 deletions

View File

@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Automatic CSI driver deployment for Azure and GCP during Constellation init - Automatic CSI driver deployment for Azure and GCP during Constellation init
- Improve reproducibility by pinning the Kubernetes components.
### Changed ### Changed
<!-- For changes in existing functionality. --> <!-- For changes in existing functionality. -->
- Constellation operators are now deployed using Helm. - Constellation operators are now deployed using Helm.

View File

@ -12,6 +12,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/cloud/metadata" "github.com/edgelesssys/constellation/v2/internal/cloud/metadata"
"github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/role" "github.com/edgelesssys/constellation/v2/internal/role"
"github.com/edgelesssys/constellation/v2/internal/versions"
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3" kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
) )
@ -21,7 +22,7 @@ type clusterFake struct{}
// InitCluster fakes bootstrapping a new cluster with the current node being the master, returning the arguments required to join the cluster. // 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( func (c *clusterFake) InitCluster(
context.Context, string, string, []byte, []uint32, bool, []byte, bool, context.Context, string, string, []byte, []uint32, bool, []byte, bool,
[]byte, bool, *logger.Logger, []byte, bool, versions.ComponentVersions, *logger.Logger,
) ([]byte, error) { ) ([]byte, error) {
return []byte{}, nil return []byte{}, nil
} }

View File

@ -34,11 +34,12 @@ type InitRequest struct {
CloudServiceAccountUri string `protobuf:"bytes,7,opt,name=cloud_service_account_uri,json=cloudServiceAccountUri,proto3" json:"cloud_service_account_uri,omitempty"` CloudServiceAccountUri string `protobuf:"bytes,7,opt,name=cloud_service_account_uri,json=cloudServiceAccountUri,proto3" json:"cloud_service_account_uri,omitempty"`
KubernetesVersion string `protobuf:"bytes,8,opt,name=kubernetes_version,json=kubernetesVersion,proto3" json:"kubernetes_version,omitempty"` KubernetesVersion string `protobuf:"bytes,8,opt,name=kubernetes_version,json=kubernetesVersion,proto3" json:"kubernetes_version,omitempty"`
// repeated SSHUserKey ssh_user_keys = 9; removed // repeated SSHUserKey ssh_user_keys = 9; removed
Salt []byte `protobuf:"bytes,10,opt,name=salt,proto3" json:"salt,omitempty"` Salt []byte `protobuf:"bytes,10,opt,name=salt,proto3" json:"salt,omitempty"`
HelmDeployments []byte `protobuf:"bytes,11,opt,name=helm_deployments,json=helmDeployments,proto3" json:"helm_deployments,omitempty"` HelmDeployments []byte `protobuf:"bytes,11,opt,name=helm_deployments,json=helmDeployments,proto3" json:"helm_deployments,omitempty"`
EnforcedPcrs []uint32 `protobuf:"varint,12,rep,packed,name=enforced_pcrs,json=enforcedPcrs,proto3" json:"enforced_pcrs,omitempty"` EnforcedPcrs []uint32 `protobuf:"varint,12,rep,packed,name=enforced_pcrs,json=enforcedPcrs,proto3" json:"enforced_pcrs,omitempty"`
EnforceIdkeydigest bool `protobuf:"varint,13,opt,name=enforce_idkeydigest,json=enforceIdkeydigest,proto3" json:"enforce_idkeydigest,omitempty"` EnforceIdkeydigest bool `protobuf:"varint,13,opt,name=enforce_idkeydigest,json=enforceIdkeydigest,proto3" json:"enforce_idkeydigest,omitempty"`
ConformanceMode bool `protobuf:"varint,14,opt,name=conformance_mode,json=conformanceMode,proto3" json:"conformance_mode,omitempty"` ConformanceMode bool `protobuf:"varint,14,opt,name=conformance_mode,json=conformanceMode,proto3" json:"conformance_mode,omitempty"`
KubernetesComponents []*KubernetesComponent `protobuf:"bytes,15,rep,name=kubernetes_components,json=kubernetesComponents,proto3" json:"kubernetes_components,omitempty"`
} }
func (x *InitRequest) Reset() { func (x *InitRequest) Reset() {
@ -157,6 +158,13 @@ func (x *InitRequest) GetConformanceMode() bool {
return false return false
} }
func (x *InitRequest) GetKubernetesComponents() []*KubernetesComponent {
if x != nil {
return x.KubernetesComponents
}
return nil
}
type InitResponse struct { type InitResponse struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -220,11 +228,82 @@ func (x *InitResponse) GetClusterId() []byte {
return nil return nil
} }
type KubernetesComponent struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
InstallPath string `protobuf:"bytes,3,opt,name=install_path,json=installPath,proto3" json:"install_path,omitempty"`
Extract bool `protobuf:"varint,4,opt,name=extract,proto3" json:"extract,omitempty"`
}
func (x *KubernetesComponent) Reset() {
*x = KubernetesComponent{}
if protoimpl.UnsafeEnabled {
mi := &file_init_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *KubernetesComponent) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*KubernetesComponent) ProtoMessage() {}
func (x *KubernetesComponent) ProtoReflect() protoreflect.Message {
mi := &file_init_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use KubernetesComponent.ProtoReflect.Descriptor instead.
func (*KubernetesComponent) Descriptor() ([]byte, []int) {
return file_init_proto_rawDescGZIP(), []int{2}
}
func (x *KubernetesComponent) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *KubernetesComponent) GetHash() string {
if x != nil {
return x.Hash
}
return ""
}
func (x *KubernetesComponent) GetInstallPath() string {
if x != nil {
return x.InstallPath
}
return ""
}
func (x *KubernetesComponent) GetExtract() bool {
if x != nil {
return x.Extract
}
return false
}
var File_init_proto protoreflect.FileDescriptor var File_init_proto protoreflect.FileDescriptor
var file_init_proto_rawDesc = []byte{ var file_init_proto_rawDesc = []byte{
0x0a, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x69, 0x6e, 0x0a, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x69, 0x6e,
0x69, 0x74, 0x22, 0xf3, 0x03, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x69, 0x74, 0x22, 0xc3, 0x04, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63,
0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65,
0x72, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x6d, 0x73, 0x5f, 0x75, 0x72, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x6d, 0x73, 0x5f, 0x75,
@ -255,22 +334,34 @@ var file_init_proto_rawDesc = []byte{
0x63, 0x65, 0x49, 0x64, 0x6b, 0x65, 0x79, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x63, 0x65, 0x49, 0x64, 0x6b, 0x65, 0x79, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a,
0x10, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64,
0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d,
0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x68, 0x0a, 0x0c, 0x49, 0x6e, 0x69, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4e, 0x0a, 0x15, 0x6b, 0x75, 0x62, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,
0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x4b,
0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65,
0x6e, 0x74, 0x52, 0x14, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6f,
0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x68, 0x0a, 0x0c, 0x49, 0x6e, 0x69, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6b, 0x75, 0x62, 0x65,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6b, 0x75, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6b, 0x75,
0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65,
0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65,
0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69,
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
0x49, 0x64, 0x32, 0x34, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2d, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x49, 0x64, 0x22, 0x78, 0x0a, 0x13, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73,
0x74, 0x12, 0x11, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18,
0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x50, 0x61,
0x2f, 0x76, 0x32, 0x2f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20,
0x2f, 0x69, 0x6e, 0x69, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x32, 0x34, 0x0a, 0x03,
0x6f, 0x33, 0x41, 0x50, 0x49, 0x12, 0x2d, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x11, 0x2e, 0x69, 0x6e,
0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e,
0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x6f,
0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -285,19 +376,21 @@ func file_init_proto_rawDescGZIP() []byte {
return file_init_proto_rawDescData return file_init_proto_rawDescData
} }
var file_init_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_init_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_init_proto_goTypes = []interface{}{ var file_init_proto_goTypes = []interface{}{
(*InitRequest)(nil), // 0: init.InitRequest (*InitRequest)(nil), // 0: init.InitRequest
(*InitResponse)(nil), // 1: init.InitResponse (*InitResponse)(nil), // 1: init.InitResponse
(*KubernetesComponent)(nil), // 2: init.KubernetesComponent
} }
var file_init_proto_depIdxs = []int32{ var file_init_proto_depIdxs = []int32{
0, // 0: init.API.Init:input_type -> init.InitRequest 2, // 0: init.InitRequest.kubernetes_components:type_name -> init.KubernetesComponent
1, // 1: init.API.Init:output_type -> init.InitResponse 0, // 1: init.API.Init:input_type -> init.InitRequest
1, // [1:2] is the sub-list for method output_type 1, // 2: init.API.Init:output_type -> init.InitResponse
0, // [0:1] is the sub-list for method input_type 2, // [2:3] is the sub-list for method output_type
0, // [0:0] is the sub-list for extension type_name 1, // [1:2] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension extendee 1, // [1:1] is the sub-list for extension type_name
0, // [0:0] is the sub-list for field type_name 1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
} }
func init() { file_init_proto_init() } func init() { file_init_proto_init() }
@ -330,6 +423,18 @@ func file_init_proto_init() {
return nil return nil
} }
} }
file_init_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*KubernetesComponent); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
} }
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
@ -337,7 +442,7 @@ func file_init_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_init_proto_rawDesc, RawDescriptor: file_init_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 2, NumMessages: 3,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View File

@ -23,6 +23,7 @@ message InitRequest {
repeated uint32 enforced_pcrs = 12; repeated uint32 enforced_pcrs = 12;
bool enforce_idkeydigest = 13; bool enforce_idkeydigest = 13;
bool conformance_mode = 14; bool conformance_mode = 14;
repeated KubernetesComponent kubernetes_components = 15;
} }
message InitResponse { message InitResponse {
@ -30,3 +31,10 @@ message InitResponse {
bytes owner_id = 2; bytes owner_id = 2;
bytes cluster_id = 3; bytes cluster_id = 3;
} }
message KubernetesComponent {
string url = 1;
string hash = 2;
string install_path = 3;
bool extract = 4;
}

View File

@ -25,6 +25,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/nodestate" "github.com/edgelesssys/constellation/v2/internal/nodestate"
"github.com/edgelesssys/constellation/v2/internal/role" "github.com/edgelesssys/constellation/v2/internal/role"
"github.com/edgelesssys/constellation/v2/internal/versions"
"go.uber.org/zap" "go.uber.org/zap"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
@ -133,6 +134,7 @@ func (s *Server) Init(ctx context.Context, req *initproto.InitRequest) (*initpro
s.issuerWrapper.VMType() == vmtype.AzureCVM, s.issuerWrapper.VMType() == vmtype.AzureCVM,
req.HelmDeployments, req.HelmDeployments,
req.ConformanceMode, req.ConformanceMode,
versions.NewComponentVersionsFromProto(req.KubernetesComponents),
s.log, s.log,
) )
if err != nil { if err != nil {
@ -233,6 +235,7 @@ type ClusterInitializer interface {
azureCVM bool, azureCVM bool,
helmDeployments []byte, helmDeployments []byte,
conformanceMode bool, conformanceMode bool,
kubernetesComponents versions.ComponentVersions,
log *logger.Logger, log *logger.Logger,
) ([]byte, error) ) ([]byte, error)
} }

View File

@ -19,6 +19,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/crypto/testvector" "github.com/edgelesssys/constellation/v2/internal/crypto/testvector"
"github.com/edgelesssys/constellation/v2/internal/file" "github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero" "github.com/spf13/afero"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -250,7 +251,7 @@ type stubClusterInitializer struct {
func (i *stubClusterInitializer) InitCluster( func (i *stubClusterInitializer) InitCluster(
context.Context, string, string, []byte, []uint32, bool, []byte, bool, context.Context, string, string, []byte, []uint32, bool, []byte, bool,
[]byte, bool, *logger.Logger, []byte, bool, versions.ComponentVersions, *logger.Logger,
) ([]byte, error) { ) ([]byte, error) {
return i.initClusterKubeconfig, i.initClusterErr return i.initClusterKubeconfig, i.initClusterErr
} }

View File

@ -1,17 +0,0 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package k8sapi
const (
// Paths and permissions necessary for Kubernetes installation.
cniPluginsDir = "/opt/cni/bin"
binDir = "/run/state/bin"
kubeadmPath = "/run/state/bin/kubeadm"
kubeletPath = "/run/state/bin/kubelet"
kubeletServicePath = "/usr/lib/systemd/system/kubelet.service"
executablePerm = 0o544
)

View File

@ -10,6 +10,7 @@ import (
"archive/tar" "archive/tar"
"compress/gzip" "compress/gzip"
"context" "context"
"crypto/sha256"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -20,6 +21,7 @@ import (
"time" "time"
"github.com/edgelesssys/constellation/v2/internal/retry" "github.com/edgelesssys/constellation/v2/internal/retry"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero" "github.com/spf13/afero"
"k8s.io/utils/clock" "k8s.io/utils/clock"
) )
@ -50,28 +52,38 @@ func newOSInstaller() *osInstaller {
} }
// Install downloads a resource from a URL, applies any given text transformations and extracts the resulting file if required. // 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 all destinations. // The resulting file(s) are copied to the destination. It also verifies the sha256 hash of the downloaded file.
func (i *osInstaller) Install( func (i *osInstaller) Install(ctx context.Context, kubernetesComponent versions.ComponentVersion) error {
ctx context.Context, sourceURL string, destinations []string, perm fs.FileMode, extract bool, tempPath, err := i.retryDownloadToTempDir(ctx, kubernetesComponent.URL)
) error {
tempPath, err := i.retryDownloadToTempDir(ctx, sourceURL)
if err != nil { if err != nil {
return err return err
} }
file, err := i.fs.OpenFile(tempPath, os.O_RDONLY, 0)
if err != nil {
return fmt.Errorf("opening file %q: %w", tempPath, err)
}
sha := sha256.New()
if _, err := io.Copy(sha, file); err != nil {
return fmt.Errorf("reading file %q: %w", tempPath, err)
}
calculatedHash := fmt.Sprintf("sha256:%x", sha.Sum(nil))
if calculatedHash != kubernetesComponent.Hash {
return fmt.Errorf("hash of file %q %s does not match expected hash %s", tempPath, calculatedHash, kubernetesComponent.Hash)
}
defer func() { defer func() {
_ = i.fs.Remove(tempPath) _ = i.fs.Remove(tempPath)
}() }()
for _, destination := range destinations { if kubernetesComponent.Extract {
var err error err = i.extractArchive(tempPath, kubernetesComponent.InstallPath, executablePerm)
if extract { } else {
err = i.extractArchive(tempPath, destination, perm) err = i.copy(tempPath, kubernetesComponent.InstallPath, executablePerm)
} else {
err = i.copy(tempPath, destination, perm)
}
if err != nil {
return fmt.Errorf("installing from %q: copying to destination %q: %w", sourceURL, destination, err)
}
} }
if err != nil {
return fmt.Errorf("installing from %q: copying to destination %q: %w", kubernetesComponent.URL, kubernetesComponent.InstallPath, err)
}
return nil return nil
} }

View File

@ -22,6 +22,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero" "github.com/spf13/afero"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -31,29 +32,52 @@ import (
) )
func TestInstall(t *testing.T) { func TestInstall(t *testing.T) {
serverURL := "http://server/path"
testCases := map[string]struct { testCases := map[string]struct {
server httpBufconnServer server httpBufconnServer
component versions.ComponentVersion
hash string
destination string destination string
extract bool extract bool
readonly bool
wantErr bool wantErr bool
wantFiles map[string][]byte wantFiles map[string][]byte
}{ }{
"download works": { "download works": {
server: newHTTPBufconnServerWithBody([]byte("file-contents")), server: newHTTPBufconnServerWithBody([]byte("file-contents")),
destination: "/destination", component: versions.ComponentVersion{
wantFiles: map[string][]byte{"/destination": []byte("file-contents")}, URL: serverURL,
Hash: "sha256:f03779b36bece74893fd6533a67549675e21573eb0e288d87158738f9c24594e",
InstallPath: "/destination",
},
wantFiles: map[string][]byte{"/destination": []byte("file-contents")},
}, },
"download with extract works": { "download with extract works": {
server: newHTTPBufconnServerWithBody(createTarGz([]byte("file-contents"), "/destination")), server: newHTTPBufconnServerWithBody(createTarGz([]byte("file-contents"), "/destination")),
destination: "/prefix", component: versions.ComponentVersion{
extract: true, URL: serverURL,
wantFiles: map[string][]byte{"/prefix/destination": []byte("file-contents")}, Hash: "sha256:a52a1664ca0a6ec9790384e3d058852ab8b3a8f389a9113d150fdc6ab308d949",
InstallPath: "/prefix",
Extract: true,
},
wantFiles: map[string][]byte{"/prefix/destination": []byte("file-contents")},
},
"hash validation fails": {
server: newHTTPBufconnServerWithBody([]byte("file-contents")),
component: versions.ComponentVersion{
URL: serverURL,
Hash: "sha256:abc",
InstallPath: "/destination",
},
wantErr: true,
}, },
"download fails": { "download fails": {
server: newHTTPBufconnServer(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) }), server: newHTTPBufconnServer(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) }),
destination: "/destination", component: versions.ComponentVersion{
wantErr: true, URL: serverURL,
Hash: "sha256:abc",
InstallPath: "/destination",
},
wantErr: true,
}, },
} }
@ -81,7 +105,7 @@ func TestInstall(t *testing.T) {
retriable: func(err error) bool { return false }, retriable: func(err error) bool { return false },
} }
err := inst.Install(context.Background(), "http://server/path", []string{tc.destination}, fs.ModePerm, tc.extract) err := inst.Install(context.Background(), tc.component)
if tc.wantErr { if tc.wantErr {
assert.Error(err) assert.Error(err)
return return

View File

@ -13,7 +13,6 @@ import (
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"io/fs"
"net" "net"
"net/http" "net/http"
"os" "os"
@ -42,6 +41,10 @@ import (
const ( const (
// kubeletStartTimeout is the maximum time given to the kubelet service to (re)start. // kubeletStartTimeout is the maximum time given to the kubelet service to (re)start.
kubeletStartTimeout = 10 * time.Minute kubeletStartTimeout = 10 * time.Minute
// crdTimeout is the maximum time given to the CRDs to be created.
crdTimeout = 30 * time.Second
executablePerm = 0o544
kubeletServicePath = "/usr/lib/systemd/system/kubelet.service"
) )
// Client provides the functions to talk to the k8s API. // Client provides the functions to talk to the k8s API.
@ -57,7 +60,7 @@ type Client interface {
type installer interface { type installer interface {
Install( Install(
ctx context.Context, sourceURL string, destinations []string, perm fs.FileMode, extract bool, ctx context.Context, kubernetesComponent versions.ComponentVersion,
) error ) error
} }
@ -75,34 +78,26 @@ func NewKubernetesUtil() *KubernetesUtil {
} }
} }
// InstallComponentsFromCLI installs the kubernetes components passed from the CLI.
func (k *KubernetesUtil) InstallComponentsFromCLI(ctx context.Context, kubernetesComponents versions.ComponentVersions) 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)
}
}
return enableSystemdUnit(ctx, kubeletServicePath)
}
// InstallComponents installs kubernetes components in the version specified. // InstallComponents installs kubernetes components in the version specified.
// TODO(AB#2543,3u13r): Remove this function once the JoinService is extended.
func (k *KubernetesUtil) InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error { func (k *KubernetesUtil) InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error {
versionConf := versions.VersionConfigs[version] versionConf := versions.VersionConfigs[version]
if err := k.inst.Install( for _, component := range versionConf.KubernetesComponents {
ctx, versionConf.CNIPlugins.URL, []string{cniPluginsDir}, executablePerm, true, if err := k.inst.Install(ctx, component); err != nil {
); err != nil { return fmt.Errorf("installing kubernetes component from URL %s: %w", component.URL, err)
return fmt.Errorf("installing cni plugins: %w", err) }
}
if err := k.inst.Install(
ctx, versionConf.Crictl.URL, []string{binDir}, executablePerm, true,
); err != nil {
return fmt.Errorf("installing crictl: %w", err)
}
if err := k.inst.Install(
ctx, versionConf.Kubelet.URL, []string{kubeletPath}, executablePerm, false,
); err != nil {
return fmt.Errorf("installing kubelet: %w", err)
}
if err := k.inst.Install(
ctx, versionConf.Kubeadm.URL, []string{kubeadmPath}, executablePerm, false,
); err != nil {
return fmt.Errorf("installing kubeadm: %w", err)
}
if err := k.inst.Install(
ctx, versionConf.Kubectl.URL, []string{constants.KubectlPath}, executablePerm, false,
); err != nil {
return fmt.Errorf("installing kubectl: %w", err)
} }
return enableSystemdUnit(ctx, kubeletServicePath) return enableSystemdUnit(ctx, kubeletServicePath)
@ -132,7 +127,7 @@ func (k *KubernetesUtil) InitCluster(
// preflight // preflight
log.Infof("Running kubeadm preflight checks") log.Infof("Running kubeadm preflight checks")
cmd := exec.CommandContext(ctx, kubeadmPath, "init", "phase", "preflight", "-v=5", "--config", initConfigFile.Name()) cmd := exec.CommandContext(ctx, constants.KubeadmPath, "init", "phase", "preflight", "-v=5", "--config", initConfigFile.Name())
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
var exitErr *exec.ExitError var exitErr *exec.ExitError
@ -144,7 +139,7 @@ func (k *KubernetesUtil) InitCluster(
// create CA certs // create CA certs
log.Infof("Creating Kubernetes control-plane certificates and keys") log.Infof("Creating Kubernetes control-plane certificates and keys")
cmd = exec.CommandContext(ctx, kubeadmPath, "init", "phase", "certs", "all", "-v=5", "--config", initConfigFile.Name()) cmd = exec.CommandContext(ctx, constants.KubeadmPath, "init", "phase", "certs", "all", "-v=5", "--config", initConfigFile.Name())
out, err = cmd.CombinedOutput() out, err = cmd.CombinedOutput()
if err != nil { if err != nil {
var exitErr *exec.ExitError var exitErr *exec.ExitError
@ -172,7 +167,7 @@ func (k *KubernetesUtil) InitCluster(
skipPhases += ",addon/kube-proxy" skipPhases += ",addon/kube-proxy"
} }
cmd = exec.CommandContext(ctx, kubeadmPath, "init", "-v=5", skipPhases, "--config", initConfigFile.Name()) cmd = exec.CommandContext(ctx, constants.KubeadmPath, "init", "-v=5", skipPhases, "--config", initConfigFile.Name())
out, err = cmd.CombinedOutput() out, err = cmd.CombinedOutput()
if err != nil { if err != nil {
var exitErr *exec.ExitError var exitErr *exec.ExitError
@ -362,7 +357,7 @@ func (k *KubernetesUtil) JoinCluster(ctx context.Context, joinConfig []byte, pee
} }
// run `kubeadm join` to join a worker node to an existing Kubernetes cluster // run `kubeadm join` to join a worker node to an existing Kubernetes cluster
cmd := exec.CommandContext(ctx, kubeadmPath, "join", "-v=5", "--config", joinConfigFile.Name()) cmd := exec.CommandContext(ctx, constants.KubeadmPath, "join", "-v=5", "--config", joinConfigFile.Name())
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
var exitErr *exec.ExitError var exitErr *exec.ExitError

View File

@ -20,6 +20,7 @@ import (
type clusterUtil interface { type clusterUtil interface {
InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error InstallComponents(ctx context.Context, version versions.ValidK8sVersion) error
InstallComponentsFromCLI(ctx context.Context, kubernetesComponents versions.ComponentVersions) error
InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) 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 JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error
SetupKonnectivity(kubectl k8sapi.Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error SetupKonnectivity(kubectl k8sapi.Client, konnectivityAgentsDaemonSet kubernetes.Marshaler) error

View File

@ -87,14 +87,14 @@ func New(cloudProvider string, clusterUtil clusterUtil, configProvider configura
func (k *KubeWrapper) InitCluster( func (k *KubeWrapper) InitCluster(
ctx context.Context, cloudServiceAccountURI, versionString string, measurementSalt []byte, enforcedPCRs []uint32, ctx context.Context, cloudServiceAccountURI, versionString string, measurementSalt []byte, enforcedPCRs []uint32,
enforceIDKeyDigest bool, idKeyDigest []byte, azureCVM bool, enforceIDKeyDigest bool, idKeyDigest []byte, azureCVM bool,
helmReleasesRaw []byte, conformanceMode bool, log *logger.Logger, helmReleasesRaw []byte, conformanceMode bool, kubernetesComponents versions.ComponentVersions, log *logger.Logger,
) ([]byte, error) { ) ([]byte, error) {
k8sVersion, err := versions.NewValidK8sVersion(versionString) k8sVersion, err := versions.NewValidK8sVersion(versionString)
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.With(zap.String("version", string(k8sVersion))).Infof("Installing Kubernetes components") log.With(zap.String("version", string(k8sVersion))).Infof("Installing Kubernetes components")
if err := k.clusterUtil.InstallComponents(ctx, k8sVersion); err != nil { if err := k.clusterUtil.InstallComponentsFromCLI(ctx, kubernetesComponents); err != nil {
return nil, err return nil, err
} }

View File

@ -237,7 +237,7 @@ func TestInitCluster(t *testing.T) {
_, err := kube.InitCluster( _, err := kube.InitCluster(
context.Background(), serviceAccountURI, string(tc.k8sVersion), context.Background(), serviceAccountURI, string(tc.k8sVersion),
nil, nil, false, nil, true, []byte("{}"), false, logger.NewTest(t), nil, nil, false, nil, true, []byte("{}"), false, nil, logger.NewTest(t),
) )
if tc.wantErr { if tc.wantErr {
@ -415,16 +415,17 @@ func TestK8sCompliantHostname(t *testing.T) {
} }
type stubClusterUtil struct { type stubClusterUtil struct {
installComponentsErr error installComponentsErr error
initClusterErr error installComponentsFromCLIErr error
setupAutoscalingError error initClusterErr error
setupKonnectivityError error setupAutoscalingError error
setupGCPGuestAgentErr error setupKonnectivityError error
setupOLMErr error setupGCPGuestAgentErr error
setupNMOErr error setupOLMErr error
setupNodeOperatorErr error setupNMOErr error
joinClusterErr error setupNodeOperatorErr error
startKubeletErr error joinClusterErr error
startKubeletErr error
initConfigs [][]byte initConfigs [][]byte
joinConfigs [][]byte joinConfigs [][]byte
@ -438,6 +439,10 @@ func (s *stubClusterUtil) InstallComponents(ctx context.Context, version version
return s.installComponentsErr return s.installComponentsErr
} }
func (s *stubClusterUtil) InstallComponentsFromCLI(ctx context.Context, kubernetesComponents versions.ComponentVersions) error {
return s.installComponentsFromCLIErr
}
// TODO: Upon changing this function, please refactor it to reduce the number of arguments to <= 5. // TODO: Upon changing this function, please refactor it to reduce the number of arguments to <= 5.
// //
//revive:disable-next-line //revive:disable-next-line

View File

@ -132,6 +132,7 @@ func initialize(cmd *cobra.Command, newDialer func(validator *cloudcmd.Validator
UseExistingKek: false, UseExistingKek: false,
CloudServiceAccountUri: serviceAccURI, CloudServiceAccountUri: serviceAccURI,
KubernetesVersion: conf.KubernetesVersion, KubernetesVersion: conf.KubernetesVersion,
KubernetesComponents: versions.VersionConfigs[k8sVersion].KubernetesComponents.ToProto(),
HelmDeployments: helmDeployments, HelmDeployments: helmDeployments,
EnforcedPcrs: conf.GetEnforcedPCRs(), EnforcedPcrs: conf.GetEnforcedPCRs(),
EnforceIdkeydigest: conf.EnforcesIDKeyDigest(), EnforceIdkeydigest: conf.EnforcesIDKeyDigest(),

View File

@ -56,12 +56,6 @@ const (
DebugdPort = 4000 DebugdPort = 4000
// KonnectivityPort port for konnectivity k8s service. // KonnectivityPort port for konnectivity k8s service.
KonnectivityPort = 8132 KonnectivityPort = 8132
// NodePortFrom start of range to use for K8s node port
// https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
NodePortFrom = 30000
// NodePortTo end of range to use for K8s node port
// https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
NodePortTo = 32767
// //
// Filenames. // Filenames.
@ -84,6 +78,15 @@ const (
// KubectlPath path to kubectl binary. // KubectlPath path to kubectl binary.
KubectlPath = "/run/state/bin/kubectl" KubectlPath = "/run/state/bin/kubectl"
// CniPluginsDir path directory for CNI plugins.
CniPluginsDir = "/opt/cni/bin"
// BinDir install path for CNI config.
BinDir = "/run/state/bin"
// KubeadmPath install path for kubeadm.
KubeadmPath = "/run/state/bin/kubeadm"
// KubeletPath install path for kubelet.
KubeletPath = "/run/state/bin/kubelet"
// //
// Filenames for Constellation's micro services. // Filenames for Constellation's micro services.
// //

View File

@ -102,43 +102,48 @@ func main() {
if !ok { if !ok {
return true return true
} }
if ident.Name == "ArtifactVersion" { if ident.Name == "ComponentVersions" {
var url *ast.KeyValueExpr for _, elt := range x.Elts {
var hash *ast.KeyValueExpr // component is one list element
// Find the URL field component := elt.(*ast.CompositeLit)
for _, e := range x.Elts {
kv, ok := e.(*ast.KeyValueExpr)
if !ok {
continue
}
ident, ok := kv.Key.(*ast.Ident)
if !ok {
continue
}
if ident.Name == "URL" {
url = kv
break
}
}
// Find the Hash field
for _, e := range x.Elts {
kv, ok := e.(*ast.KeyValueExpr)
if !ok {
continue
}
ident, ok := kv.Key.(*ast.Ident)
if !ok {
continue
}
if ident.Name == "Hash" {
hash = kv
break
}
}
// Generate the hash var url *ast.KeyValueExpr
fmt.Println("Generating hash for", url.Value.(*ast.BasicLit).Value) var hash *ast.KeyValueExpr
hash.Value.(*ast.BasicLit).Value = mustGetHash(url.Value.(*ast.BasicLit).Value) // Find the URL field
for _, e := range component.Elts {
kv, ok := e.(*ast.KeyValueExpr)
if !ok {
continue
}
ident, ok := kv.Key.(*ast.Ident)
if !ok {
continue
}
if ident.Name == "URL" {
url = kv
break
}
}
// Find the Hash field
for _, e := range component.Elts {
kv, ok := e.(*ast.KeyValueExpr)
if !ok {
continue
}
ident, ok := kv.Key.(*ast.Ident)
if !ok {
continue
}
if ident.Name == "Hash" {
hash = kv
break
}
}
// Generate the hash
fmt.Println("Generating hash for", url.Value.(*ast.BasicLit).Value)
hash.Value.(*ast.BasicLit).Value = mustGetHash(url.Value.(*ast.BasicLit).Value)
}
} }
} }
return true return true

View File

@ -9,6 +9,9 @@ package versions
import ( import (
"fmt" "fmt"
"strings" "strings"
"github.com/edgelesssys/constellation/v2/bootstrapper/initproto"
"github.com/edgelesssys/constellation/v2/internal/constants"
) )
// ValidK8sVersion represents any of the three currently supported k8s versions. // ValidK8sVersion represents any of the three currently supported k8s versions.
@ -93,25 +96,37 @@ const (
var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{ var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{
V1_23: { V1_23: {
PatchVersion: "v1.23.14", // renovate:kubernetes-release PatchVersion: "v1.23.14", // renovate:kubernetes-release
CNIPlugins: ArtifactVersion{ KubernetesComponents: ComponentVersions{
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", 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",
Crictl: ArtifactVersion{ InstallPath: constants.CniPluginsDir,
URL: "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-amd64.tar.gz", // renovate:crictl-release Extract: true,
Hash: "sha256:86ab210c007f521ac4cdcbcf0ae3fb2e10923e65f16de83e0e1db191a07f0235", },
}, {
Kubelet: ArtifactVersion{ URL: "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-amd64.tar.gz", // renovate:crictl-release
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.23.14/bin/linux/amd64/kubelet", // renovate:kubernetes-release Hash: "sha256:86ab210c007f521ac4cdcbcf0ae3fb2e10923e65f16de83e0e1db191a07f0235",
Hash: "sha256:f2bef00508790f632d035a6cfdd31539115611bfc93c5a3266ceb95bb2f27b76", InstallPath: constants.BinDir,
}, Extract: true,
Kubeadm: ArtifactVersion{ },
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.23.14/bin/linux/amd64/kubeadm", // renovate:kubernetes-release {
Hash: "sha256:46c847e2699839b9ccf6673f0b946c4778a3a2e8e463d15854ba30d3f0cbd87a", URL: "https://storage.googleapis.com/kubernetes-release/release/v1.23.14/bin/linux/amd64/kubelet", // renovate:kubernetes-release
}, Hash: "sha256:f2bef00508790f632d035a6cfdd31539115611bfc93c5a3266ceb95bb2f27b76",
Kubectl: ArtifactVersion{ InstallPath: constants.KubeletPath,
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.23.14/bin/linux/amd64/kubectl", // renovate:kubernetes-release Extract: false,
Hash: "sha256:13ce4b18ba6e15d5d259249c530637dd7fb9722d121df022099f3ed5f2bd74cd", },
{
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.23.14/bin/linux/amd64/kubeadm", // renovate:kubernetes-release
Hash: "sha256:46c847e2699839b9ccf6673f0b946c4778a3a2e8e463d15854ba30d3f0cbd87a",
InstallPath: constants.KubeadmPath,
Extract: false,
},
{
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.23.14/bin/linux/amd64/kubectl", // renovate:kubernetes-release
Hash: "sha256:13ce4b18ba6e15d5d259249c530637dd7fb9722d121df022099f3ed5f2bd74cd",
InstallPath: constants.KubectlPath,
Extract: false,
},
}, },
// CloudControllerManagerImageAWS is the CCM image used on AWS. // CloudControllerManagerImageAWS is the CCM image used on AWS.
CloudControllerManagerImageAWS: "registry.k8s.io/provider-aws/cloud-controller-manager:v1.23.2@sha256:5caf74bfe1c6e1b7b7d40345db52b54eeea7229a8fd73c7db9488ef87dc7a496", // renovate:container CloudControllerManagerImageAWS: "registry.k8s.io/provider-aws/cloud-controller-manager:v1.23.2@sha256:5caf74bfe1c6e1b7b7d40345db52b54eeea7229a8fd73c7db9488ef87dc7a496", // renovate:container
@ -127,25 +142,37 @@ var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{
}, },
V1_24: { V1_24: {
PatchVersion: "v1.24.8", // renovate:kubernetes-release PatchVersion: "v1.24.8", // renovate:kubernetes-release
CNIPlugins: ArtifactVersion{ KubernetesComponents: ComponentVersions{
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", 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",
Crictl: ArtifactVersion{ InstallPath: constants.CniPluginsDir,
URL: "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-amd64.tar.gz", // renovate:crictl-release Extract: true,
Hash: "sha256:86ab210c007f521ac4cdcbcf0ae3fb2e10923e65f16de83e0e1db191a07f0235", },
}, {
Kubelet: ArtifactVersion{ URL: "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-amd64.tar.gz", // renovate:crictl-release
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.24.8/bin/linux/amd64/kubelet", // renovate:kubernetes-release Hash: "sha256:86ab210c007f521ac4cdcbcf0ae3fb2e10923e65f16de83e0e1db191a07f0235",
Hash: "sha256:2da0b93857cf352bff5d1eb42e34d398a5971b63a53d8687b45179a78540d6d6", InstallPath: constants.BinDir,
}, Extract: true,
Kubeadm: ArtifactVersion{ },
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.24.8/bin/linux/amd64/kubeadm", // renovate:kubernetes-release {
Hash: "sha256:9fea42b4fb5eb2da638d20710ebb791dde221e6477793d3de70134ac058c4cc7", URL: "https://storage.googleapis.com/kubernetes-release/release/v1.24.8/bin/linux/amd64/kubelet", // renovate:kubernetes-release
}, Hash: "sha256:2da0b93857cf352bff5d1eb42e34d398a5971b63a53d8687b45179a78540d6d6",
Kubectl: ArtifactVersion{ InstallPath: constants.KubeletPath,
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.24.8/bin/linux/amd64/kubectl", // renovate:kubernetes-release Extract: false,
Hash: "sha256:f93c18751ec715b4d4437e7ece18fe91948c71be1f24ab02a2dde150f5449855", },
{
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.24.8/bin/linux/amd64/kubeadm", // renovate:kubernetes-release
Hash: "sha256:9fea42b4fb5eb2da638d20710ebb791dde221e6477793d3de70134ac058c4cc7",
InstallPath: constants.KubeadmPath,
Extract: false,
},
{
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.24.8/bin/linux/amd64/kubectl", // renovate:kubernetes-release
Hash: "sha256:f93c18751ec715b4d4437e7ece18fe91948c71be1f24ab02a2dde150f5449855",
InstallPath: constants.KubectlPath,
Extract: false,
},
}, },
// CloudControllerManagerImageAWS is the CCM image used on AWS. // CloudControllerManagerImageAWS is the CCM image used on AWS.
CloudControllerManagerImageAWS: "registry.k8s.io/provider-aws/cloud-controller-manager:v1.24.1@sha256:4b75b09cc5b3959d06a8c2fb84f165e8163ec0153eaa6a48ece6c8113e78e720", // renovate:container CloudControllerManagerImageAWS: "registry.k8s.io/provider-aws/cloud-controller-manager:v1.24.1@sha256:4b75b09cc5b3959d06a8c2fb84f165e8163ec0153eaa6a48ece6c8113e78e720", // renovate:container
@ -161,25 +188,37 @@ var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{
}, },
V1_25: { V1_25: {
PatchVersion: "v1.25.4", // renovate:kubernetes-release PatchVersion: "v1.25.4", // renovate:kubernetes-release
CNIPlugins: ArtifactVersion{ KubernetesComponents: ComponentVersions{
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", 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",
Crictl: ArtifactVersion{ InstallPath: constants.CniPluginsDir,
URL: "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-amd64.tar.gz", // renovate:crictl-release Extract: true,
Hash: "sha256:86ab210c007f521ac4cdcbcf0ae3fb2e10923e65f16de83e0e1db191a07f0235", },
}, {
Kubelet: ArtifactVersion{ URL: "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-amd64.tar.gz", // renovate:crictl-release
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.25.4/bin/linux/amd64/kubelet", // renovate:kubernetes-release Hash: "sha256:86ab210c007f521ac4cdcbcf0ae3fb2e10923e65f16de83e0e1db191a07f0235",
Hash: "sha256:7f7437e361f829967ee02e30026d7e85219693432ac5e930cc98dd9c7ddb2fac", InstallPath: constants.BinDir,
}, Extract: true,
Kubeadm: ArtifactVersion{ },
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.25.4/bin/linux/amd64/kubeadm", // renovate:kubernetes-release {
Hash: "sha256:b8a6119d2a3a7c6add43dcf8f920436bf7fe71a77a086e96e40aa9d6f70be826", URL: "https://storage.googleapis.com/kubernetes-release/release/v1.25.4/bin/linux/amd64/kubelet", // renovate:kubernetes-release
}, Hash: "sha256:7f7437e361f829967ee02e30026d7e85219693432ac5e930cc98dd9c7ddb2fac",
Kubectl: ArtifactVersion{ InstallPath: constants.KubeletPath,
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.25.4/bin/linux/amd64/kubectl", // renovate:kubernetes-release Extract: false,
Hash: "sha256:e4e569249798a09f37e31b8b33571970fcfbdecdd99b1b81108adc93ca74b522", },
{
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.25.4/bin/linux/amd64/kubeadm", // renovate:kubernetes-release
Hash: "sha256:b8a6119d2a3a7c6add43dcf8f920436bf7fe71a77a086e96e40aa9d6f70be826",
InstallPath: constants.KubeadmPath,
Extract: false,
},
{
URL: "https://storage.googleapis.com/kubernetes-release/release/v1.25.4/bin/linux/amd64/kubectl", // renovate:kubernetes-release
Hash: "sha256:e4e569249798a09f37e31b8b33571970fcfbdecdd99b1b81108adc93ca74b522",
InstallPath: constants.KubectlPath,
Extract: false,
},
}, },
// CloudControllerManagerImageAWS is the CCM image used on AWS. // CloudControllerManagerImageAWS is the CCM image used on AWS.
CloudControllerManagerImageAWS: "registry.k8s.io/provider-aws/cloud-controller-manager:v1.25.1@sha256:85d3f1e9dacc72531445989bb10999e1e70ebc409d11be57e5baa5f031a893b0", // renovate:container CloudControllerManagerImageAWS: "registry.k8s.io/provider-aws/cloud-controller-manager:v1.25.1@sha256:85d3f1e9dacc72531445989bb10999e1e70ebc409d11be57e5baa5f031a893b0", // renovate:container
@ -201,22 +240,44 @@ var VersionConfigs = map[ValidK8sVersion]KubernetesVersion{
// KubernetesVersion bundles download URLs to all version-releated binaries necessary for installing/deploying a particular Kubernetes version. // KubernetesVersion bundles download URLs to all version-releated binaries necessary for installing/deploying a particular Kubernetes version.
type KubernetesVersion struct { type KubernetesVersion struct {
PatchVersion string PatchVersion string
CNIPlugins ArtifactVersion // No k8s version dependency. KubernetesComponents ComponentVersions
Crictl ArtifactVersion // k8s version dependency. CloudControllerManagerImageAWS string // k8s version dependency.
Kubelet ArtifactVersion // k8s version dependency. CloudControllerManagerImageGCP string // Using self-built image until resolved: https://github.com/kubernetes/cloud-provider-gcp/issues/289
Kubeadm ArtifactVersion // k8s version dependency. CloudControllerManagerImageAzure string // k8s version dependency.
Kubectl ArtifactVersion // k8s version dependency. CloudNodeManagerImageAzure string // k8s version dependency. Same version as above.
CloudControllerManagerImageAWS string // k8s version dependency. ClusterAutoscalerImage string // Matches k8s versioning scheme.
CloudControllerManagerImageGCP string // Using self-built image until resolved: https://github.com/kubernetes/cloud-provider-gcp/issues/289
CloudControllerManagerImageAzure string // k8s version dependency.
CloudNodeManagerImageAzure string // k8s version dependency. Same version as above.
ClusterAutoscalerImage string // Matches k8s versioning scheme.
} }
// ArtifactVersion is a version of a particular artifact. // ComponentVersion is a version of a particular artifact.
type ArtifactVersion struct { type ComponentVersion struct {
URL string URL string
Hash string Hash string
InstallPath string
Extract bool
}
// ComponentVersions is a list of ComponentVersion.
type ComponentVersions []ComponentVersion
// NewComponentVersionsFromProto converts a protobuf KubernetesVersion to ComponentVersions.
func NewComponentVersionsFromProto(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
}
// ToProto converts a ComponentVersions to a protobuf KubernetesVersion.
func (c ComponentVersions) ToProto() []*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
} }
// versionFromDockerImage returns the version tag from the image name, e.g. "v1.22.2" from "foocr.io/org/repo:v1.22.2@sha256:3009fj0...". // versionFromDockerImage returns the version tag from the image name, e.g. "v1.22.2" from "foocr.io/org/repo:v1.22.2@sha256:3009fj0...".