Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions api/common/v1alpha1/adopt_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package v1alpha1

// AdoptOptions is the options for CRDs to attach to an existing Kong entity.
// +kubebuilder:object:generate=true
// +kubebuilder:validation:XValidation:rule="self.from == oldSelf.from",message="'from'(adopt source) is immutable"
// +kubebuilder:validation:XValidation:rule="self.from == 'konnect' ? has(self.konnect) : true",message="Must specify Konnect options when from='konnect'"
// +kubebuilder:validation:XValidation:rule="has(self.konnect) ? (self.konnect.id == oldSelf.konnect.id) : true",message="konnect.id is immutable"
// +apireference:kgo:include
type AdoptOptions struct {
// From is the source of the entity to adopt from.
// Now 'konnect' is supported.
// +required
// +kubebuilder:validation:Enum=konnect
From AdoptSource `json:"from"`
// Konnect is the options for adopting the entity from Konnect.
// Required when from == 'konnect'.
// +optional
Konnect *AdoptKonnectOptions `json:"konnect,omitempty"`
}

// AdoptSource is the type to define the source of the entity to adopt from.
type AdoptSource string

const (
// AdoptSourceKonnect indicates that the entity is adopted from Konnect.
AdoptSourceKonnect AdoptSource = "konnect"
)

