diff --git a/CHANGELOG.md b/CHANGELOG.md index 26cd02704..b2b9ff12c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - (Maintenance) Switch to google.golang.org/protobuf - (Feature) Add DebugPackage to the OPS Binary - (Feature) (Networking) ArangoRoute Protocol +- (Feature) (Platform) Platform Requirements support ## [1.2.43](https://github.com/arangodb/kube-arangodb/tree/1.2.43) (2024-10-14) - (Feature) ArangoRoute CRD diff --git a/go.mod b/go.mod index 886044454..b02eb624d 100644 --- a/go.mod +++ b/go.mod @@ -73,6 +73,7 @@ require ( ) require ( + github.com/Masterminds/semver/v3 v3.3.0 github.com/aws/aws-sdk-go v1.55.5 helm.sh/helm/v3 v3.16.2 ) @@ -85,7 +86,6 @@ require ( github.com/BurntSushi/toml v1.3.2 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.3.0 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect diff --git a/integrations/scheduler/v2/definition/chart.pb.go b/integrations/scheduler/v2/definition/chart.pb.go index 77d22e830..6bbcc5eaa 100644 --- a/integrations/scheduler/v2/definition/chart.pb.go +++ b/integrations/scheduler/v2/definition/chart.pb.go @@ -50,6 +50,8 @@ type SchedulerV2ChartInfo struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Chart Version Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // Keeps the Platform details from the output + Platform *SchedulerV2ChartPlatform `protobuf:"bytes,3,opt,name=platform,proto3,oneof" json:"platform,omitempty"` } func (x *SchedulerV2ChartInfo) Reset() { @@ -98,6 +100,62 @@ func (x *SchedulerV2ChartInfo) GetVersion() string { return "" } +func (x *SchedulerV2ChartInfo) GetPlatform() *SchedulerV2ChartPlatform { + if x != nil { + return x.Platform + } + return nil +} + +// Chart Platform Details +type SchedulerV2ChartPlatform struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of the requirements + Requirements map[string]string `protobuf:"bytes,1,rep,name=requirements,proto3" json:"requirements,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *SchedulerV2ChartPlatform) Reset() { + *x = SchedulerV2ChartPlatform{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SchedulerV2ChartPlatform) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SchedulerV2ChartPlatform) ProtoMessage() {} + +func (x *SchedulerV2ChartPlatform) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[1] + 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 SchedulerV2ChartPlatform.ProtoReflect.Descriptor instead. +func (*SchedulerV2ChartPlatform) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{1} +} + +func (x *SchedulerV2ChartPlatform) GetRequirements() map[string]string { + if x != nil { + return x.Requirements + } + return nil +} + // SchedulerV2 ListCharts Request type SchedulerV2ListChartsRequest struct { state protoimpl.MessageState @@ -111,7 +169,7 @@ type SchedulerV2ListChartsRequest struct { func (x *SchedulerV2ListChartsRequest) Reset() { *x = SchedulerV2ListChartsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[1] + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -124,7 +182,7 @@ func (x *SchedulerV2ListChartsRequest) String() string { func (*SchedulerV2ListChartsRequest) ProtoMessage() {} func (x *SchedulerV2ListChartsRequest) ProtoReflect() protoreflect.Message { - mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[1] + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -137,7 +195,7 @@ func (x *SchedulerV2ListChartsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SchedulerV2ListChartsRequest.ProtoReflect.Descriptor instead. func (*SchedulerV2ListChartsRequest) Descriptor() ([]byte, []int) { - return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{1} + return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{2} } func (x *SchedulerV2ListChartsRequest) GetItems() int64 { @@ -160,7 +218,7 @@ type SchedulerV2ListChartsResponse struct { func (x *SchedulerV2ListChartsResponse) Reset() { *x = SchedulerV2ListChartsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[2] + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -173,7 +231,7 @@ func (x *SchedulerV2ListChartsResponse) String() string { func (*SchedulerV2ListChartsResponse) ProtoMessage() {} func (x *SchedulerV2ListChartsResponse) ProtoReflect() protoreflect.Message { - mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[2] + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -186,7 +244,7 @@ func (x *SchedulerV2ListChartsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SchedulerV2ListChartsResponse.ProtoReflect.Descriptor instead. func (*SchedulerV2ListChartsResponse) Descriptor() ([]byte, []int) { - return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{2} + return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{3} } func (x *SchedulerV2ListChartsResponse) GetCharts() []string { @@ -209,7 +267,7 @@ type SchedulerV2GetChartRequest struct { func (x *SchedulerV2GetChartRequest) Reset() { *x = SchedulerV2GetChartRequest{} if protoimpl.UnsafeEnabled { - mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[3] + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -222,7 +280,7 @@ func (x *SchedulerV2GetChartRequest) String() string { func (*SchedulerV2GetChartRequest) ProtoMessage() {} func (x *SchedulerV2GetChartRequest) ProtoReflect() protoreflect.Message { - mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[3] + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -235,7 +293,7 @@ func (x *SchedulerV2GetChartRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SchedulerV2GetChartRequest.ProtoReflect.Descriptor instead. func (*SchedulerV2GetChartRequest) Descriptor() ([]byte, []int) { - return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{3} + return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{4} } func (x *SchedulerV2GetChartRequest) GetName() string { @@ -260,7 +318,7 @@ type SchedulerV2GetChartResponse struct { func (x *SchedulerV2GetChartResponse) Reset() { *x = SchedulerV2GetChartResponse{} if protoimpl.UnsafeEnabled { - mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[4] + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -273,7 +331,7 @@ func (x *SchedulerV2GetChartResponse) String() string { func (*SchedulerV2GetChartResponse) ProtoMessage() {} func (x *SchedulerV2GetChartResponse) ProtoReflect() protoreflect.Message { - mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[4] + mi := &file_integrations_scheduler_v2_definition_chart_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -286,7 +344,7 @@ func (x *SchedulerV2GetChartResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SchedulerV2GetChartResponse.ProtoReflect.Descriptor instead. func (*SchedulerV2GetChartResponse) Descriptor() ([]byte, []int) { - return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{4} + return file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP(), []int{5} } func (x *SchedulerV2GetChartResponse) GetChart() []byte { @@ -309,34 +367,51 @@ var file_integrations_scheduler_v2_definition_chart_proto_rawDesc = []byte{ 0x0a, 0x30, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x22, 0x44, 0x0a, - 0x14, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x43, 0x68, 0x61, 0x72, - 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x22, 0x43, 0x0a, 0x1c, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x56, 0x32, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x48, 0x00, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x88, 0x01, 0x01, 0x42, 0x08, - 0x0a, 0x06, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x37, 0x0a, 0x1d, 0x53, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, - 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x74, - 0x73, 0x22, 0x30, 0x0a, 0x1a, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, - 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x68, 0x0a, 0x1b, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x56, 0x32, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x63, 0x68, 0x61, 0x72, 0x74, 0x12, 0x33, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x74, 0x6f, 0x12, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x22, 0x97, 0x01, + 0x0a, 0x14, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x43, 0x68, - 0x61, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x42, 0x48, 0x5a, - 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, - 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, - 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x64, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x72, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x48, 0x00, 0x52, 0x08, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0xb6, 0x01, 0x0a, 0x18, 0x53, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x43, 0x68, 0x61, 0x72, 0x74, 0x50, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x59, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, + 0x56, 0x32, 0x43, 0x68, 0x61, 0x72, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, + 0x3f, 0x0a, 0x11, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x43, 0x0a, 0x1c, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x19, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, + 0x00, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x37, 0x0a, 0x1d, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x56, 0x32, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x74, 0x73, 0x22, 0x30, + 0x0a, 0x1a, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x47, 0x65, 0x74, + 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x68, 0x0a, 0x1b, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x47, + 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x12, 0x33, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, + 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x32, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, + 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -351,21 +426,25 @@ func file_integrations_scheduler_v2_definition_chart_proto_rawDescGZIP() []byte return file_integrations_scheduler_v2_definition_chart_proto_rawDescData } -var file_integrations_scheduler_v2_definition_chart_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_integrations_scheduler_v2_definition_chart_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_integrations_scheduler_v2_definition_chart_proto_goTypes = []interface{}{ (*SchedulerV2ChartInfo)(nil), // 0: scheduler.SchedulerV2ChartInfo - (*SchedulerV2ListChartsRequest)(nil), // 1: scheduler.SchedulerV2ListChartsRequest - (*SchedulerV2ListChartsResponse)(nil), // 2: scheduler.SchedulerV2ListChartsResponse - (*SchedulerV2GetChartRequest)(nil), // 3: scheduler.SchedulerV2GetChartRequest - (*SchedulerV2GetChartResponse)(nil), // 4: scheduler.SchedulerV2GetChartResponse + (*SchedulerV2ChartPlatform)(nil), // 1: scheduler.SchedulerV2ChartPlatform + (*SchedulerV2ListChartsRequest)(nil), // 2: scheduler.SchedulerV2ListChartsRequest + (*SchedulerV2ListChartsResponse)(nil), // 3: scheduler.SchedulerV2ListChartsResponse + (*SchedulerV2GetChartRequest)(nil), // 4: scheduler.SchedulerV2GetChartRequest + (*SchedulerV2GetChartResponse)(nil), // 5: scheduler.SchedulerV2GetChartResponse + nil, // 6: scheduler.SchedulerV2ChartPlatform.RequirementsEntry } var file_integrations_scheduler_v2_definition_chart_proto_depIdxs = []int32{ - 0, // 0: scheduler.SchedulerV2GetChartResponse.info:type_name -> scheduler.SchedulerV2ChartInfo - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 1, // 0: scheduler.SchedulerV2ChartInfo.platform:type_name -> scheduler.SchedulerV2ChartPlatform + 6, // 1: scheduler.SchedulerV2ChartPlatform.requirements:type_name -> scheduler.SchedulerV2ChartPlatform.RequirementsEntry + 0, // 2: scheduler.SchedulerV2GetChartResponse.info:type_name -> scheduler.SchedulerV2ChartInfo + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_integrations_scheduler_v2_definition_chart_proto_init() } @@ -387,7 +466,7 @@ func file_integrations_scheduler_v2_definition_chart_proto_init() { } } file_integrations_scheduler_v2_definition_chart_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SchedulerV2ListChartsRequest); i { + switch v := v.(*SchedulerV2ChartPlatform); i { case 0: return &v.state case 1: @@ -399,7 +478,7 @@ func file_integrations_scheduler_v2_definition_chart_proto_init() { } } file_integrations_scheduler_v2_definition_chart_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SchedulerV2ListChartsResponse); i { + switch v := v.(*SchedulerV2ListChartsRequest); i { case 0: return &v.state case 1: @@ -411,7 +490,7 @@ func file_integrations_scheduler_v2_definition_chart_proto_init() { } } file_integrations_scheduler_v2_definition_chart_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SchedulerV2GetChartRequest); i { + switch v := v.(*SchedulerV2ListChartsResponse); i { case 0: return &v.state case 1: @@ -423,6 +502,18 @@ func file_integrations_scheduler_v2_definition_chart_proto_init() { } } file_integrations_scheduler_v2_definition_chart_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SchedulerV2GetChartRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v2_definition_chart_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SchedulerV2GetChartResponse); i { case 0: return &v.state @@ -435,14 +526,15 @@ func file_integrations_scheduler_v2_definition_chart_proto_init() { } } } - file_integrations_scheduler_v2_definition_chart_proto_msgTypes[1].OneofWrappers = []interface{}{} + file_integrations_scheduler_v2_definition_chart_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_integrations_scheduler_v2_definition_chart_proto_msgTypes[2].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_integrations_scheduler_v2_definition_chart_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 7, NumExtensions: 0, NumServices: 0, }, diff --git a/integrations/scheduler/v2/definition/chart.proto b/integrations/scheduler/v2/definition/chart.proto index 7dad5cffb..920ad09ae 100644 --- a/integrations/scheduler/v2/definition/chart.proto +++ b/integrations/scheduler/v2/definition/chart.proto @@ -30,6 +30,14 @@ message SchedulerV2ChartInfo { string name = 1; // Chart Version string version = 2; + // Keeps the Platform details from the output + optional SchedulerV2ChartPlatform platform = 3; +} + +// Chart Platform Details +message SchedulerV2ChartPlatform { + // List of the requirements + map requirements = 1; } // SchedulerV2 ListCharts Request diff --git a/integrations/scheduler/v2/implementation_test.go b/integrations/scheduler/v2/implementation_test.go index 86bf1cadf..bb51d5194 100644 --- a/integrations/scheduler/v2/implementation_test.go +++ b/integrations/scheduler/v2/implementation_test.go @@ -23,14 +23,19 @@ package v2 import ( "context" "testing" + "time" "github.com/stretchr/testify/require" "helm.sh/helm/v3/pkg/action" + core "k8s.io/api/core/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" pbSchedulerV2 "github.com/arangodb/kube-arangodb/integrations/scheduler/v2/definition" pbSharedV1 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" "github.com/arangodb/kube-arangodb/pkg/util/tests" + "github.com/arangodb/kube-arangodb/pkg/util/tests/suite" ) func cleanup(t *testing.T, c helm.Client) func() { @@ -47,6 +52,32 @@ func cleanup(t *testing.T, c helm.Client) func() { require.NoError(t, err) }) } + + t.Run("Remove NS", func(t *testing.T) { + if err := c.Client().Kubernetes().CoreV1().Namespaces().Delete(context.Background(), tests.FakeNamespace, meta.DeleteOptions{}); !kerrors.IsNotFound(err) { + require.NoError(t, err) + } + + for { + time.Sleep(time.Second) + + if _, err := c.Client().Kubernetes().CoreV1().Namespaces().Get(context.Background(), tests.FakeNamespace, meta.GetOptions{}); !kerrors.IsNotFound(err) { + require.NoError(t, err) + continue + } + + break + } + }) + + t.Run("Create NS", func(t *testing.T) { + _, err = c.Client().Kubernetes().CoreV1().Namespaces().Create(context.Background(), &core.Namespace{ + ObjectMeta: meta.ObjectMeta{ + Name: tests.FakeNamespace, + }, + }, meta.CreateOptions{}) + require.NoError(t, err) + }) }) return func() { @@ -63,6 +94,23 @@ func cleanup(t *testing.T, c helm.Client) func() { require.NoError(t, err) }) } + + t.Run("Remove NS", func(t *testing.T) { + if err := c.Client().Kubernetes().CoreV1().Namespaces().Delete(context.Background(), tests.FakeNamespace, meta.DeleteOptions{}); !kerrors.IsNotFound(err) { + require.NoError(t, err) + } + + for { + time.Sleep(time.Second) + + if _, err := c.Client().Kubernetes().CoreV1().Namespaces().Get(context.Background(), tests.FakeNamespace, meta.GetOptions{}); !kerrors.IsNotFound(err) { + require.NoError(t, err) + continue + } + + break + } + }) }) } } @@ -139,7 +187,7 @@ func Test_Implementation(t *testing.T) { status, err := scheduler.Install(context.Background(), &pbSchedulerV2.SchedulerV2InstallRequest{ Name: "test", Values: nil, - Chart: example_1_0_0, + Chart: suite.GetChart(t, "example", "1.0.0"), }) require.NoError(t, err) @@ -154,7 +202,7 @@ func Test_Implementation(t *testing.T) { }) t.Run("Install Outside", func(t *testing.T) { - resp, err := h.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err := h.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test-outside" }) require.NoError(t, err) @@ -173,7 +221,7 @@ func Test_Implementation(t *testing.T) { status, err := scheduler.Install(context.Background(), &pbSchedulerV2.SchedulerV2InstallRequest{ Name: "test-x", Values: nil, - Chart: example_1_0_0, + Chart: suite.GetChart(t, "example", "1.0.0"), Options: &pbSchedulerV2.SchedulerV2InstallRequestOptions{ Labels: map[string]string{ "X": "X", @@ -186,7 +234,7 @@ func Test_Implementation(t *testing.T) { }) t.Run("Install Second Outside", func(t *testing.T) { - resp, err := h.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err := h.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test-outside-x" in.Labels = map[string]string{ "X": "X", @@ -234,7 +282,20 @@ func Test_Implementation(t *testing.T) { status, err := scheduler.Upgrade(context.Background(), &pbSchedulerV2.SchedulerV2UpgradeRequest{ Name: "test", Values: values, - Chart: example_1_0_0, + Chart: suite.GetChart(t, "example", "1.0.0"), + }) + require.NoError(t, err) + + require.NotNil(t, status.GetAfter()) + t.Logf("Data: %s", string(status.GetAfter().GetValues())) + require.Len(t, status.GetAfter().GetValues(), len(values)) + }) + + t.Run("Upgrade to 1", func(t *testing.T) { + status, err := scheduler.Upgrade(context.Background(), &pbSchedulerV2.SchedulerV2UpgradeRequest{ + Name: "test", + Values: values, + Chart: suite.GetChart(t, "example", "1.0.1"), }) require.NoError(t, err) @@ -251,7 +312,7 @@ func Test_Implementation(t *testing.T) { require.NotNil(t, status.GetRelease()) - require.EqualValues(t, 2, status.GetRelease().GetVersion()) + require.EqualValues(t, 3, status.GetRelease().GetVersion()) t.Logf("Data: %s", string(status.GetRelease().GetValues())) require.Len(t, status.GetRelease().GetValues(), len(values)) }) diff --git a/integrations/scheduler/v2/suite/example-1.0.0.tgz b/integrations/scheduler/v2/suite/example-1.0.0.tgz deleted file mode 100644 index c12100f2b..000000000 Binary files a/integrations/scheduler/v2/suite/example-1.0.0.tgz and /dev/null differ diff --git a/integrations/scheduler/v2/suite_test.go b/integrations/scheduler/v2/suite_test.go index 621048aa1..47a1a6caa 100644 --- a/integrations/scheduler/v2/suite_test.go +++ b/integrations/scheduler/v2/suite_test.go @@ -44,9 +44,6 @@ func init() { }) } -//go:embed suite/example-1.0.0.tgz -var example_1_0_0 []byte - func Handler(t *testing.T, ctx context.Context, client helm.Client, mods ...Mod) svc.Handler { handler, err := New(client, NewConfiguration().With(mods...)) require.NoError(t, err) diff --git a/pkg/apis/platform/v1alpha1/chart_details.go b/pkg/apis/platform/v1alpha1/chart_details.go index 4adcb0fee..0be1f3edf 100644 --- a/pkg/apis/platform/v1alpha1/chart_details.go +++ b/pkg/apis/platform/v1alpha1/chart_details.go @@ -21,8 +21,17 @@ package v1alpha1 type ChartDetails struct { - Name string `json:"name,omitempty"` - Version string `json:"version,omitempty"` + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` + Platform *ChartDetailsPlatform `json:"platform,omitempty"` +} + +func (c *ChartDetails) GetPlatform() *ChartDetailsPlatform { + if c == nil { + return nil + } + + return c.Platform } func (c *ChartDetails) GetName() string { diff --git a/pkg/apis/platform/v1alpha1/chart_details_platform.go b/pkg/apis/platform/v1alpha1/chart_details_platform.go new file mode 100644 index 000000000..ca7ffe4aa --- /dev/null +++ b/pkg/apis/platform/v1alpha1/chart_details_platform.go @@ -0,0 +1,33 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package v1alpha1 + +type ChartDetailsPlatform struct { + Requirements ChartDetailsPlatformRequirements `json:"requirements,omitempty"` +} + +func (c *ChartDetailsPlatform) GetRequirements() ChartDetailsPlatformRequirements { + if c == nil { + return nil + } + + return c.Requirements +} diff --git a/pkg/apis/platform/v1alpha1/chart_details_platform_version.go b/pkg/apis/platform/v1alpha1/chart_details_platform_version.go new file mode 100644 index 000000000..2e261b254 --- /dev/null +++ b/pkg/apis/platform/v1alpha1/chart_details_platform_version.go @@ -0,0 +1,37 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package v1alpha1 + +import ( + "github.com/arangodb/kube-arangodb/pkg/util" +) + +type ChartDetailsPlatformRequirements map[string]ChartDetailsPlatformVersionConstrain + +type ChartDetailsPlatformVersionConstrain string + +func (c *ChartDetailsPlatformVersionConstrain) AsSemverConstrain() (util.VersionConstrain, error) { + if c == nil { + return nil, nil + } + + return util.NewVersionConstrain(string(*c)) +} diff --git a/pkg/apis/platform/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/platform/v1alpha1/zz_generated.deepcopy.go index c7ccfbd4e..eed78e47e 100644 --- a/pkg/apis/platform/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/platform/v1alpha1/zz_generated.deepcopy.go @@ -358,6 +358,11 @@ func (in *ArangoPlatformStorageStatus) DeepCopy() *ArangoPlatformStorageStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ChartDetails) DeepCopyInto(out *ChartDetails) { *out = *in + if in.Platform != nil { + in, out := &in.Platform, &out.Platform + *out = new(ChartDetailsPlatform) + (*in).DeepCopyInto(*out) + } return } @@ -371,6 +376,51 @@ func (in *ChartDetails) DeepCopy() *ChartDetails { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChartDetailsPlatform) DeepCopyInto(out *ChartDetailsPlatform) { + *out = *in + if in.Requirements != nil { + in, out := &in.Requirements, &out.Requirements + *out = make(ChartDetailsPlatformRequirements, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChartDetailsPlatform. +func (in *ChartDetailsPlatform) DeepCopy() *ChartDetailsPlatform { + if in == nil { + return nil + } + out := new(ChartDetailsPlatform) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in ChartDetailsPlatformRequirements) DeepCopyInto(out *ChartDetailsPlatformRequirements) { + { + in := &in + *out = make(ChartDetailsPlatformRequirements, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChartDetailsPlatformRequirements. +func (in ChartDetailsPlatformRequirements) DeepCopy() ChartDetailsPlatformRequirements { + if in == nil { + return nil + } + out := new(ChartDetailsPlatformRequirements) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ChartStatusInfo) DeepCopyInto(out *ChartStatusInfo) { *out = *in @@ -382,7 +432,7 @@ func (in *ChartStatusInfo) DeepCopyInto(out *ChartStatusInfo) { if in.Details != nil { in, out := &in.Details, &out.Details *out = new(ChartDetails) - **out = **in + (*in).DeepCopyInto(*out) } return } diff --git a/pkg/apis/shared/validate.go b/pkg/apis/shared/validate.go index 59e5c139b..ceaffcc8c 100644 --- a/pkg/apis/shared/validate.go +++ b/pkg/apis/shared/validate.go @@ -207,6 +207,19 @@ func ValidateList[T any](in []T, validator func(T) error, checks ...func(in []T) return WithErrors(errors...) } +// ValidateInterfaceMap Validates object if is not nil with path +func ValidateInterfaceMap[T ValidateInterface](in map[string]T) error { + errors := make([]error, 0, len(in)) + + for id := range in { + if err := PrefixResourceError(id, in[id].Validate()); err != nil { + errors = append(errors, err) + } + } + + return WithErrors(errors...) +} + // ValidateMap validates all elements on the list func ValidateMap[T any](in map[string]T, validator func(string, T) error, checks ...func(in map[string]T) error) error { errors := make([]error, 0, len(in)+len(checks)) diff --git a/pkg/handlers/platform/chart/chart_test.go b/pkg/handlers/platform/chart/chart_test.go index 99fcdecef..712cf951f 100644 --- a/pkg/handlers/platform/chart/chart_test.go +++ b/pkg/handlers/platform/chart/chart_test.go @@ -29,6 +29,7 @@ import ( "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/tests" + "github.com/arangodb/kube-arangodb/pkg/util/tests/suite" ) func Test_ChartReconcile_EmptyChart(t *testing.T) { @@ -78,7 +79,7 @@ func Test_ChartReconcile_EmptyChart(t *testing.T) { t.Run("Invalid chart name", func(t *testing.T) { // Arrange tests.Apply(t, extension_invalid_name, func(t *testing.T, obj *platformApi.ArangoPlatformChart) { - obj.Spec.Definition = chart_1_0 + obj.Spec.Definition = suite.GetChart(t, "example", "1.0.0") }) tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension_invalid_name) @@ -99,7 +100,7 @@ func Test_ChartReconcile_EmptyChart(t *testing.T) { t.Run("Valid chart 1.0.0", func(t *testing.T) { // Arrange tests.Apply(t, extension, func(t *testing.T, obj *platformApi.ArangoPlatformChart) { - obj.Spec.Definition = chart_1_0 + obj.Spec.Definition = suite.GetChart(t, "example", "1.0.0") }) tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) @@ -117,14 +118,41 @@ func Test_ChartReconcile_EmptyChart(t *testing.T) { require.NotNil(t, extension.Status.Info.Details) require.EqualValues(t, "example", extension.Status.Info.Details.GetName()) require.EqualValues(t, "1.0.0", extension.Status.Info.Details.GetVersion()) - require.EqualValues(t, util.SHA256(chart_1_0), extension.Status.Info.Checksum) + require.EqualValues(t, util.SHA256(suite.GetChart(t, "example", "1.0.0")), extension.Status.Info.Checksum) + require.Nil(t, extension.Status.Info.Details.Platform) + require.True(t, extension.Status.Conditions.IsTrue(platformApi.ReadyCondition)) + }) + + t.Run("Valid chart 1.0.1", func(t *testing.T) { + // Arrange + tests.Apply(t, extension, func(t *testing.T, obj *platformApi.ArangoPlatformChart) { + obj.Spec.Definition = suite.GetChart(t, "example", "1.0.1") + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.True(t, extension.Status.Conditions.IsTrue(platformApi.SpecValidCondition)) + require.NotNil(t, extension.Status.Info) + require.True(t, extension.Status.Info.Valid) + require.EqualValues(t, extension.Status.Info.Message, "") + require.NotNil(t, extension.Status.Info.Details) + require.EqualValues(t, "example", extension.Status.Info.Details.GetName()) + require.EqualValues(t, "1.0.1", extension.Status.Info.Details.GetVersion()) + require.EqualValues(t, util.SHA256(suite.GetChart(t, "example", "1.0.1")), extension.Status.Info.Checksum) + require.NotNil(t, extension.Status.Info.Details.Platform) require.True(t, extension.Status.Conditions.IsTrue(platformApi.ReadyCondition)) }) t.Run("Valid chart 1.1.0", func(t *testing.T) { // Arrange tests.Apply(t, extension, func(t *testing.T, obj *platformApi.ArangoPlatformChart) { - obj.Spec.Definition = chart_1_1 + obj.Spec.Definition = suite.GetChart(t, "example", "1.1.0") }) tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) @@ -142,7 +170,8 @@ func Test_ChartReconcile_EmptyChart(t *testing.T) { require.NotNil(t, extension.Status.Info.Details) require.EqualValues(t, "example", extension.Status.Info.Details.GetName()) require.EqualValues(t, "1.1.0", extension.Status.Info.Details.GetVersion()) - require.EqualValues(t, util.SHA256(chart_1_1), extension.Status.Info.Checksum) + require.Nil(t, extension.Status.Info.Details.Platform) + require.EqualValues(t, util.SHA256(suite.GetChart(t, "example", "1.1.0")), extension.Status.Info.Checksum) require.True(t, extension.Status.Conditions.IsTrue(platformApi.ReadyCondition)) }) } diff --git a/pkg/handlers/platform/chart/handler.go b/pkg/handlers/platform/chart/handler.go index 7b5cc9db8..3467371b2 100644 --- a/pkg/handlers/platform/chart/handler.go +++ b/pkg/handlers/platform/chart/handler.go @@ -142,7 +142,7 @@ func (h *handler) HandleSpecData(ctx context.Context, item operation.Item, exten return true, operator.Reconcile("Spec changed") } - if chart.Name() != extension.GetName() { + if chart.Chart().Name() != extension.GetName() { status.Info = &platformApi.ChartStatusInfo{ Definition: extension.Spec.Definition, Checksum: extension.Spec.Definition.SHA256(), @@ -153,11 +153,23 @@ func (h *handler) HandleSpecData(ctx context.Context, item operation.Item, exten return true, operator.Reconcile("Spec changed") } + platform, err := chart.Platform() + if err != nil { + status.Info = &platformApi.ChartStatusInfo{ + Definition: extension.Spec.Definition, + Checksum: extension.Spec.Definition.SHA256(), + Valid: false, + Message: "Chart is invalid: Unable to get platform details", + } + + return true, operator.Reconcile("Spec changed") + } + status.Info = &platformApi.ChartStatusInfo{ Definition: extension.Spec.Definition, Checksum: extension.Spec.Definition.SHA256(), Valid: true, - Details: chartInfoExtract(chart), + Details: chartInfoExtract(chart.Chart(), platform), } return true, operator.Reconcile("Spec changed") @@ -169,13 +181,29 @@ func (h *handler) CanBeHandled(item operation.Item) bool { item.Kind == Kind() } -func chartInfoExtract(chart *chart.Chart) *platformApi.ChartDetails { +func chartInfoExtract(chart *chart.Chart, platform *helm.Platform) *platformApi.ChartDetails { if chart == nil || chart.Metadata == nil { return nil } - return &platformApi.ChartDetails{ + r := &platformApi.ChartDetails{ Name: chart.Name(), Version: chart.Metadata.Version, } + + if platform != nil { + var c platformApi.ChartDetailsPlatform + + if len(platform.Requirements) > 0 { + c.Requirements = make(platformApi.ChartDetailsPlatformRequirements, len(platform.Requirements)) + + for k, v := range platform.Requirements { + c.Requirements[k] = platformApi.ChartDetailsPlatformVersionConstrain(v) + } + } + + r.Platform = &c + } + + return r } diff --git a/pkg/handlers/platform/chart/suite/example-1.0.0.tgz b/pkg/handlers/platform/chart/suite/example-1.0.0.tgz deleted file mode 100644 index c12100f2b..000000000 Binary files a/pkg/handlers/platform/chart/suite/example-1.0.0.tgz and /dev/null differ diff --git a/pkg/handlers/platform/chart/suite_test.go b/pkg/handlers/platform/chart/suite_test.go index ef95717f5..45f1fe57f 100644 --- a/pkg/handlers/platform/chart/suite_test.go +++ b/pkg/handlers/platform/chart/suite_test.go @@ -33,12 +33,6 @@ import ( "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" ) -//go:embed suite/example-1.0.0.tgz -var chart_1_0 []byte - -//go:embed suite/example-1.1.0.tgz -var chart_1_1 []byte - func newFakeHandler() *handler { f := fakeClientSet.NewSimpleClientset() k := fake.NewSimpleClientset() diff --git a/pkg/util/k8sutil/helm/chart.go b/pkg/util/k8sutil/helm/chart.go index 67461b27d..e590706bb 100644 --- a/pkg/util/k8sutil/helm/chart.go +++ b/pkg/util/k8sutil/helm/chart.go @@ -30,8 +30,12 @@ import ( type Chart []byte -func (c Chart) Get() (*chart.Chart, error) { - return newChartReaderFromBytes(c) +func (c Chart) Get() (ChartData, error) { + return newChartFromData(c) +} + +func (c Chart) Raw() []byte { + return c } func newChartReaderFromBytes(in []byte) (*chart.Chart, error) { diff --git a/pkg/util/k8sutil/helm/chart_data.go b/pkg/util/k8sutil/helm/chart_data.go new file mode 100644 index 000000000..1b8ab8b57 --- /dev/null +++ b/pkg/util/k8sutil/helm/chart_data.go @@ -0,0 +1,58 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package helm + +import ( + "helm.sh/helm/v3/pkg/chart" + + "github.com/arangodb/kube-arangodb/pkg/util/errors" +) + +type ChartData interface { + Chart() *chart.Chart + + Platform() (*Platform, error) +} + +type chartData struct { + chart *chart.Chart +} + +func (c chartData) Platform() (*Platform, error) { + return extractPlatform(c.chart) +} + +func (c chartData) Chart() *chart.Chart { + return c.chart +} + +func newChartFromData(data []byte) (ChartData, error) { + var c chartData + + v, err := newChartReaderFromBytes(data) + if err != nil { + return nil, errors.Errorf("Unable to load chart") + } + + c.chart = v + + return c, nil +} diff --git a/pkg/util/k8sutil/helm/chart_manager_test.go b/pkg/util/k8sutil/helm/chart_manager_test.go index b1cd665a0..583b1c835 100644 --- a/pkg/util/k8sutil/helm/chart_manager_test.go +++ b/pkg/util/k8sutil/helm/chart_manager_test.go @@ -50,17 +50,17 @@ func Test_Manager(t *testing.T) { vchart, err := vdata.Get() require.NoError(t, err) - require.NotNil(t, vchart.Metadata) + require.NotNil(t, vchart.Chart().Metadata) data, err := mgr.Chart(context.Background(), repo, "latest") require.NoError(t, err) chart, err := data.Get() require.NoError(t, err) - require.NotNil(t, chart.Metadata) + require.NotNil(t, chart.Chart().Metadata) - require.EqualValues(t, v, vchart.Metadata.Version) - require.EqualValues(t, v, chart.Metadata.Version) + require.EqualValues(t, v, vchart.Chart().Metadata.Version) + require.EqualValues(t, v, chart.Chart().Metadata.Version) }) t.Run("ByVersion", func(t *testing.T) { for _, version := range limitArray(mgr.Versions(repo), 5) { @@ -71,8 +71,8 @@ func Test_Manager(t *testing.T) { c, err := data.Get() require.NoError(t, err) - require.NotNil(t, c.Metadata) - require.EqualValues(t, version, c.Metadata.Version) + require.NotNil(t, c.Chart().Metadata) + require.EqualValues(t, version, c.Chart().Metadata.Version) }) } }) diff --git a/pkg/util/k8sutil/helm/client.go b/pkg/util/k8sutil/helm/client.go index 40ca7d1be..5654a30ca 100644 --- a/pkg/util/k8sutil/helm/client.go +++ b/pkg/util/k8sutil/helm/client.go @@ -184,7 +184,7 @@ func (c *client) Install(ctx context.Context, chart Chart, values Values, mods . return nil, err } - result, err := act.Run(chartData, valuesData) + result, err := act.Run(chartData.Chart(), valuesData) if err != nil { return nil, err } @@ -217,7 +217,7 @@ func (c *client) Upgrade(ctx context.Context, name string, chart Chart, values V } if release != nil { - if meta := chartData.Metadata; meta != nil { + if meta := chartData.Chart().Metadata; meta != nil { if release.GetChart().GetMetadata().GetVersion() == meta.Version { // We are on the same version if release.Values.Equals(values) { @@ -230,7 +230,7 @@ func (c *client) Upgrade(ctx context.Context, name string, chart Chart, values V } } - result, err := act.Run(name, chartData, valuesData) + result, err := act.Run(name, chartData.Chart(), valuesData) if err != nil { return nil, err } diff --git a/pkg/util/k8sutil/helm/client_test.go b/pkg/util/k8sutil/helm/client_test.go index 546fead80..65103c8e8 100644 --- a/pkg/util/k8sutil/helm/client_test.go +++ b/pkg/util/k8sutil/helm/client_test.go @@ -30,6 +30,7 @@ import ( meta "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/arangodb/kube-arangodb/pkg/util/tests" + "github.com/arangodb/kube-arangodb/pkg/util/tests/suite" ) func cleanup(t *testing.T, c Client) func() { @@ -81,7 +82,7 @@ func Test_Connection(t *testing.T) { }) t.Run("Install", func(t *testing.T) { - resp, err := c.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err := c.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test" }) require.NoError(t, err) @@ -90,7 +91,7 @@ func Test_Connection(t *testing.T) { }) t.Run("Upgrade With No change", func(t *testing.T) { - resp, err := c.Upgrade(context.Background(), "test", example_1_0_0, nil) + resp, err := c.Upgrade(context.Background(), "test", suite.GetChart(t, "example", "1.0.0"), nil) require.NoError(t, err) require.NotNil(t, resp) @@ -99,7 +100,7 @@ func Test_Connection(t *testing.T) { }) t.Run("Upgrade With change", func(t *testing.T) { - resp, err := c.Upgrade(context.Background(), "test", example_1_0_0, Values(`{"A":"X"}`)) + resp, err := c.Upgrade(context.Background(), "test", suite.GetChart(t, "example", "1.0.0"), Values(`{"A":"X"}`)) require.NoError(t, err) require.NotNil(t, resp) @@ -135,7 +136,7 @@ func Test_Connection(t *testing.T) { }) t.Run("Reinstall", func(t *testing.T) { - resp, err := c.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err := c.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test" in.Labels = map[string]string{ "X1": "X1", @@ -150,7 +151,7 @@ func Test_Connection(t *testing.T) { defer cleanup(t, c)() t.Run("Install", func(t *testing.T) { - resp, err := c.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err := c.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test-1" in.Labels = map[string]string{ "X1": "X1", @@ -160,7 +161,7 @@ func Test_Connection(t *testing.T) { require.Len(t, resp.Labels, 1) - resp, err = c.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err = c.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test-2" in.Labels = map[string]string{ "X1": "X2", @@ -170,7 +171,7 @@ func Test_Connection(t *testing.T) { require.Len(t, resp.Labels, 1) - resp, err = c.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err = c.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test-3" in.Labels = map[string]string{ "X1": "X1", @@ -181,7 +182,7 @@ func Test_Connection(t *testing.T) { require.Len(t, resp.Labels, 2) - resp, err = c.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err = c.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test-4" }) require.NoError(t, err) @@ -236,7 +237,7 @@ func Test_Connection(t *testing.T) { defer cleanup(t, c)() t.Run("Install", func(t *testing.T) { - resp, err := c.Install(context.Background(), example_1_0_0, nil, func(in *action.Install) { + resp, err := c.Install(context.Background(), suite.GetChart(t, "example", "1.0.0"), nil, func(in *action.Install) { in.ReleaseName = "test" }) require.NoError(t, err) @@ -250,7 +251,7 @@ func Test_Connection(t *testing.T) { }) t.Run("Update", func(t *testing.T) { - resp, err := c.Upgrade(context.Background(), "test", example_1_0_0, newValues(t, map[string]any{ + resp, err := c.Upgrade(context.Background(), "test", suite.GetChart(t, "example", "1.0.0"), newValues(t, map[string]any{ "data": map[string]string{ "test": "test", }, diff --git a/pkg/util/k8sutil/helm/platform.go b/pkg/util/k8sutil/helm/platform.go new file mode 100644 index 000000000..bb4d2a470 --- /dev/null +++ b/pkg/util/k8sutil/helm/platform.go @@ -0,0 +1,54 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package helm + +import ( + "helm.sh/helm/v3/pkg/chart" + + "github.com/arangodb/kube-arangodb/pkg/util" +) + +const ( + PlatformFileName = "platform.yml" +) + +func extractPlatform(chart *chart.Chart) (*Platform, error) { + if chart == nil { + return nil, nil + } + + for _, file := range chart.Files { + if file == nil { + return nil, nil + } + + if file.Name == PlatformFileName { + obj, err := util.JsonOrYamlUnmarshal[Platform](file.Data) + if err != nil { + return nil, err + } + + return &obj, nil + } + } + + return nil, nil +} diff --git a/pkg/util/k8sutil/helm/platform_object.go b/pkg/util/k8sutil/helm/platform_object.go new file mode 100644 index 000000000..08944b31a --- /dev/null +++ b/pkg/util/k8sutil/helm/platform_object.go @@ -0,0 +1,29 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package helm + +type Platform struct { + Requirements PlatformRequirements `json:"requirements,omitempty"` +} + +type PlatformRequirements map[string]PlatformVersionDefinition + +type PlatformVersionDefinition string diff --git a/pkg/util/k8sutil/helm/platform_test.go b/pkg/util/k8sutil/helm/platform_test.go new file mode 100644 index 000000000..db8a23330 --- /dev/null +++ b/pkg/util/k8sutil/helm/platform_test.go @@ -0,0 +1,46 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package helm + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/arangodb/kube-arangodb/pkg/util/tests/suite" +) + +func Test_Platform(t *testing.T) { + c1, err := Chart(suite.GetChart(t, "example", "1.0.0")).Get() + require.NoError(t, err) + + p1, err := c1.Platform() + require.NoError(t, err) + + c2, err := Chart(suite.GetChart(t, "example", "1.0.1")).Get() + require.NoError(t, err) + + p2, err := c2.Platform() + require.NoError(t, err) + + require.Nil(t, p1) + require.NotNil(t, p2) +} diff --git a/pkg/util/k8sutil/helm/suite/example-1.0.0.tgz b/pkg/util/k8sutil/helm/suite/example-1.0.0.tgz deleted file mode 100644 index c12100f2b..000000000 Binary files a/pkg/util/k8sutil/helm/suite/example-1.0.0.tgz and /dev/null differ diff --git a/pkg/util/k8sutil/helm/suite_test.go b/pkg/util/k8sutil/helm/suite_test.go index bb496ba95..73b134dcd 100644 --- a/pkg/util/k8sutil/helm/suite_test.go +++ b/pkg/util/k8sutil/helm/suite_test.go @@ -38,9 +38,6 @@ func init() { }) } -//go:embed suite/example-1.0.0.tgz -var example_1_0_0 []byte - func newValues(t *testing.T, in any) Values { v, err := NewValues(in) require.NoError(t, err) diff --git a/pkg/util/tests/suite/chart.go b/pkg/util/tests/suite/chart.go new file mode 100644 index 000000000..234417504 --- /dev/null +++ b/pkg/util/tests/suite/chart.go @@ -0,0 +1,55 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package suite + +import ( + _ "embed" + "testing" + + "github.com/stretchr/testify/require" +) + +//go:embed chart/example-1.0.0.tgz +var chart_example_1_0_0 []byte + +//go:embed chart/example-1.0.1.tgz +var chart_example_1_0_1 []byte + +//go:embed chart/example-1.1.0.tgz +var chart_example_1_1_0 []byte + +func GetChart(t *testing.T, name, version string) []byte { + switch name { + case "example": + switch version { + case "1.0.0": + return chart_example_1_0_0 + case "1.0.1": + return chart_example_1_0_1 + case "1.1.0": + return chart_example_1_1_0 + } + } + + require.Fail(t, "Chart with version not found") + + return nil +} diff --git a/pkg/util/tests/suite/chart/example-1.0.0.tgz b/pkg/util/tests/suite/chart/example-1.0.0.tgz new file mode 100644 index 000000000..04fda88bf Binary files /dev/null and b/pkg/util/tests/suite/chart/example-1.0.0.tgz differ diff --git a/pkg/util/tests/suite/chart/example-1.0.1.tgz b/pkg/util/tests/suite/chart/example-1.0.1.tgz new file mode 100644 index 000000000..15e8fea4a Binary files /dev/null and b/pkg/util/tests/suite/chart/example-1.0.1.tgz differ diff --git a/pkg/handlers/platform/chart/suite/example-1.1.0.tgz b/pkg/util/tests/suite/chart/example-1.1.0.tgz similarity index 100% rename from pkg/handlers/platform/chart/suite/example-1.1.0.tgz rename to pkg/util/tests/suite/chart/example-1.1.0.tgz diff --git a/pkg/util/version.go b/pkg/util/version.go new file mode 100644 index 000000000..1d8f05e19 --- /dev/null +++ b/pkg/util/version.go @@ -0,0 +1,57 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package util + +import "github.com/Masterminds/semver/v3" + +type VersionConstrain interface { + Validate(version string) (bool, error) +} + +type versionConstrain struct { + constrain *semver.Constraints +} + +func (v versionConstrain) Validate(version string) (bool, error) { + ver, err := semver.NewVersion(version) + if err != nil { + return false, err + } + + if ver.Prerelease() != "" { + nver, nerr := ver.SetPrerelease("") + if nerr != nil { + return false, nerr + } + ver = &nver + } + + return v.constrain.Check(ver), nil +} + +func NewVersionConstrain(constrain string) (VersionConstrain, error) { + c, err := semver.NewConstraint(constrain) + if err != nil { + return nil, err + } + + return versionConstrain{constrain: c}, nil +} diff --git a/pkg/util/version_test.go b/pkg/util/version_test.go new file mode 100644 index 000000000..c32af38d6 --- /dev/null +++ b/pkg/util/version_test.go @@ -0,0 +1,127 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package util + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_VersionConstrain(t *testing.T) { + type constrain struct { + version string + valid bool + } + + validate := func(version string, checks ...constrain) { + t.Run(version, func(t *testing.T) { + vc, err := NewVersionConstrain(version) + require.NoError(t, err) + + for _, el := range checks { + t.Run(el.version, func(t *testing.T) { + b, err := vc.Validate(el.version) + require.NoError(t, err) + + if el.valid { + require.True(t, b) + } else { + require.False(t, b) + } + }) + } + }) + } + + validate(">= 1.2.3 < 1.3.0", + constrain{ + version: "1.2.3", + valid: true, + }, + constrain{ + version: "1.2.5", + valid: true, + }, + constrain{ + version: "1.3.0", + }, + constrain{ + version: "v1.2.3-abcdefg", + valid: true, + }, + ) + + validate(">= 1.2.3 < 1.3.0 || >= 1.3.1 < 1.4.0", + constrain{ + version: "1.2.3", + valid: true, + }, + constrain{ + version: "1.2.5", + valid: true, + }, + constrain{ + version: "1.3.0", + }, + constrain{ + version: "v1.2.3-abcdefg", + valid: true, + }, + constrain{ + version: "1.3.5", + valid: true, + }, + constrain{ + version: "1.4.0", + }, + ) + + validate("~ 1", + constrain{ + version: "1.2.3", + valid: true, + }, + constrain{ + version: "1.2.5", + valid: true, + }, + constrain{ + version: "1.3.0", + valid: true, + }, + constrain{ + version: "v1.2.3-abcdefg", + valid: true, + }, + constrain{ + version: "1.3.5", + valid: true, + }, + constrain{ + version: "1.4.0", + valid: true, + }, + constrain{ + version: "2.0.0", + }, + ) +}