mirror of
https://github.com/kubevela/kubevela.git
synced 2026-05-22 01:03:27 +00:00
* Proof Concept Signed-off-by: Brian Kane <briankane1@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * Cleanup dispatch stages and remove dry run namespaces Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * Single Health Condition Working Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * Multiple Health Conditions Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * Support Empty Health Status Signed-off-by: Brian Kane <briankane1@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * Caching Signed-off-by: Brian Kane <briankane1@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * includes changes from make-reviewable Signed-off-by: Amit Singh <singhamitch@outlook.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * minor formatting fixes Signed-off-by: Amit Singh <singhamitch@outlook.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * fix: handles cases where resource is nil Signed-off-by: Amit Singh <singhamitch@outlook.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: creates chart release before returning rendered resources to kubevela Signed-off-by: Amit Singh <singhamitch@outlook.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: helm release record via dry-run for helm list visibility The previous createChartRelease did a real helm install/upgrade which deployed resources directly, conflicting with KubeVela's dispatch ("exists but not managed by any application" errors). Also, Helm's lazy client via cli.New().RESTClientGetter() silently wrote to in-memory storage instead of Kubernetes secrets, so helm list never showed releases. Fix: use dry-run install to build a release object without deploying resources, and bypass Helm's lazy client by creating a direct Kubernetes clientset wired to helmdriver.NewSecrets. Set KubeVersion from the real cluster version to pass chart constraints. Prevent duplicate revisions on repeated reconciles via mutex serialization and in-memory fingerprint tracking (chartVersion + values). New revisions are only created when chart version or values actually change. Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * fix: override Kubernetes version for kubeVersion validation in chart release Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Enhance Helm chart component definition and CUE provider, update API types, and add new examples and documentation. Signed-off-by: Chaitanya Reddy Onteddu <co@guidewire.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Add Helm uninstall action and optimize install/upgrade with release fingerprinting and KubeVela ownership labels. Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Introduce to prevent resources from being applied while ensuring they are recorded for garbage collection, and apply it to Helm release secrets. Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Enhance velaLabelPostRenderer to include Helm ownership annotations and improve cache invalidation logic for Helm releases Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Enhance Helm release secret tracking for garbage collection during application deletion and upgrades Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> Co-Authored-By: Jerrin Francis <jerrinfrancis7@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Add Helm chart test and application definition for podinfo deployment Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Refactor Helm release secret handling and improve metadata filtering for KubeVela adoption Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Label existing Helm release secrets with KubeVela ownership for better tracking and cleanup Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Remove outdated documentation files for Helm integration and revision management Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Add various Helm chart application test and improve test coverage for Helmchart component Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Update Helm chart tests to validate deployment list and ensure label presence Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Enhance Helm chart tests for resource verification and application health checks Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Update Helm chart test scenarios for multi-component health checks and resource configurations Signed-off-by: Anaswara Suresh <anaswarasuresh2212@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Implement dry-run mode for Helm provider to enhance validation without cluster interaction Signed-off-by: Anaswara Suresh <anaswarasuresh2212@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Refactor import statements and enhance Helmchart edge case tests for better error handling and validation Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Refactor Helm provider methods for improved error handling and retry logic during installation Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Improve Helm provider tests and documentation with enhanced assertions and example configurations Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Register helm package with cuex.DefaultCompiler for improved import resolution Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Remove crossplane application configuration from crossplane-app.yaml Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Enhance workload compiler with external package loading and improve Helm chart health checks Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Remove unused cuex import and initialization function from helm provider Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Replace cuex.DefaultCompiler with localcuex.WorkloadCompiler for improved CUE compilation Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * feat: Implement dry-run mode for Helm provider functions during validation Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> * test: add unit tests for Helm provider and workflow provider - Created suite tests for the Helm provider in pkg/cue/cuex/providers/helm/suite_test.go. - Implemented unit tests for Helm workflow provider in pkg/workflow/providers/helm/helm_test.go. - Added suite tests for Helm workflow provider in pkg/workflow/providers/helm/suite_test.go. Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> * feat: Add additional health check tests for error scenarios Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> * feat: Enhance health check logic and improve documentation in helmchart definition Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> * feat: Refactor helmchart template for improved readability and structure Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> * docs: remove redundant struct-only tests from helm_test.go Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com> * Feat: Implement CUE sanitization for OpenAPI schema generation Signed-off-by: Vishal Kumar <vishal210893@gmail.com> * feat: Add tests for rendering and fetching Helm charts with dry-run support Signed-off-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com> * feat: Enhance required parameter validation tests with retry logic for webhook synchronization Signed-off-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com> * feat: Improve chart version retrieval by sorting entries and enhancing error messages Signed-off-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com> * feat: Enhance primary output handling for Helm charts with stable ConfigMap metadata Signed-off-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com> * chore: Fix CUE formatting alignment in helmchart definition Signed-off-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com> * feat: Extend timeout for self-healing Helmchart tests to improve reliability Signed-off-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com> * feat: Increase timeout for golangci-lint to enhance linting reliability Signed-off-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com> --------- Signed-off-by: Brian Kane <briankane1@gmail.com> Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com> Signed-off-by: Amit Singh <singhamitch@outlook.com> Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com> Signed-off-by: Chaitanya Reddy Onteddu <co@guidewire.com> Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com> Signed-off-by: Anaswara Suresh <anaswarasuresh2212@gmail.com> Signed-off-by: Vishal Kumar <vishal210893@gmail.com> Signed-off-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com> Co-authored-by: Brian Kane <briankane1@gmail.com> Co-authored-by: Amit Singh <singhamitch@outlook.com> Co-authored-by: Jerrin Francis <jerrinfrancis7@gmail.com> Co-authored-by: Reetika Malhotra <malhotra.reetika25@gmail.com> Co-authored-by: Chaitanya Reddy Onteddu <co@guidewire.com> Co-authored-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com> Co-authored-by: Vishal Kumar <vishal210893@gmail.com> Co-authored-by: Anaswara Suresh <anaswarasuresh2212@gmail.com> Co-authored-by: vaibhav0096 <vaibhav.agrawal0096@gmail.com>
241 lines
7.2 KiB
Go
241 lines
7.2 KiB
Go
/*
|
|
Copyright 2024 The KubeVela Authors.
|
|
|
|
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.
|
|
*/
|
|
|
|
package controllers_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
wfTypesv1alpha1 "github.com/kubevela/pkg/apis/oam/v1alpha1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
|
|
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
|
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
|
"github.com/oam-dev/kubevela/pkg/oam/util"
|
|
)
|
|
|
|
var _ = Describe("Application required-parameter validation", Ordered, func() {
|
|
var (
|
|
ctx context.Context
|
|
nsName string
|
|
namespace corev1.Namespace
|
|
)
|
|
|
|
BeforeAll(func() {
|
|
ctx = context.Background()
|
|
nsName = randomNamespaceName("requiredparam-validation-test")
|
|
namespace = corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName}}
|
|
|
|
By("creating the test namespace")
|
|
Eventually(func() error {
|
|
return k8sClient.Create(ctx, &namespace)
|
|
}, 3*time.Second, 300*time.Millisecond).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
|
|
|
By("Apply the component definition")
|
|
Expect(k8sClient.Create(ctx, newConfigMapComponent(nsName))).To(Succeed())
|
|
})
|
|
|
|
AfterEach(func() {
|
|
By("Cleaning up resources after each test")
|
|
Expect(k8sClient.DeleteAllOf(ctx, &v1beta1.Application{}, client.InNamespace(nsName))).To(Succeed())
|
|
})
|
|
|
|
AfterAll(func() {
|
|
By("Cleaning up resources after all the test")
|
|
Expect(k8sClient.DeleteAllOf(ctx, &v1beta1.ComponentDefinition{}, client.InNamespace(nsName))).To(Succeed())
|
|
Expect(k8sClient.Delete(ctx, &namespace)).To(Succeed())
|
|
})
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Scenario 1: missing parameter → expect failure
|
|
// -------------------------------------------------------------------------
|
|
It("fails when the required parameter is missing", func() {
|
|
// The webhook uses an informer-cached client. After creating the
|
|
// ComponentDefinition in BeforeAll the cache may not have synced yet,
|
|
// so retry until the webhook can actually find the definition and
|
|
// return the expected "missing parameters" validation error.
|
|
Eventually(func(g Gomega) {
|
|
app := appWithWorkflow.DeepCopy()
|
|
app.Name = "app-missing-param"
|
|
app.Namespace = nsName
|
|
|
|
err := k8sClient.Create(ctx, app)
|
|
g.Expect(err).To(HaveOccurred())
|
|
g.Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(`component %q: missing parameters: secondkey.value2.value3.value5`, "configmap-component")))
|
|
}, 30*time.Second, 2*time.Second).Should(Succeed())
|
|
})
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Scenario 2: param provided via workflow → expect success
|
|
// -------------------------------------------------------------------------
|
|
It("succeeds when the parameter is provided in the workflow", func() {
|
|
Eventually(func() error {
|
|
app := appWithWorkflow.DeepCopy()
|
|
app.Name = "app-with-param-wf"
|
|
app.Namespace = nsName
|
|
|
|
// inject missing parameter
|
|
app.Spec.Workflow.Steps[0].Inputs = append(app.Spec.Workflow.Steps[0].Inputs,
|
|
wfTypesv1alpha1.InputItem{
|
|
ParameterKey: "secondkey.value2.value3.value5",
|
|
From: "dummy",
|
|
})
|
|
|
|
return k8sClient.Create(ctx, app)
|
|
}, 30*time.Second, 2*time.Second).Should(Succeed())
|
|
})
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Scenario 3: param provided via policy → expect success
|
|
// -------------------------------------------------------------------------
|
|
It("succeeds when the parameter is provided in a policy", func() {
|
|
Eventually(func() error {
|
|
app := appWithPolicy.DeepCopy()
|
|
app.Name = "app-with-param-policy"
|
|
app.Namespace = nsName
|
|
|
|
return k8sClient.Create(ctx, app)
|
|
}, 30*time.Second, 2*time.Second).Should(Succeed())
|
|
})
|
|
})
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* Helpers */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
func newConfigMapComponent(namespace string) *v1beta1.ComponentDefinition {
|
|
return &v1beta1.ComponentDefinition{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "ComponentDefinition",
|
|
APIVersion: "core.oam.dev/v1beta1",
|
|
},
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "configmap-component",
|
|
Namespace: namespace, // set it here
|
|
},
|
|
Spec: v1beta1.ComponentDefinitionSpec{
|
|
Schematic: &common.Schematic{
|
|
CUE: &common.CUE{Template: configMapOutputTemp},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
var configMapOutputTemp = `
|
|
parameter: {
|
|
firstkey: string & !="" & !~".*-$"
|
|
secondkey: {
|
|
value1: string
|
|
value2: {
|
|
value3: {
|
|
value4: *"default-value-2" | string
|
|
value5: string
|
|
}
|
|
}
|
|
}
|
|
thirdkey?: string
|
|
}
|
|
output: {
|
|
apiVersion: "v1"
|
|
kind: "ConfigMap"
|
|
metadata: { name: context.name }
|
|
data: {
|
|
one: parameter.firstkey
|
|
two: parameter.secondkey.value2.value3.value5
|
|
three: parameter.secondkey.value1
|
|
four: parameter.thirdkey
|
|
}
|
|
}
|
|
`
|
|
|
|
var appWithWorkflow = v1beta1.Application{
|
|
Spec: v1beta1.ApplicationSpec{
|
|
Components: []common.ApplicationComponent{{
|
|
Name: "configmap-component",
|
|
Type: "configmap-component",
|
|
Properties: &runtime.RawExtension{Raw: []byte(`{
|
|
"secondkey": { "value2": { "value3": { "value4": "1" } } }
|
|
}`)},
|
|
}},
|
|
Workflow: &v1beta1.Workflow{
|
|
Steps: []wfTypesv1alpha1.WorkflowStep{{
|
|
WorkflowStepBase: wfTypesv1alpha1.WorkflowStepBase{
|
|
Name: "apply",
|
|
Type: "apply-component",
|
|
Inputs: wfTypesv1alpha1.StepInputs{
|
|
{ParameterKey: "firstkey", From: "dummy1"},
|
|
{ParameterKey: "secondkey.value1", From: "dummy2"},
|
|
{ParameterKey: "thirdkey", From: "dummy3"},
|
|
},
|
|
Properties: util.Object2RawExtension(map[string]any{"component": "express-server"}),
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
}
|
|
|
|
var appWithPolicy = v1beta1.Application{
|
|
Spec: v1beta1.ApplicationSpec{
|
|
Components: []common.ApplicationComponent{{
|
|
Name: "app-policy",
|
|
Type: "configmap-component",
|
|
Properties: &runtime.RawExtension{Raw: []byte(`{
|
|
"secondkey": { "value2": { "value3": { "value4": "1" } } }
|
|
}`)},
|
|
}},
|
|
Policies: []v1beta1.AppPolicy{{
|
|
Name: "override-configmap-data",
|
|
Type: "override",
|
|
Properties: &runtime.RawExtension{Raw: mustJSON(policyProperties)},
|
|
}},
|
|
},
|
|
}
|
|
|
|
var policyProperties = map[string]any{
|
|
"components": []any{map[string]any{
|
|
"name": "express-server",
|
|
"properties": map[string]any{
|
|
"firstkey": "nginx:1.20",
|
|
"secondkey": map[string]any{
|
|
"value1": "abc",
|
|
"value2": map[string]any{
|
|
"value3": map[string]any{
|
|
"value5": "1",
|
|
},
|
|
},
|
|
},
|
|
"thirdkey": "123",
|
|
},
|
|
}},
|
|
}
|
|
|
|
func mustJSON(v any) []byte {
|
|
out, err := json.Marshal(v)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return out
|
|
}
|