diff --git a/cmd/kyma/alpha/create/module/module.go b/cmd/kyma/alpha/create/module/module.go
index a66327f79..b05e9fad1 100644
--- a/cmd/kyma/alpha/create/module/module.go
+++ b/cmd/kyma/alpha/create/module/module.go
@@ -8,6 +8,9 @@ import (
"path/filepath"
"strings"
+ "github.com/kyma-project/cli/internal/cli"
+ "github.com/kyma-project/cli/internal/nice"
+ "github.com/kyma-project/cli/pkg/module"
"github.com/mandelsoft/vfs/pkg/memoryfs"
"github.com/mandelsoft/vfs/pkg/osfs"
"github.com/mandelsoft/vfs/pkg/vfs"
@@ -16,10 +19,8 @@ import (
"github.com/spf13/cobra"
"go.uber.org/zap"
"golang.org/x/exp/maps"
-
- "github.com/kyma-project/cli/internal/cli"
- "github.com/kyma-project/cli/internal/nice"
- "github.com/kyma-project/cli/pkg/module"
+ "gopkg.in/yaml.v3"
+ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
)
type command struct {
@@ -205,6 +206,11 @@ func configureLegacyFlags(cmd *cobra.Command, o *Options) *cobra.Command {
return cmd
}
+type validator interface {
+ GetCrd() []byte
+ Run(ctx context.Context, log *zap.SugaredLogger) error
+}
+
func (cmd *command) Run(ctx context.Context) error {
osFS := osfs.New()
@@ -249,7 +255,8 @@ func (cmd *command) Run(ctx context.Context) error {
}
cmd.CurrentStep.Successf("Module built")
- if err := cmd.validateDefaultCR(ctx, modDef, l); err != nil {
+ var crValidator validator
+ if crValidator, err = cmd.validateDefaultCR(ctx, modDef, l); err != nil {
return err
}
@@ -350,6 +357,12 @@ func (cmd *command) Run(ctx context.Context) error {
labels["operator.kyma-project.io/internal"] = "true"
}
}
+ isClusterScoped := isCrdClusterScoped(crValidator.GetCrd())
+ if isClusterScoped {
+ annotations["operator.kyma-project.io/is-cluster-scoped"] = "true"
+ } else {
+ annotations["operator.kyma-project.io/is-cluster-scoped"] = "false"
+ }
var channel = cmd.opts.Channel
if modCnf != nil {
@@ -374,15 +387,10 @@ func (cmd *command) Run(ctx context.Context) error {
return nil
}
-func (cmd *command) validateDefaultCR(ctx context.Context, modDef *module.Definition, l *zap.SugaredLogger) error {
+func (cmd *command) validateDefaultCR(ctx context.Context, modDef *module.Definition, l *zap.SugaredLogger) (validator, error) {
cmd.NewStep("Validating Default CR")
- type validator interface {
- Run(ctx context.Context, log *zap.SugaredLogger) error
- }
-
var crValidator validator
-
if cmd.opts.WithModuleConfigFile() {
crValidator = module.NewSingleManifestFileCRValidator(modDef.DefaultCR, modDef.SingleManifestPath)
} else {
@@ -392,12 +400,12 @@ func (cmd *command) validateDefaultCR(ctx context.Context, modDef *module.Defini
if err := crValidator.Run(ctx, l); err != nil {
if errors.Is(err, module.ErrEmptyCR) {
cmd.CurrentStep.Successf("Default CR validation skipped - no default CR")
- return nil
+ return crValidator, nil
}
- return err
+ return crValidator, err
}
cmd.CurrentStep.Successf("Default CR validation succeeded")
- return nil
+ return crValidator, nil
}
func (cmd *command) getRemote(nameMapping module.NameMapping) (*module.Remote, error) {
@@ -515,3 +523,16 @@ func resolveFilePath(given, absolutePrefix string) (string, error) {
return res, nil
}
+
+func isCrdClusterScoped(crdBytes []byte) bool {
+ if crdBytes == nil {
+ return false
+ }
+
+ crd := &apiextensions.CustomResourceDefinition{}
+ if err := yaml.Unmarshal(crdBytes, crd); err != nil {
+ return false
+ }
+
+ return crd.Spec.Scope == apiextensions.ClusterScoped
+}
diff --git a/cmd/kyma/alpha/create/module/module_test.go b/cmd/kyma/alpha/create/module/module_test.go
new file mode 100644
index 000000000..b62fa5142
--- /dev/null
+++ b/cmd/kyma/alpha/create/module/module_test.go
@@ -0,0 +1,45 @@
+package module
+
+import (
+ _ "embed"
+ "testing"
+)
+
+//go:embed testdata/clusterScopedCRD.yaml
+var clusterScopedCrd []byte
+
+//go:embed testdata/namespacedScopedCRD.yaml
+var namespacedScopedCrd []byte
+
+func Test_isCrdClusterScoped(t *testing.T) {
+ type args struct {
+ crdBytes []byte
+ }
+ tests := []struct {
+ name string
+ args args
+ want bool
+ }{
+ {
+ name: "Cluster scoped module",
+ args: args{
+ crdBytes: clusterScopedCrd,
+ },
+ want: true,
+ },
+ {
+ name: "Namespaced scoped module",
+ args: args{
+ crdBytes: namespacedScopedCrd,
+ },
+ want: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := isCrdClusterScoped(tt.args.crdBytes); got != tt.want {
+ t.Errorf("isCrdClusterScoped() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/cmd/kyma/alpha/create/module/testdata/clusterScopedCRD.yaml b/cmd/kyma/alpha/create/module/testdata/clusterScopedCRD.yaml
new file mode 100644
index 000000000..69241aa6b
--- /dev/null
+++ b/cmd/kyma/alpha/create/module/testdata/clusterScopedCRD.yaml
@@ -0,0 +1,351 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.11.3
+ creationTimestamp: null
+ name: logpipelines.telemetry.kyma-project.io
+spec:
+ group: telemetry.kyma-project.io
+ names:
+ kind: LogPipeline
+ listKind: LogPipelineList
+ plural: logpipelines
+ singular: logpipeline
+ scope: Cluster
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .status.conditions[-1].type
+ name: Status
+ type: string
+ - jsonPath: .status.unsupportedMode
+ name: Unsupported-Mode
+ type: boolean
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: LogPipeline is the Schema for the logpipelines API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Defines the desired state of LogPipeline
+ properties:
+ files:
+ items:
+ description: Provides file content to be consumed by a LogPipeline
+ configuration
+ properties:
+ content:
+ type: string
+ name:
+ type: string
+ type: object
+ type: array
+ filters:
+ items:
+ description: Describes a filtering option on the logs of the pipeline.
+ properties:
+ custom:
+ description: 'Custom filter definition in the Fluent Bit syntax.
+ Note: If you use a `custom` filter, you put the LogPipeline
+ in unsupported mode.'
+ type: string
+ type: object
+ type: array
+ input:
+ description: Defines where to collect logs, including selector mechanisms.
+ properties:
+ application:
+ description: Configures in more detail from which containers application
+ logs are enabled as input.
+ properties:
+ containers:
+ description: Describes whether application logs from specific
+ containers are selected. The options are mutually exclusive.
+ properties:
+ exclude:
+ description: Specifies to exclude only the container logs
+ with the specified container names.
+ items:
+ type: string
+ type: array
+ include:
+ description: Specifies to include only the container logs
+ with the specified container names.
+ items:
+ type: string
+ type: array
+ type: object
+ dropLabels:
+ description: Defines whether to drop all Kubernetes labels.
+ The default is `false`.
+ type: boolean
+ keepAnnotations:
+ description: Defines whether to keep all Kubernetes annotations.
+ The default is `false`.
+ type: boolean
+ namespaces:
+ description: Describes whether application logs from specific
+ Namespaces are selected. The options are mutually exclusive.
+ System Namespaces are excluded by default from the collection.
+ properties:
+ exclude:
+ description: Exclude the container logs of the specified
+ Namespace names.
+ items:
+ type: string
+ type: array
+ include:
+ description: Include only the container logs of the specified
+ Namespace names.
+ items:
+ type: string
+ type: array
+ system:
+ description: Set to `true` if collecting from all Namespaces
+ must also include the system Namespaces like kube-system,
+ istio-system, and kyma-system.
+ type: boolean
+ type: object
+ type: object
+ type: object
+ output:
+ description: '[Fluent Bit output](https://docs.fluentbit.io/manual/pipeline/outputs)
+ where you want to push the logs. Only one output can be specified.'
+ properties:
+ custom:
+ description: 'Defines a custom output in the Fluent Bit syntax.
+ Note: If you use a `custom` output, you put the LogPipeline
+ in unsupported mode.'
+ type: string
+ grafana-loki:
+ description: Configures an output to the Kyma-internal Loki instance.
+ [Fluent Bit grafana-loki output](https://grafana.com/docs/loki/v2.2.x/clients/fluentbit/).
+ **Note:** This output is considered legacy and is only provided
+ for backward compatibility with the [deprecated](https://kyma-project.io/blog/2022/11/2/loki-deprecation/)
+ in-cluster Loki instance. It might not be compatible with the
+ latest Loki versions. For integration with a custom Loki installation
+ use the `custom` output with the name `loki` instead, see also
+ [Installing a custom Loki stack in Kyma](https://github.com/kyma-project/examples/tree/main/loki).
+ properties:
+ labels:
+ additionalProperties:
+ type: string
+ description: Labels to set for each log record.
+ type: object
+ removeKeys:
+ description: Attributes to be removed from a log record.
+ items:
+ type: string
+ type: array
+ url:
+ description: Grafana Loki URL.
+ properties:
+ value:
+ description: Value that can contain references to Secret
+ values.
+ type: string
+ valueFrom:
+ properties:
+ secretKeyRef:
+ description: Refers to a key in a Secret. You must
+ provide `name` and `namespace` of the Secret, as
+ well as the name of the `key`.
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: object
+ type: object
+ type: object
+ http:
+ description: Configures an HTTP-based output compatible with the
+ Fluent Bit HTTP output plugin.
+ properties:
+ compress:
+ description: Defines the compression algorithm to use.
+ type: string
+ dedot:
+ description: Enables de-dotting of Kubernetes labels and annotations
+ for compatibility with ElasticSearch based backends. Dots
+ (.) will be replaced by underscores (_). Default is `false`.
+ type: boolean
+ format:
+ description: Data format to be used in the HTTP request body.
+ Default is `json`.
+ type: string
+ host:
+ description: Defines the host of the HTTP receiver.
+ properties:
+ value:
+ description: Value that can contain references to Secret
+ values.
+ type: string
+ valueFrom:
+ properties:
+ secretKeyRef:
+ description: Refers to a key in a Secret. You must
+ provide `name` and `namespace` of the Secret, as
+ well as the name of the `key`.
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: object
+ type: object
+ password:
+ description: Defines the basic auth password.
+ properties:
+ value:
+ description: Value that can contain references to Secret
+ values.
+ type: string
+ valueFrom:
+ properties:
+ secretKeyRef:
+ description: Refers to a key in a Secret. You must
+ provide `name` and `namespace` of the Secret, as
+ well as the name of the `key`.
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: object
+ type: object
+ port:
+ description: Defines the port of the HTTP receiver. Default
+ is 443.
+ type: string
+ tls:
+ description: Configures TLS for the HTTP target server.
+ properties:
+ disabled:
+ description: Indicates if TLS is disabled or enabled.
+ Default is `false`.
+ type: boolean
+ skipCertificateValidation:
+ description: If `true`, the validation of certificates
+ is skipped. Default is `false`.
+ type: boolean
+ type: object
+ uri:
+ description: Defines the URI of the HTTP receiver. Default
+ is "/".
+ type: string
+ user:
+ description: Defines the basic auth user.
+ properties:
+ value:
+ description: Value that can contain references to Secret
+ values.
+ type: string
+ valueFrom:
+ properties:
+ secretKeyRef:
+ description: Refers to a key in a Secret. You must
+ provide `name` and `namespace` of the Secret, as
+ well as the name of the `key`.
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: object
+ type: object
+ type: object
+ type: object
+ variables:
+ description: A list of mappings from Kubernetes Secret keys to environment
+ variables. Mapped keys are mounted as environment variables, so
+ that they are available as [Variables](https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/classic-mode/variables)
+ in the sections.
+ items:
+ description: References a Kubernetes secret that should be provided
+ as environment variable to Fluent Bit
+ properties:
+ name:
+ description: Name of the variable to map.
+ type: string
+ valueFrom:
+ properties:
+ secretKeyRef:
+ description: Refers to a key in a Secret. You must provide
+ `name` and `namespace` of the Secret, as well as the name
+ of the `key`.
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ type: object
+ type: object
+ type: array
+ type: object
+ status:
+ description: Shows the observed state of the LogPipeline
+ properties:
+ conditions:
+ description: An array of conditions describing the status of the pipeline.
+ items:
+ description: LogPipelineCondition contains details for the current
+ condition of this LogPipeline
+ properties:
+ lastTransitionTime:
+ description: An array of conditions describing the status of
+ the pipeline.
+ format: date-time
+ type: string
+ reason:
+ description: An array of conditions describing the status of
+ the pipeline.
+ type: string
+ type:
+ description: 'The possible transition types are:
- `Running`:
+ The instance is ready and usable.
- `Pending`: The pipeline
+ is being activated.'
+ type: string
+ type: object
+ type: array
+ unsupportedMode:
+ description: Is active when the LogPipeline uses a `custom` output
+ or filter; see [unsupported mode](https://kyma-project.io/docs/kyma/latest/01-overview/telemetry/telemetry-02-logs/#unsupported-mode).
+ type: boolean
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
\ No newline at end of file
diff --git a/cmd/kyma/alpha/create/module/testdata/namespacedScopedCRD.yaml b/cmd/kyma/alpha/create/module/testdata/namespacedScopedCRD.yaml
new file mode 100644
index 000000000..9165437e7
--- /dev/null
+++ b/cmd/kyma/alpha/create/module/testdata/namespacedScopedCRD.yaml
@@ -0,0 +1,137 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.9.2
+ creationTimestamp: null
+ name: samples.operator.kyma-project.io
+spec:
+ group: operator.kyma-project.io
+ names:
+ kind: Sample
+ listKind: SampleList
+ plural: samples
+ singular: sample
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .status.state
+ name: State
+ type: string
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: Sample is the Schema for the samples API.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ resourceFilePath:
+ description: ResourceFilePath indicates the local dir path containing
+ a .yaml or .yml, with all required resources to be processed
+ type: string
+ type: object
+ status:
+ properties:
+ conditions:
+ description: Conditions contain a set of conditionals to determine
+ the State of Status. If all Conditions are met, State is expected
+ to be in StateReady.
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource. --- This struct is intended for direct
+ use as an array at the field path .status.conditions. For example,
+ \n type FooStatus struct{ // Represents the observations of a
+ foo's current state. // Known .status.conditions.type are: \"Available\",
+ \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
+ // +listType=map // +listMapKey=type Conditions []metav1.Condition
+ `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
+ protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
+ properties:
+ lastTransitionTime:
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another. This should be when
+ the underlying condition changed. If that is not known, then
+ using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: message is a human readable message indicating
+ details about the transition. This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon. For instance, if .metadata.generation
+ is currently 12, but the .status.conditions[x].observedGeneration
+ is 9, the condition is out of date with respect to the current
+ state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition. Producers
+ of specific condition types may define expected values and
+ meanings for this field, and whether the values are considered
+ a guaranteed API. The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ --- Many .condition.type values are consistent across resources
+ like Available, but because arbitrary conditions can be useful
+ (see .node.status.conditions), the ability to deconflict is
+ important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ state:
+ description: State signifies current state of Module CR. Value can
+ be one of ("Ready", "Processing", "Error", "Deleting").
+ enum:
+ - Processing
+ - Deleting
+ - Ready
+ - Error
+ - Warning
+ - ""
+ type: string
+ required:
+ - state
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 71625b10c..f6047765e 100644
--- a/go.mod
+++ b/go.mod
@@ -26,11 +26,11 @@ require (
github.com/go-logr/logr v1.2.4
github.com/go-logr/zapr v1.2.3
github.com/imdario/mergo v0.3.15
- github.com/kyma-incubator/reconciler v0.0.0-20230720145416-32bfb53785f1
+ github.com/kyma-incubator/reconciler v0.0.0-20230811075910-e99144248b04
github.com/kyma-project/hydroform/function v0.0.0-20230628151226-25b31247e585
github.com/kyma-project/hydroform/provision v0.0.0-20230418133637-1ea26b368bb6
github.com/kyma-project/lifecycle-manager v0.0.0-20230626125722-e28fc6438d83
- github.com/mandelsoft/vfs v0.0.0-20220805210647-bf14a11bfe31
+ github.com/mandelsoft/vfs v0.0.0-20230714093241-d557f163aecd
github.com/open-component-model/ocm v0.3.0-rc.1
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc2
@@ -254,14 +254,14 @@ require (
go.starlark.net v0.0.0-20230128213706-3f75dec8e403 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
- golang.org/x/crypto v0.9.0 // indirect
+ golang.org/x/crypto v0.10.0 // indirect
golang.org/x/mod v0.9.0 // indirect
- golang.org/x/net v0.10.0 // indirect
+ golang.org/x/net v0.11.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/sync v0.1.0 // indirect
- golang.org/x/sys v0.8.0 // indirect
- golang.org/x/term v0.8.0 // indirect
- golang.org/x/text v0.9.0 // indirect
+ golang.org/x/sys v0.9.0 // indirect
+ golang.org/x/term v0.9.0 // indirect
+ golang.org/x/text v0.10.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.7.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
diff --git a/go.sum b/go.sum
index 1ed3588d9..a0d92524d 100644
--- a/go.sum
+++ b/go.sum
@@ -1173,8 +1173,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
-github.com/kyma-incubator/reconciler v0.0.0-20230720145416-32bfb53785f1 h1:GtieKj9fCIlvVnfjcCvQ7R6aOAuFSfHnZFkoVLssQCI=
-github.com/kyma-incubator/reconciler v0.0.0-20230720145416-32bfb53785f1/go.mod h1:hJnoGbxdqK4urAPkU8J1OxFXVqPc9pA7MlIL321xK3E=
+github.com/kyma-incubator/reconciler v0.0.0-20230811075910-e99144248b04 h1:JRKd3v6qI/PD62x9X229IyT3clra/cr1BIRvE1TQ110=
+github.com/kyma-incubator/reconciler v0.0.0-20230811075910-e99144248b04/go.mod h1:hJnoGbxdqK4urAPkU8J1OxFXVqPc9pA7MlIL321xK3E=
github.com/kyma-project/hydroform/function v0.0.0-20230628151226-25b31247e585 h1:+fs52VM2jVQuVHWpcSVGfD9RXyao3izEm5Z+HYlJ5lk=
github.com/kyma-project/hydroform/function v0.0.0-20230628151226-25b31247e585/go.mod h1:aNqrx5xoV2sOw5FZFShUzFLpc5VJku9YhokKC3PyQro=
github.com/kyma-project/hydroform/provision v0.0.0-20230418133637-1ea26b368bb6 h1:k8TsRKhbYr+uQ1Glpbwii9kBqMPSFEZdMSov9KJjgiA=
@@ -1231,8 +1231,8 @@ github.com/mandelsoft/logging v0.0.0-20221114215048-ab754b164dd6/go.mod h1:vxGpz
github.com/mandelsoft/spiff v1.7.0-beta-3 h1:AvZldpnctpyfQqtAA5uxokD5rlCK52mGAXxg7tnW5Ag=
github.com/mandelsoft/spiff v1.7.0-beta-3/go.mod h1:3Kg6qrggWO4oc1k++acd6xhcWisJ2YkzxpVZpuYONGg=
github.com/mandelsoft/vfs v0.0.0-20201002080026-d03d33d5889a/go.mod h1:74aV7kulg9C434HiI3zNALN79QHc9IZMN+SI4UdLn14=
-github.com/mandelsoft/vfs v0.0.0-20220805210647-bf14a11bfe31 h1:5gmUtnP0NYOODvS/gTeQOJKSu4W8bOUImDiKdAb/j1A=
-github.com/mandelsoft/vfs v0.0.0-20220805210647-bf14a11bfe31/go.mod h1:74aV7kulg9C434HiI3zNALN79QHc9IZMN+SI4UdLn14=
+github.com/mandelsoft/vfs v0.0.0-20230714093241-d557f163aecd h1:bp5Qgw/7gqjGU9jNLCMSCDEGw3r1uIxMju6V+F18GbY=
+github.com/mandelsoft/vfs v0.0.0-20230714093241-d557f163aecd/go.mod h1:k83vb5I4cqRGJh3TUUVbf2oTF8FrYhvixQ+FwIAgP1Y=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
@@ -1886,8 +1886,8 @@ golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
-golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
-golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
+golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -2024,8 +2024,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
+golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -2198,8 +2198,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -2210,8 +2210,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
+golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2226,8 +2226,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/pkg/module/kubebuilder/project.go b/pkg/module/kubebuilder/project.go
index 11bf057da..835c0a6c3 100644
--- a/pkg/module/kubebuilder/project.go
+++ b/pkg/module/kubebuilder/project.go
@@ -18,7 +18,6 @@ const (
V4alpha = "go.kubebuilder.io/v4-alpha"
projectFile = "PROJECT"
- configFile = "config.yaml"
defaultKustomization = "config/default"
samplesPath = "config/samples/"
OutputPath = "manifests"
@@ -88,18 +87,6 @@ func (p *Project) Build(name string) (string, error) {
return renderedManifestPath, nil
}
-func (p *Project) Config() (string, error) {
- configPath := filepath.Join(p.path, configFile)
- info, err := os.Stat(configPath)
- if err != nil {
- return "", err
- }
- if info.IsDir() {
- return "", fmt.Errorf("expected file but found directory at %q", configPath)
- }
- return configPath, nil
-}
-
// DefaultCR checks the samples of the project to obtain the default CR for the operator and returns its contents.
// Should there be several sample files, the user will be asked to specify which one to use.
func (p *Project) DefaultCR(s step.Step) ([]byte, error) {
diff --git a/pkg/module/resources.go b/pkg/module/resources.go
index 60e2420e5..407e71dcb 100644
--- a/pkg/module/resources.go
+++ b/pkg/module/resources.go
@@ -234,17 +234,6 @@ func inspectProject(def *Definition, p *kubebuilder.Project, layers []Layer, s s
return err
}
- // config.yaml -> layer 2
- if configPath, err := p.Config(); err == nil {
- def.Layers = append(def.Layers, Layer{
- name: configLayerName,
- resourceType: typeYaml,
- path: configPath,
- })
- } else if !errors.Is(err, os.ErrNotExist) {
- return fmt.Errorf("error while determining config layer: %w", err)
- }
-
// Add default CR if generating template
var cr []byte
if def.RegistryURL != "" {
diff --git a/pkg/module/validation.go b/pkg/module/validation.go
index 91dab4396..c13cc9b13 100644
--- a/pkg/module/validation.go
+++ b/pkg/module/validation.go
@@ -10,10 +10,9 @@ import (
"strings"
"time"
- "github.com/kyma-project/cli/pkg/module/kubebuilder"
-
setup "github.com/kyma-project/cli/internal/cli/setup/envtest"
"github.com/kyma-project/cli/internal/kube"
+ "github.com/kyma-project/cli/pkg/module/kubebuilder"
"go.uber.org/zap"
"gopkg.in/yaml.v3"
amv "k8s.io/apimachinery/pkg/util/validation"
@@ -24,6 +23,7 @@ var ErrEmptyCR = errors.New("provided CR is empty")
type DefaultCRValidator struct {
crdSearchDir string
crData []byte
+ crd []byte
}
func NewDefaultCRValidator(cr []byte, modulePath string) *DefaultCRValidator {
@@ -51,13 +51,14 @@ func (v *DefaultCRValidator) Run(ctx context.Context, log *zap.SugaredLogger) er
}
// find the file containing the CRD for given group and kind
- crdFound, crdFilePath, err := findCRDFileFor(group, kind, v.crdSearchDir)
+ crd, crdFilePath, err := findCRDFileFor(group, kind, v.crdSearchDir)
if err != nil {
return fmt.Errorf("error finding CRD file in the %q directory: %w", v.crdSearchDir, err)
}
- if !crdFound {
+ if crd == nil {
return fmt.Errorf("can't find the CRD for (group: %q, kind %q)", group, kind)
}
+ v.crd = crd
return runTestEnv(ctx, log, crdFilePath, crMap)
}
@@ -200,42 +201,43 @@ func renderYamlFromMap(modelMap map[string]interface{}) ([]byte, error) {
}
// findCRDFileFor returns path to the file with a CRD definition for the given group and kind, if exists.
-// It looks in the dirPath directory and all of its subdirectories, recursively. The first parameter is true if the file is found, it's false otherwise.
-func findCRDFileFor(group, kind, dirPath string) (bool, string, error) {
+// It looks in the dirPath directory and all of its subdirectories, recursively.
+func findCRDFileFor(group, kind, dirPath string) ([]byte, string, error) {
//list all files in the dirPath and all it's subdirectories, recursively
files, err := listFiles(dirPath)
if err != nil {
- return false, "", fmt.Errorf("error listing files in %q directory: %w", dirPath, err)
+ return nil, "", fmt.Errorf("error listing files in %q directory: %w", dirPath, err)
}
var found string
+ var crd []byte
for _, f := range files {
- ok, err := isCRDFileFor(group, kind, f)
+ crd, err = getCRDFileFor(group, kind, f)
if err != nil {
//Error is expected. Either the file is not YAML, or it's not a CRD, or it's a CRD but not the one we're looking for.
continue
}
- if ok {
+ if crd != nil {
found = f
break
}
}
if found != "" {
- return true, found, nil
+ return crd, found, nil
}
- return false, "", nil
+ return nil, "", nil
}
-// isCRDFileFor checks if the given file is a CRD for given group and kind.
-func isCRDFileFor(group, kind, filePath string) (bool, error) {
+// getCRDFileFor returns the crd if the given file is a CRD for given group and kind.
+func getCRDFileFor(group, kind, filePath string) ([]byte, error) {
res, err := getCRDFromFile(group, kind, filePath)
if err != nil {
- return false, err
+ return nil, err
}
- return res != nil, nil
+ return res, nil
}
// getCRDFromFile tries to find a CRD for given group and kind in the given multi-document YAML file. Returns a generic map representation of the CRD
@@ -354,6 +356,7 @@ func ValidateName(name string) error {
type SingleManifestFileCRValidator struct {
manifestPath string
crData []byte
+ crd []byte
}
func NewSingleManifestFileCRValidator(cr []byte, manifestPath string) *SingleManifestFileCRValidator {
@@ -387,6 +390,7 @@ func (v *SingleManifestFileCRValidator) Run(ctx context.Context, log *zap.Sugare
if crdBytes == nil {
return fmt.Errorf("can't find the CRD for (group: %q, kind %q)", group, kind)
}
+ v.crd = crdBytes
// store extracted CRD in a temp file
tempDir, err := os.MkdirTemp("", "temporary-crd")
@@ -408,3 +412,11 @@ func (v *SingleManifestFileCRValidator) Run(ctx context.Context, log *zap.Sugare
// run testEnv using the temporary file with extracted CRD
return runTestEnv(ctx, log, tempCRDFile, crMap)
}
+
+func (v *SingleManifestFileCRValidator) GetCrd() []byte {
+ return v.crd
+}
+
+func (v *DefaultCRValidator) GetCrd() []byte {
+ return v.crd
+}