// AdoptKonnectOptions specifies the options for adopting the entity from Konnect.
// +kubebuilder:object:generate=true
// +apireference:kgo:include
type AdoptKonnectOptions struct {
// ID is the Konnect ID of the entity.
// +required
ID string `json:"id"`
}
35 changes: 35 additions & 0 deletions api/common/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions api/configuration/v1alpha1/kongservice_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,19 @@ type KongService struct {

// KongServiceSpec defines specification of a Kong Service.
// +kubebuilder:validation:XValidation:rule="!has(self.controlPlaneRef) ? true : self.controlPlaneRef.type != 'kic'", message="KIC is not supported as control plane"
// +kubebuilder:validation:XValidation:rule="!has(self.adopt) ? true : (has(self.controlPlaneRef) && self.controlPlaneRef.type == 'konnectNamespacedRef')", message="spec.adopt is allowed only when controlPlaneRef is konnectNamespacedRef"
// +kubebuilder:validation:XValidation:rule="(has(oldSelf.adopt) && has(self.adopt)) || (!has(oldSelf.adopt) && !has(self.adopt))", message="Cannot set or unset spec.adopt in updates"
// +apireference:kgo:include
type KongServiceSpec struct {
// ControlPlaneRef is a reference to a ControlPlane this KongService is associated with.
// +kubebuilder:validation:XValidation:message="'konnectID' type is not supported", rule="self.type != 'konnectID'"
// +required
ControlPlaneRef *commonv1alpha1.ControlPlaneRef `json:"controlPlaneRef"`

// Adopt is the options for adopting a service from an existing service in Konnect.
// +optional
Adopt *commonv1alpha1.AdoptOptions `json:"adopt,omitempty"`

KongServiceAPISpec `json:",inline"`
}

Expand Down
5 changes: 5 additions & 0 deletions api/configuration/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,39 @@ spec:
spec:
description: KongServiceSpec defines specification of a Kong Service.
properties:
adopt:
description: Adopt is the options for adopting a service from an existing
service in Konnect.
properties:
from:
description: |-
From is the source of the entity to adopt from.
Now 'konnect' is supported.
enum:
- konnect
type: string
konnect:
description: |-
Konnect is the options for adopting the entity from Konnect.
Required when from == 'konnect'.
properties:
id:
description: ID is the Konnect ID of the entity.
type: string
required:
- id
type: object
required:
- from
type: object
x-kubernetes-validations:
- message: '''from''(adopt source) is immutable'
rule: self.from == oldSelf.from
- message: Must specify Konnect options when from='konnect'
rule: 'self.from == ''konnect'' ? has(self.konnect) : true'
- message: konnect.id is immutable
rule: 'has(self.konnect) ? (self.konnect.id == oldSelf.konnect.id)
: true'
connect_timeout:
description: The timeout in milliseconds for establishing a connection
to the upstream server.
Expand Down Expand Up @@ -198,6 +231,12 @@ spec:
- message: KIC is not supported as control plane
rule: '!has(self.controlPlaneRef) ? true : self.controlPlaneRef.type
!= ''kic'''
- message: spec.adopt is allowed only when controlPlaneRef is konnectNamespacedRef
rule: '!has(self.adopt) ? true : (has(self.controlPlaneRef) && self.controlPlaneRef.type
== ''konnectNamespacedRef'')'
- message: Cannot set or unset spec.adopt in updates
rule: (has(oldSelf.adopt) && has(self.adopt)) || (!has(oldSelf.adopt)
&& !has(self.adopt))
status:
default:
conditions:
Expand Down
40 changes: 40 additions & 0 deletions config/samples/konnect_kongservice_adopt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
kind: KonnectAPIAuthConfiguration
apiVersion: konnect.konghq.com/v1alpha1
metadata:
name: konnect-api-auth-1
namespace: default
spec:
type: token
token: kpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
serverURL: eu.api.konghq.com
---
kind: KonnectGatewayControlPlane
apiVersion: konnect.konghq.com/v1alpha1
metadata:
name: test1
namespace: default
spec:
name: test1
labels:
app: test1
key1: test1
konnect:
authRef:
name: konnect-api-auth-1
---
kind: KongService
apiVersion: configuration.konghq.com/v1alpha1
metadata:
name: service-adopted-1
namespace: default
spec:
adopt:
from: konnect
konnect:
id: "aaaabbbb-cccc-dddd-eeee-000011112222"
name: service-1
host: example.com
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: test1
1 change: 1 addition & 0 deletions docs/all-api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,7 @@ KongServiceSpec defines specification of a Kong Service.
| Field | Description |
| --- | --- |
| `controlPlaneRef` _[ControlPlaneRef](#controlplaneref)_ | ControlPlaneRef is a reference to a ControlPlane this KongService is associated with. |
| `adopt` _[AdoptOptions](#adoptoptions)_ | Adopt is the options for adopting a service from an existing service in Konnect. |
| `url` _string_ | Helper field to set `protocol`, `host`, `port` and `path` using a URL. This field is write-only and is not returned in responses. |
| `connect_timeout` _integer_ | The timeout in milliseconds for establishing a connection to the upstream server. |
| `enabled` _boolean_ | Whether the Service is active. If set to `false`, the proxy behavior will be as if any routes attached to it do not exist (404). Default: `true`. |
Expand Down
1 change: 1 addition & 0 deletions docs/configuration-api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,7 @@ KongServiceSpec defines specification of a Kong Service.
| Field | Description |
| --- | --- |
| `controlPlaneRef` _[ControlPlaneRef](#controlplaneref)_ | ControlPlaneRef is a reference to a ControlPlane this KongService is associated with. |
| `adopt` _[AdoptOptions](#adoptoptions)_ | Adopt is the options for adopting a service from an existing service in Konnect. |
| `url` _string_ | Helper field to set `protocol`, `host`, `port` and `path` using a URL. This field is write-only and is not returned in responses. |
| `connect_timeout` _integer_ | The timeout in milliseconds for establishing a connection to the upstream server. |
| `enabled` _boolean_ | Whether the Service is active. If set to `false`, the proxy behavior will be as if any routes attached to it do not exist (404). Default: `true`. |
Expand Down
112 changes: 112 additions & 0 deletions test/crdsvalidation/configuration.konghq.com/kongservice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,116 @@ func TestKongService(t *testing.T) {
},
}.Run(t)
})

t.Run("adopt options testing", func(t *testing.T) {
common.TestCasesGroup[*configurationv1alpha1.KongService]{
{
Name: "valid adopt options",
TestObject: &configurationv1alpha1.KongService{
ObjectMeta: common.CommonObjectMeta,
Spec: configurationv1alpha1.KongServiceSpec{
ControlPlaneRef: &commonv1alpha1.ControlPlaneRef{
Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef,
KonnectNamespacedRef: &commonv1alpha1.KonnectNamespacedRef{
Name: "test-konnect-control-plane",
},
},
Adopt: &commonv1alpha1.AdoptOptions{
From: commonv1alpha1.AdoptSourceKonnect,
Konnect: &commonv1alpha1.AdoptKonnectOptions{
ID: "test-konnect-id",
},
},
},
},
},
{
Name: "invalid adopt.from",
TestObject: &configurationv1alpha1.KongService{
ObjectMeta: common.CommonObjectMeta,
Spec: configurationv1alpha1.KongServiceSpec{
ControlPlaneRef: &commonv1alpha1.ControlPlaneRef{
Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef,
KonnectNamespacedRef: &commonv1alpha1.KonnectNamespacedRef{
Name: "test-konnect-control-plane",
},
},
Adopt: &commonv1alpha1.AdoptOptions{
From: "invalid-adopt-from",
Konnect: &commonv1alpha1.AdoptKonnectOptions{
ID: "test-konnect-id",
},
},
},
},
ExpectedErrorMessage: lo.ToPtr("spec.adopt.from: Unsupported value"),
},
{
Name: "missing adopt.konnect",
TestObject: &configurationv1alpha1.KongService{
ObjectMeta: common.CommonObjectMeta,
Spec: configurationv1alpha1.KongServiceSpec{
ControlPlaneRef: &commonv1alpha1.ControlPlaneRef{
Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef,
KonnectNamespacedRef: &commonv1alpha1.KonnectNamespacedRef{
Name: "test-konnect-control-plane",
},
},
Adopt: &commonv1alpha1.AdoptOptions{
From: commonv1alpha1.AdoptSourceKonnect,
},
},
},
ExpectedErrorMessage: lo.ToPtr("Must specify Konnect options when from='konnect'"),
},
{
Name: "adopt.konnect.id is immutable",
TestObject: &configurationv1alpha1.KongService{
ObjectMeta: common.CommonObjectMeta,
Spec: configurationv1alpha1.KongServiceSpec{
ControlPlaneRef: &commonv1alpha1.ControlPlaneRef{
Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef,
KonnectNamespacedRef: &commonv1alpha1.KonnectNamespacedRef{
Name: "test-konnect-control-plane",
},
},
Adopt: &commonv1alpha1.AdoptOptions{
From: commonv1alpha1.AdoptSourceKonnect,
Konnect: &commonv1alpha1.AdoptKonnectOptions{
ID: "test-konnect-id",
},
},
},
},
Update: func(ks *configurationv1alpha1.KongService) {
ks.Spec.Adopt.Konnect.ID = "test-konnect-id-2"
},
ExpectedUpdateErrorMessage: lo.ToPtr("konnect.id is immutable"),
},
{
Name: "Cannot unset adopt",
TestObject: &configurationv1alpha1.KongService{
ObjectMeta: common.CommonObjectMeta,
Spec: configurationv1alpha1.KongServiceSpec{
ControlPlaneRef: &commonv1alpha1.ControlPlaneRef{
Type: configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef,
KonnectNamespacedRef: &commonv1alpha1.KonnectNamespacedRef{
Name: "test-konnect-control-plane",
},
},
Adopt: &commonv1alpha1.AdoptOptions{
From: commonv1alpha1.AdoptSourceKonnect,
Konnect: &commonv1alpha1.AdoptKonnectOptions{
ID: "test-konnect-id",
},
},
},
},
Update: func(ks *configurationv1alpha1.KongService) {
ks.Spec.Adopt = nil
},
ExpectedUpdateErrorMessage: lo.ToPtr("Cannot set or unset spec.adopt in updates"),
},
}.Run(t)
})
}