Skip to content

Commit

Permalink
feat: Add imports to ServiceDeployment CRD (#1083)
Browse files Browse the repository at this point in the history
  • Loading branch information
maciaszczykm authored Jun 20, 2024
1 parent a55ae90 commit 84fd3bd
Show file tree
Hide file tree
Showing 8 changed files with 413 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,77 @@ spec:
description: chart version to use
type: string
type: object
imports:
items:
properties:
stackRef:
description: |-
ObjectReference contains enough information to let you inspect or modify the referred object.
---
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
Those cannot be well described when embedded.
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
and the version of the actual struct is irrelevant.
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: |-
If referring to a piece of an object instead of an entire object, this string
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within a pod, this would take on a value like:
"spec.containers{name}" (where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to have some well-defined way of
referencing a part of an object.
TODO: this design is not final and this field is subject to change in the future.
type: string
kind:
description: |-
Kind of the referent.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
namespace:
description: |-
Namespace of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
type: string
resourceVersion:
description: |-
Specific resourceVersion to which this reference is made, if any.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
type: string
uid:
description: |-
UID of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
type: string
type: object
x-kubernetes-map-type: atomic
required:
- stackRef
type: object
type: array
x-kubernetes-validations:
- message: Imports are immutable
rule: self == oldSelf
kustomize:
properties:
path:
Expand Down
1 change: 1 addition & 0 deletions controller/api/v1alpha1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ func (in *GitRef) Attributes() *console.GitRefAttributes {
return &console.GitRefAttributes{
Ref: in.Ref,
Folder: in.Folder,
Files: in.Files,
}
}

Expand Down
79 changes: 78 additions & 1 deletion controller/api/v1alpha1/servicedeployment_types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package v1alpha1

import (
"encoding/json"

console "github.com/pluralsh/console-client-go"
"github.com/samber/lo"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -23,6 +27,14 @@ type ServiceKustomize struct {
Path string `json:"path"`
}

func (sk *ServiceKustomize) Attributes() *console.KustomizeAttributes {
if sk == nil {
return nil
}

return &console.KustomizeAttributes{Path: sk.Path}
}

type ServiceHelm struct {
// Fetches the helm values from a secret in this cluster, will consider any key with yaml data a values file and merge them iteratively
// +kubebuilder:validation:Optional
Expand Down Expand Up @@ -68,6 +80,43 @@ type SyncConfigAttributes struct {
Annotations map[string]string `json:"annotations,omitempty"`
}

func (sca *SyncConfigAttributes) Attributes() (*console.SyncConfigAttributes, error) {
if sca == nil {
return nil, nil
}

createNamespace := true
if sca.CreateNamespace != nil {
createNamespace = *sca.CreateNamespace
}

var annotations *string
if sca.Annotations != nil {
result, err := json.Marshal(sca.Annotations)
if err != nil {
return nil, err
}
annotations = lo.ToPtr(string(result))
}

var labels *string
if sca.Labels != nil {
result, err := json.Marshal(sca.Labels)
if err != nil {
return nil, err
}
labels = lo.ToPtr(string(result))
}

return &console.SyncConfigAttributes{
CreateNamespace: &createNamespace,
NamespaceMetadata: &console.MetadataAttributes{
Labels: labels,
Annotations: annotations,
},
}, nil
}

type ServiceSpec struct {
// the name of this service, if not provided ServiceDeployment's own name from ServiceDeployment.ObjectMeta will be used.
// +kubebuilder:validation:Optional
Expand Down Expand Up @@ -109,12 +158,40 @@ type ServiceSpec struct {
// Templated should apply liquid templating to raw yaml files, defaults to true
// +kubebuilder:validation:Optional
Templated *bool `json:"templated,omitempty"`

// +kubebuilder:validation:Optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Imports are immutable"
Imports []ServiceImport `json:"imports"`
// Detach determined if user want to delete or detach service
// +kubebuilder:validation:Optional
Detach bool `json:"detach,omitempty"`
}

type ServiceImport struct {
// +kubebuilder:validation:Required
StackRef corev1.ObjectReference `json:"stackRef"`
}

func (ss *ServiceSpec) DependenciesAttribute() []*console.ServiceDependencyAttributes {
if len(ss.Dependencies) < 1 {
return nil
}

deps := make([]*console.ServiceDependencyAttributes, 0)
for _, dep := range ss.Dependencies {
deps = append(deps, &console.ServiceDependencyAttributes{Name: dep.Name})
}

return deps
}

func (ss *ServiceSpec) TemplatedAttribute() *bool {
if ss.Templated == nil {
return lo.ToPtr(true)
}

return ss.Templated
}

type ServiceStatus struct {
Status `json:",inline"`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,77 @@ spec:
description: chart version to use
type: string
type: object
imports:
items:
properties:
stackRef:
description: |-
ObjectReference contains enough information to let you inspect or modify the referred object.
---
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
Those cannot be well described when embedded.
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
and the version of the actual struct is irrelevant.
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: |-
If referring to a piece of an object instead of an entire object, this string
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within a pod, this would take on a value like:
"spec.containers{name}" (where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to have some well-defined way of
referencing a part of an object.
TODO: this design is not final and this field is subject to change in the future.
type: string
kind:
description: |-
Kind of the referent.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
namespace:
description: |-
Namespace of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
type: string
resourceVersion:
description: |-
Specific resourceVersion to which this reference is made, if any.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
type: string
uid:
description: |-
UID of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
type: string
type: object
x-kubernetes-map-type: atomic
required:
- stackRef
type: object
type: array
x-kubernetes-validations:
- message: Imports are immutable
rule: self == oldSelf
kustomize:
properties:
path:
Expand Down
56 changes: 53 additions & 3 deletions controller/config/samples/service_deployment.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,52 @@
apiVersion: deployments.plural.sh/v1alpha1
kind: Cluster
metadata:
name: mgmt
namespace: default
spec:
handle: mgmt
---
apiVersion: deployments.plural.sh/v1alpha1
kind: GitRepository
metadata:
name: test
namespace: default
spec:
url: https://github.com/zreigz/tf-hello.git
---
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: default
data:
secret: dGVzdA==
---
apiVersion: deployments.plural.sh/v1alpha1
kind: InfrastructureStack
metadata:
name: test-stack
namespace: default
spec:
name: "test"
type: TERRAFORM
configuration:
version: "sha-ae2663f-terraform-1.8.2"
image: "ghcr.io/pluralsh/harness"
repositoryRef:
name: test
namespace: default
clusterRef:
name: mgmt
namespace: default
git:
ref: main
folder: terraform
---
apiVersion: deployments.plural.sh/v1alpha1
kind: ServiceDeployment
metadata:
name: k8saws
name: test
namespace: default
spec:
version: 0.0.1
Expand All @@ -10,9 +55,14 @@ spec:
ref: master
repositoryRef:
kind: GitRepository
name: k8shelm
name: test
namespace: default
clusterRef:
kind: Cluster
name: aws
name: mgmt
namespace: default
imports:
- stackRef:
kind: InfrastructureStack
name: test-stack
namespace: default
7 changes: 4 additions & 3 deletions controller/internal/controller/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ func genServiceTemplate(ctx context.Context, c runtimeclient.Client, namespace s
}
if len(srv.Dependencies) > 0 {
serviceTemplate.Dependencies = make([]*console.ServiceDependencyAttributes, 0)
}
for _, dep := range srv.Dependencies {
serviceTemplate.Dependencies = append(serviceTemplate.Dependencies, &console.ServiceDependencyAttributes{Name: dep.Name})

for _, dep := range srv.Dependencies {
serviceTemplate.Dependencies = append(serviceTemplate.Dependencies, &console.ServiceDependencyAttributes{Name: dep.Name})
}
}

if srv.Templated != nil {
Expand Down
Loading

0 comments on commit 84fd3bd

Please sign in to comment.