mirror of
https://github.com/kubevela/kubevela.git
synced 2026-05-20 00:07:27 +00:00
Replace the three-state field marker system (Optional/Mandatory/Required)
with a simpler two-state system where the default behavior produces
`field: type` (no marker), `.Required()` produces `field!: type`, and
`.Optional()` produces `field?: type`.
- Remove Mandatory(), IsMandatory(), ForceOptional(), IsForceOptional()
from all param types, StructField, Param interface, and CUE generator
- Replace `mandatory` and `forceOptional` fields with `optional` field
in baseParam and StructField
- Simplify CUE marker resolution to: default=none, Required="!",
Optional="?"
- Remove BeMandatory() matcher and mandatoryParam interface
- Migrate all test usages: .Mandatory() removed (now default behavior),
.ForceOptional() replaced with .Optional()
Signed-off-by: Jerrin Francis <jerrinfrancis7@gmail.com>
843 lines
24 KiB
Go
843 lines
24 KiB
Go
/*
|
|
Copyright 2025 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 defkit_test
|
|
|
|
import (
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
|
|
"github.com/oam-dev/kubevela/pkg/definition/defkit"
|
|
)
|
|
|
|
var _ = Describe("VelaContext", func() {
|
|
|
|
Context("VelaCtx", func() {
|
|
It("should create a context instance", func() {
|
|
vela := defkit.VelaCtx()
|
|
Expect(vela).NotTo(BeNil())
|
|
})
|
|
})
|
|
|
|
Context("Basic Context References", func() {
|
|
var vela *defkit.VelaContext
|
|
|
|
BeforeEach(func() {
|
|
vela = defkit.VelaCtx()
|
|
})
|
|
|
|
It("should return name reference", func() {
|
|
ref := vela.Name()
|
|
Expect(ref.Path()).To(Equal("context.name"))
|
|
})
|
|
|
|
It("should return namespace reference", func() {
|
|
ref := vela.Namespace()
|
|
Expect(ref.Path()).To(Equal("context.namespace"))
|
|
})
|
|
|
|
It("should return appName reference", func() {
|
|
ref := vela.AppName()
|
|
Expect(ref.Path()).To(Equal("context.appName"))
|
|
})
|
|
|
|
It("should return appRevision reference", func() {
|
|
ref := vela.AppRevision()
|
|
Expect(ref.Path()).To(Equal("context.appRevision"))
|
|
})
|
|
|
|
It("should return appRevisionNum reference", func() {
|
|
ref := vela.AppRevisionNum()
|
|
Expect(ref.Path()).To(Equal("context.appRevisionNum"))
|
|
})
|
|
})
|
|
|
|
Context("ClusterVersion", func() {
|
|
var vela *defkit.VelaContext
|
|
|
|
BeforeEach(func() {
|
|
vela = defkit.VelaCtx()
|
|
})
|
|
|
|
It("should return cluster version reference", func() {
|
|
ref := vela.ClusterVersion()
|
|
Expect(ref.Path()).To(Equal("context.clusterVersion"))
|
|
})
|
|
|
|
It("should return major version reference", func() {
|
|
ref := vela.ClusterVersion().Major()
|
|
Expect(ref.Path()).To(Equal("context.clusterVersion.major"))
|
|
})
|
|
|
|
It("should return minor version reference", func() {
|
|
ref := vela.ClusterVersion().Minor()
|
|
Expect(ref.Path()).To(Equal("context.clusterVersion.minor"))
|
|
})
|
|
|
|
It("should return patch version reference", func() {
|
|
ref := vela.ClusterVersion().Patch()
|
|
Expect(ref.Path()).To(Equal("context.clusterVersion.patch"))
|
|
})
|
|
|
|
It("should return gitVersion reference", func() {
|
|
ref := vela.ClusterVersion().GitVersion()
|
|
Expect(ref.Path()).To(Equal("context.clusterVersion.gitVersion"))
|
|
})
|
|
})
|
|
|
|
Context("Additional VelaContext Methods", func() {
|
|
var vela *defkit.VelaContext
|
|
|
|
BeforeEach(func() {
|
|
vela = defkit.VelaCtx()
|
|
})
|
|
|
|
It("should return revision reference", func() {
|
|
ref := vela.Revision()
|
|
Expect(ref.Path()).To(Equal("context.revision"))
|
|
})
|
|
|
|
It("should return output reference", func() {
|
|
ref := vela.Output()
|
|
Expect(ref.Path()).To(Equal("context.output"))
|
|
})
|
|
|
|
It("should return outputs reference with name", func() {
|
|
ref := vela.Outputs("service")
|
|
Expect(ref.Path()).To(Equal("context.outputs.service"))
|
|
})
|
|
|
|
It("should return outputs reference for configmap", func() {
|
|
ref := vela.Outputs("configmap")
|
|
Expect(ref.Path()).To(Equal("context.outputs.configmap"))
|
|
})
|
|
})
|
|
|
|
Context("ContextRef String Method", func() {
|
|
It("should return string representation for name", func() {
|
|
vela := defkit.VelaCtx()
|
|
ref := vela.Name()
|
|
Expect(ref.String()).To(Equal("$(context.name)"))
|
|
})
|
|
|
|
It("should return string representation for namespace", func() {
|
|
vela := defkit.VelaCtx()
|
|
ref := vela.Namespace()
|
|
Expect(ref.String()).To(Equal("$(context.namespace)"))
|
|
})
|
|
|
|
It("should return string representation for appName", func() {
|
|
vela := defkit.VelaCtx()
|
|
ref := vela.AppName()
|
|
Expect(ref.String()).To(Equal("$(context.appName)"))
|
|
})
|
|
|
|
It("should return string representation for revision", func() {
|
|
vela := defkit.VelaCtx()
|
|
ref := vela.Revision()
|
|
Expect(ref.String()).To(Equal("$(context.revision)"))
|
|
})
|
|
|
|
It("should return string representation for output", func() {
|
|
vela := defkit.VelaCtx()
|
|
ref := vela.Output()
|
|
Expect(ref.String()).To(Equal("$(context.output)"))
|
|
})
|
|
|
|
It("should return string representation for outputs", func() {
|
|
vela := defkit.VelaCtx()
|
|
ref := vela.Outputs("service")
|
|
Expect(ref.String()).To(Equal("$(context.outputs.service)"))
|
|
})
|
|
})
|
|
|
|
Context("Context in Expressions", func() {
|
|
It("should use context ref in comparison", func() {
|
|
vela := defkit.VelaCtx()
|
|
cond := defkit.Ge(vela.ClusterVersion().Minor(), defkit.Lit(21))
|
|
Expect(cond.Left()).To(Equal(vela.ClusterVersion().Minor()))
|
|
})
|
|
|
|
It("should use context ref in resource Set", func() {
|
|
vela := defkit.VelaCtx()
|
|
r := defkit.NewResource("v1", "ConfigMap").
|
|
Set("metadata.name", vela.Name()).
|
|
Set("metadata.namespace", vela.Namespace())
|
|
Expect(r.Ops()).To(HaveLen(2))
|
|
})
|
|
})
|
|
})
|
|
|
|
var _ = Describe("TestContext", func() {
|
|
|
|
Context("TestContextBuilder", func() {
|
|
It("should create test context with defaults", func() {
|
|
ctx := defkit.TestContext()
|
|
Expect(ctx.Name()).To(Equal("test-component"))
|
|
Expect(ctx.Namespace()).To(Equal("default"))
|
|
Expect(ctx.AppName()).To(Equal("test-app"))
|
|
})
|
|
|
|
It("should set custom name", func() {
|
|
ctx := defkit.TestContext().WithName("my-component")
|
|
Expect(ctx.Name()).To(Equal("my-component"))
|
|
})
|
|
|
|
It("should set custom namespace", func() {
|
|
ctx := defkit.TestContext().WithNamespace("production")
|
|
Expect(ctx.Namespace()).To(Equal("production"))
|
|
})
|
|
|
|
It("should set app name", func() {
|
|
ctx := defkit.TestContext().WithAppName("my-app")
|
|
Expect(ctx.AppName()).To(Equal("my-app"))
|
|
})
|
|
|
|
It("should set single parameter", func() {
|
|
ctx := defkit.TestContext().WithParam("replicas", 3)
|
|
Expect(ctx.Params()["replicas"]).To(Equal(3))
|
|
})
|
|
|
|
It("should set multiple parameters", func() {
|
|
ctx := defkit.TestContext().WithParams(map[string]any{
|
|
"image": "nginx:latest",
|
|
"replicas": 5,
|
|
"port": 8080,
|
|
})
|
|
Expect(ctx.Params()["image"]).To(Equal("nginx:latest"))
|
|
Expect(ctx.Params()["replicas"]).To(Equal(5))
|
|
Expect(ctx.Params()["port"]).To(Equal(8080))
|
|
})
|
|
|
|
It("should set cluster version", func() {
|
|
ctx := defkit.TestContext().WithClusterVersion(1, 30)
|
|
major, minor := ctx.ClusterVersion()
|
|
Expect(major).To(Equal(1))
|
|
Expect(minor).To(Equal(30))
|
|
})
|
|
|
|
It("should chain configuration methods", func() {
|
|
ctx := defkit.TestContext().
|
|
WithName("web").
|
|
WithNamespace("prod").
|
|
WithParam("image", "nginx").
|
|
WithParam("replicas", 3).
|
|
WithClusterVersion(1, 28)
|
|
|
|
Expect(ctx.Name()).To(Equal("web"))
|
|
Expect(ctx.Namespace()).To(Equal("prod"))
|
|
Expect(ctx.Params()["image"]).To(Equal("nginx"))
|
|
Expect(ctx.Params()["replicas"]).To(Equal(3))
|
|
major, minor := ctx.ClusterVersion()
|
|
Expect(major).To(Equal(1))
|
|
Expect(minor).To(Equal(28))
|
|
})
|
|
})
|
|
|
|
Context("Render", func() {
|
|
var (
|
|
image *defkit.StringParam
|
|
replicas *defkit.IntParam
|
|
port *defkit.IntParam
|
|
comp *defkit.ComponentDefinition
|
|
)
|
|
|
|
BeforeEach(func() {
|
|
image = defkit.String("image")
|
|
replicas = defkit.Int("replicas").Default(1)
|
|
port = defkit.Int("port").Default(80)
|
|
|
|
comp = defkit.NewComponent("webservice").
|
|
Description("Web service component").
|
|
Workload("apps/v1", "Deployment").
|
|
Params(image, replicas, port).
|
|
Template(func(tpl *defkit.Template) {
|
|
vela := defkit.VelaCtx()
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
Set("metadata.name", vela.Name()).
|
|
Set("spec.replicas", replicas).
|
|
Set("spec.template.spec.containers[0].image", image).
|
|
Set("spec.template.spec.containers[0].ports[0].containerPort", port),
|
|
)
|
|
tpl.Outputs("service",
|
|
defkit.NewResource("v1", "Service").
|
|
Set("metadata.name", vela.Name()).
|
|
Set("spec.ports[0].port", port),
|
|
)
|
|
})
|
|
})
|
|
|
|
It("should render component with parameter values", func() {
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithName("my-web").
|
|
WithParam("image", "nginx:1.21").
|
|
WithParam("replicas", 3).
|
|
WithParam("port", 8080),
|
|
)
|
|
|
|
Expect(rendered.APIVersion()).To(Equal("apps/v1"))
|
|
Expect(rendered.Kind()).To(Equal("Deployment"))
|
|
Expect(rendered.Get("metadata.name")).To(Equal("my-web"))
|
|
Expect(rendered.Get("spec.replicas")).To(Equal(3))
|
|
Expect(rendered.Get("spec.template.spec.containers[0].image")).To(Equal("nginx:1.21"))
|
|
Expect(rendered.Get("spec.template.spec.containers[0].ports[0].containerPort")).To(Equal(8080))
|
|
})
|
|
|
|
It("should use default values when parameters not set", func() {
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithName("default-web").
|
|
WithParam("image", "nginx:latest"),
|
|
)
|
|
|
|
Expect(rendered.Get("spec.replicas")).To(Equal(1))
|
|
Expect(rendered.Get("spec.template.spec.containers[0].ports[0].containerPort")).To(Equal(80))
|
|
})
|
|
|
|
It("should render all outputs", func() {
|
|
outputs := comp.RenderAll(
|
|
defkit.TestContext().
|
|
WithName("my-web").
|
|
WithParam("image", "nginx:latest").
|
|
WithParam("port", 9000),
|
|
)
|
|
|
|
Expect(outputs.Primary.Kind()).To(Equal("Deployment"))
|
|
Expect(outputs.Auxiliary).To(HaveKey("service"))
|
|
Expect(outputs.Auxiliary["service"].Kind()).To(Equal("Service"))
|
|
Expect(outputs.Auxiliary["service"].Get("spec.ports[0].port")).To(Equal(9000))
|
|
})
|
|
|
|
It("should resolve context references", func() {
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithName("context-test").
|
|
WithNamespace("test-ns").
|
|
WithParam("image", "test"),
|
|
)
|
|
|
|
Expect(rendered.Get("metadata.name")).To(Equal("context-test"))
|
|
})
|
|
})
|
|
|
|
Context("SetIf with IsSet", func() {
|
|
It("should set field when parameter is set", func() {
|
|
cpu := defkit.String("cpu").Optional()
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(cpu).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "Pod").
|
|
SetIf(cpu.IsSet(), "spec.resources.limits.cpu", cpu),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("cpu", "500m"),
|
|
)
|
|
|
|
Expect(rendered.Get("spec.resources.limits.cpu")).To(Equal("500m"))
|
|
})
|
|
|
|
It("should not set field when parameter is not set", func() {
|
|
cpu := defkit.String("cpu").Optional()
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(cpu).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "Pod").
|
|
SetIf(cpu.IsSet(), "spec.resources.limits.cpu", cpu),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(defkit.TestContext())
|
|
|
|
Expect(rendered.Get("spec.resources.limits.cpu")).To(BeNil())
|
|
})
|
|
})
|
|
|
|
Context("Literal values", func() {
|
|
It("should set literal string values", func() {
|
|
comp := defkit.NewComponent("test").
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
Set("data.key", defkit.Lit("literal-value")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(defkit.TestContext())
|
|
Expect(rendered.Get("data.key")).To(Equal("literal-value"))
|
|
})
|
|
|
|
It("should set literal int values", func() {
|
|
comp := defkit.NewComponent("test").
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
Set("spec.replicas", defkit.Lit(5)),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(defkit.TestContext())
|
|
Expect(rendered.Get("spec.replicas")).To(Equal(5))
|
|
})
|
|
})
|
|
|
|
Context("Comparison conditions in Render", func() {
|
|
It("should evaluate greater-than condition", func() {
|
|
replicas := defkit.Int("replicas")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(replicas).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
SetIf(defkit.Gt(replicas, defkit.Lit(1)), "spec.strategy.type", defkit.Lit("RollingUpdate")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("replicas", 3),
|
|
)
|
|
Expect(rendered.Get("spec.strategy.type")).To(Equal("RollingUpdate"))
|
|
})
|
|
|
|
It("should evaluate less-than condition", func() {
|
|
replicas := defkit.Int("replicas")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(replicas).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
SetIf(defkit.Lt(replicas, defkit.Lit(5)), "spec.minReplicas", replicas),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("replicas", 3),
|
|
)
|
|
Expect(rendered.Get("spec.minReplicas")).To(Equal(3))
|
|
})
|
|
|
|
It("should evaluate greater-than-or-equal condition", func() {
|
|
port := defkit.Int("port")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(port).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "Service").
|
|
SetIf(defkit.Ge(port, defkit.Lit(8080)), "spec.ports[0].port", port),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("port", 8080),
|
|
)
|
|
Expect(rendered.Get("spec.ports[0].port")).To(Equal(8080))
|
|
})
|
|
|
|
It("should evaluate less-than-or-equal condition", func() {
|
|
replicas := defkit.Int("replicas")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(replicas).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
SetIf(defkit.Le(replicas, defkit.Lit(10)), "spec.replicas", replicas),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("replicas", 10),
|
|
)
|
|
Expect(rendered.Get("spec.replicas")).To(Equal(10))
|
|
})
|
|
|
|
It("should evaluate not-equal condition", func() {
|
|
env := defkit.String("env")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(env).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
SetIf(defkit.Ne(env, defkit.Lit("prod")), "spec.debug", defkit.Lit(true)),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("env", "dev"),
|
|
)
|
|
Expect(rendered.Get("spec.debug")).To(Equal(true))
|
|
})
|
|
})
|
|
|
|
Context("Numeric value comparisons", func() {
|
|
It("should compare float values", func() {
|
|
threshold := defkit.Float("threshold")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(threshold).
|
|
Template(func(tpl *defkit.Template) {
|
|
cond := defkit.Gt(threshold, defkit.Lit(0.5))
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
SetIf(cond, "data.highThreshold", defkit.Lit("true")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("threshold", 0.8),
|
|
)
|
|
Expect(rendered.Get("data.highThreshold")).To(Equal("true"))
|
|
})
|
|
|
|
It("should compare int values with different operators", func() {
|
|
priority := defkit.Int("priority")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(priority).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
SetIf(defkit.Ge(priority, defkit.Lit(1)), "data.low", defkit.Lit("yes")).
|
|
SetIf(defkit.Ge(priority, defkit.Lit(5)), "data.medium", defkit.Lit("yes")).
|
|
SetIf(defkit.Ge(priority, defkit.Lit(8)), "data.high", defkit.Lit("yes")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("priority", 6),
|
|
)
|
|
Expect(rendered.Get("data.low")).To(Equal("yes"))
|
|
Expect(rendered.Get("data.medium")).To(Equal("yes"))
|
|
Expect(rendered.Get("data.high")).To(BeNil())
|
|
})
|
|
})
|
|
|
|
Context("Logical conditions in Render", func() {
|
|
It("should evaluate And condition", func() {
|
|
replicas := defkit.Int("replicas")
|
|
cpu := defkit.String("cpu")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(replicas, cpu).
|
|
Template(func(tpl *defkit.Template) {
|
|
cond := defkit.And(
|
|
defkit.Gt(replicas, defkit.Lit(1)),
|
|
cpu.IsSet(),
|
|
)
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
SetIf(cond, "spec.resources.limits.cpu", cpu),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithParam("replicas", 3).
|
|
WithParam("cpu", "500m"),
|
|
)
|
|
Expect(rendered.Get("spec.resources.limits.cpu")).To(Equal("500m"))
|
|
})
|
|
|
|
It("should evaluate Or condition", func() {
|
|
debug := defkit.Bool("debug")
|
|
env := defkit.String("env")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(debug, env).
|
|
Template(func(tpl *defkit.Template) {
|
|
cond := defkit.Or(
|
|
defkit.Eq(debug, defkit.Lit(true)),
|
|
defkit.Eq(env, defkit.Lit("dev")),
|
|
)
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
SetIf(cond, "spec.logging", defkit.Lit("verbose")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithParam("debug", false).
|
|
WithParam("env", "dev"),
|
|
)
|
|
Expect(rendered.Get("spec.logging")).To(Equal("verbose"))
|
|
})
|
|
|
|
It("should evaluate Not condition", func() {
|
|
enabled := defkit.Bool("enabled")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(enabled).
|
|
Template(func(tpl *defkit.Template) {
|
|
cond := defkit.Not(defkit.Eq(enabled, defkit.Lit(true)))
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
SetIf(cond, "spec.paused", defkit.Lit(true)),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("enabled", false),
|
|
)
|
|
Expect(rendered.Get("spec.paused")).To(Equal(true))
|
|
})
|
|
|
|
It("should evaluate nested And/Or conditions", func() {
|
|
replicas := defkit.Int("replicas")
|
|
cpu := defkit.String("cpu")
|
|
memory := defkit.String("memory")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(replicas, cpu, memory).
|
|
Template(func(tpl *defkit.Template) {
|
|
// (replicas > 1) AND (cpu set OR memory set)
|
|
cond := defkit.And(
|
|
defkit.Gt(replicas, defkit.Lit(1)),
|
|
defkit.Or(cpu.IsSet(), memory.IsSet()),
|
|
)
|
|
tpl.Output(
|
|
defkit.NewResource("apps/v1", "Deployment").
|
|
SetIf(cond, "spec.autoscaling", defkit.Lit(true)),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithParam("replicas", 3).
|
|
WithParam("memory", "512Mi"),
|
|
)
|
|
Expect(rendered.Get("spec.autoscaling")).To(Equal(true))
|
|
})
|
|
})
|
|
|
|
Context("If/EndIf blocks in Render", func() {
|
|
It("should evaluate If block when condition is true", func() {
|
|
enabled := defkit.Bool("enabled")
|
|
port := defkit.Int("port")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(enabled, port).
|
|
Template(func(tpl *defkit.Template) {
|
|
cond := defkit.Eq(enabled, defkit.Lit(true))
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "Service").
|
|
Set("metadata.name", defkit.VelaCtx().Name()).
|
|
If(cond).
|
|
Set("spec.ports[0].port", port).
|
|
Set("spec.ports[0].protocol", defkit.Lit("TCP")).
|
|
EndIf(),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithName("my-svc").
|
|
WithParam("enabled", true).
|
|
WithParam("port", 8080),
|
|
)
|
|
|
|
Expect(rendered.Get("metadata.name")).To(Equal("my-svc"))
|
|
Expect(rendered.Get("spec.ports[0].port")).To(Equal(8080))
|
|
Expect(rendered.Get("spec.ports[0].protocol")).To(Equal("TCP"))
|
|
})
|
|
|
|
It("should skip If block when condition is false", func() {
|
|
enabled := defkit.Bool("enabled")
|
|
port := defkit.Int("port")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(enabled, port).
|
|
Template(func(tpl *defkit.Template) {
|
|
cond := defkit.Eq(enabled, defkit.Lit(true))
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "Service").
|
|
Set("metadata.name", defkit.VelaCtx().Name()).
|
|
If(cond).
|
|
Set("spec.ports[0].port", port).
|
|
EndIf(),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithName("my-svc").
|
|
WithParam("enabled", false).
|
|
WithParam("port", 8080),
|
|
)
|
|
|
|
Expect(rendered.Get("metadata.name")).To(Equal("my-svc"))
|
|
Expect(rendered.Get("spec.ports[0].port")).To(BeNil())
|
|
})
|
|
})
|
|
|
|
Context("Array indexing in Render", func() {
|
|
It("should set values at array indices", func() {
|
|
ports := defkit.Array("ports")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(ports).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "Service").
|
|
Set("spec.ports[0].port", defkit.Lit(80)).
|
|
Set("spec.ports[0].name", defkit.Lit("http")).
|
|
Set("spec.ports[1].port", defkit.Lit(443)).
|
|
Set("spec.ports[1].name", defkit.Lit("https")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(defkit.TestContext())
|
|
|
|
Expect(rendered.Get("spec.ports[0].port")).To(Equal(80))
|
|
Expect(rendered.Get("spec.ports[0].name")).To(Equal("http"))
|
|
Expect(rendered.Get("spec.ports[1].port")).To(Equal(443))
|
|
Expect(rendered.Get("spec.ports[1].name")).To(Equal("https"))
|
|
})
|
|
})
|
|
|
|
Context("Context references in Render", func() {
|
|
It("should resolve appRevision context ref", func() {
|
|
comp := defkit.NewComponent("test").
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
Set("metadata.name", defkit.VelaCtx().Name()).
|
|
Set("metadata.labels.app", defkit.VelaCtx().AppName()).
|
|
Set("metadata.labels.revision", defkit.VelaCtx().AppRevision()),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().
|
|
WithName("my-config").
|
|
WithAppName("my-app").
|
|
WithAppRevision("my-app-v1"),
|
|
)
|
|
|
|
Expect(rendered.Get("metadata.name")).To(Equal("my-config"))
|
|
Expect(rendered.Get("metadata.labels.app")).To(Equal("my-app"))
|
|
Expect(rendered.Get("metadata.labels.revision")).To(Equal("my-app-v1"))
|
|
})
|
|
|
|
It("should resolve namespace context ref", func() {
|
|
comp := defkit.NewComponent("test").
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
Set("metadata.namespace", defkit.VelaCtx().Namespace()),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithNamespace("prod"),
|
|
)
|
|
|
|
Expect(rendered.Get("metadata.namespace")).To(Equal("prod"))
|
|
})
|
|
})
|
|
|
|
Context("Different numeric types in comparison", func() {
|
|
It("should compare int64 values", func() {
|
|
count := defkit.Int("count")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(count).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
SetIf(defkit.Gt(count, defkit.Lit(int64(100))), "data.large", defkit.Lit("true")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("count", int64(150)),
|
|
)
|
|
|
|
Expect(rendered.Get("data.large")).To(Equal("true"))
|
|
})
|
|
|
|
It("should compare float32 values", func() {
|
|
ratio := defkit.Float("ratio")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(ratio).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
SetIf(defkit.Lt(ratio, defkit.Lit(float32(0.5))), "data.low", defkit.Lit("true")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("ratio", float32(0.3)),
|
|
)
|
|
|
|
Expect(rendered.Get("data.low")).To(Equal("true"))
|
|
})
|
|
})
|
|
|
|
Context("Boolean parameter conditions", func() {
|
|
It("should evaluate boolean parameter directly", func() {
|
|
debug := defkit.Bool("debug")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(debug).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
SetIf(debug.IsTrue(), "data.debug", defkit.Lit("enabled")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("debug", true),
|
|
)
|
|
|
|
Expect(rendered.Get("data.debug")).To(Equal("enabled"))
|
|
})
|
|
|
|
It("should evaluate boolean false condition", func() {
|
|
enabled := defkit.Bool("enabled")
|
|
|
|
comp := defkit.NewComponent("test").
|
|
Params(enabled).
|
|
Template(func(tpl *defkit.Template) {
|
|
tpl.Output(
|
|
defkit.NewResource("v1", "ConfigMap").
|
|
SetIf(enabled.IsFalse(), "data.disabled", defkit.Lit("true")),
|
|
)
|
|
})
|
|
|
|
rendered := comp.Render(
|
|
defkit.TestContext().WithParam("enabled", false),
|
|
)
|
|
|
|
Expect(rendered.Get("data.disabled")).To(Equal("true"))
|
|
})
|
|
})
|
|
})
|