Skip to content

Commit

Permalink
feat(konnect): add KongSNI reconciler (#653)
Browse files Browse the repository at this point in the history
* KongSNI reconciler

* add tests and sample

* Update modules/manager/controller_setup.go

* Update test/envtest/konnect_entities_sni_test.go

* feat(konnect): add index for KongSNI on referenced certificate name

* feat(konnect): fallback to create on not found error when upserting the SNI

---------

Co-authored-by: Patryk Małek <patryk.malek@konghq.com>
  • Loading branch information
randmonkey and pmalek authored Sep 30, 2024
1 parent 9c6420b commit c84710b
Show file tree
Hide file tree
Showing 26 changed files with 1,706 additions and 17 deletions.
1 change: 1 addition & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ packages:
CertificatesSDK:
KeysSDK:
KeySetsSDK:
SNIsSDK:
2 changes: 2 additions & 0 deletions config/rbac/role/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ rules:
- kongplugins/status
- kongroutes/status
- kongservices/status
- kongsnis/status
- kongtargets/status
- kongupstreampolicies/status
- kongupstreams/status
Expand Down Expand Up @@ -182,6 +183,7 @@ rules:
resources:
- kongroutes
- kongservices
- kongsnis
- kongtargets
- kongupstreams
- kongvaults
Expand Down
98 changes: 98 additions & 0 deletions config/samples/konnect_sni.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
kind: KonnectAPIAuthConfiguration
apiVersion: konnect.konghq.com/v1alpha1
metadata:
name: konnect-api-auth-dev-1
namespace: default
spec:
type: token
token: kpat_XXXXXXXXXXXXXXXXXXX
serverURL: us.api.konghq.tech
---
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-dev-1
---
kind: KongCertificate
apiVersion: configuration.konghq.com/v1alpha1
metadata:
name: cert-1
namespace: default
annotations:
konghq.com/tags: "infra"
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: test1
tags:
- production
cert: |
-----BEGIN CERTIFICATE-----
MIIDPTCCAiUCFG5IolqRiKPMfzTI8peXlaF6cZODMA0GCSqGSIb3DQEBCwUAMFsx
CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5
MRIwEAYDVQQKDAlLb25nIEluYy4xFDASBgNVBAMMC2tvbmdocS50ZWNoMB4XDTI0
MDkyNTA3MjIzOFoXDTM0MDkyMzA3MjIzOFowWzELMAkGA1UEBhMCVVMxCzAJBgNV
BAgMAkNBMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxEjAQBgNVBAoMCUtvbmcgSW5j
LjEUMBIGA1UEAwwLa29uZ2hxLnRlY2gwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDXmNBzpWyJ0YUdfCamZpJiwRQMn5vVY8iKQrd3dD03DWyPHu/fXlrL
+QPTRip5d1SrxjzQ4S3fgme442BTlElF9d1w1rhg+DIg6NsW1jd+3IZaICnq7BZH
rJGlW+IWJSKHmNQ39nfVQwgL/QdylrYpbB7uwdEDMa78GfXteiXTcuNobCr7VWVz
rY6rQXo/dImWE1PtMp/EZEMsEbgbQpK5+fUnKTmFncVlDAZ2Q3s2MPikV5UhMVyQ
dKQydU0Ev0LRtpsjW8pQdshMG1ilMq6Yg6YU95gakLVjRXMoDlIJOu08mdped+2Y
VIUSXhRyRt1hbkFP0fXG0THfZ3DjH7jRAgMBAAEwDQYJKoZIhvcNAQELBQADggEB
ANEXlNaQKLrB+jsnNjybsTRkvRRmwjnXaQV0jHzjseGsTJoKY5ABBsSRDiHtqB+9
LPTpHhLYJWsHSLwawIJ3aWDDpF4MNTRsvO12v7wM8Q42OSgkP23O6a5ESkyHRBAb
dLVEp+0Z3kjYwPIglIK37PcgDci6Zim73GOfapDEASNbnCu8js2g/ucYPPXkGMxl
PSUER7MTNf9wRbXrroCE+tZw4kUyUh+6taNlU4ialAJLO1x6UGVRHvPgEx0fAAxA
seBH+A9QMvVl2cKcvrOgZ0CWY01aFRO9ROQ7PrYXqRFvOZu8K3QzLw7xYoK1DTp+
kkO/oPy+WIbqEvj7QrhUXpo=
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDXmNBzpWyJ0YUd
fCamZpJiwRQMn5vVY8iKQrd3dD03DWyPHu/fXlrL+QPTRip5d1SrxjzQ4S3fgme4
42BTlElF9d1w1rhg+DIg6NsW1jd+3IZaICnq7BZHrJGlW+IWJSKHmNQ39nfVQwgL
/QdylrYpbB7uwdEDMa78GfXteiXTcuNobCr7VWVzrY6rQXo/dImWE1PtMp/EZEMs
EbgbQpK5+fUnKTmFncVlDAZ2Q3s2MPikV5UhMVyQdKQydU0Ev0LRtpsjW8pQdshM
G1ilMq6Yg6YU95gakLVjRXMoDlIJOu08mdped+2YVIUSXhRyRt1hbkFP0fXG0THf
Z3DjH7jRAgMBAAECggEAOSZ4h1dgDK5+H2FEK5MAFe6BnpEGsYu4YrIpySAGhBvq
XYwBYRA1eGFjmrM8WiOATeKIR4SRcPC0BwY7CBzESafRkfJRQN86BpBDV2vknRve
/3AMPIplo41CtHdFWMJyQ0iHZOhQPrd8oBTsTvtVgWh4UKkO+05FyO0mzFM3SLPs
pqRwMZjLlKVZhbI1l0Ur787tzWpMQQHmd8csAvlak+GIciQWELbVK+5kr/FDpJbq
joIeHX7DCmIqrD/Okwa8SfJu1sutmRX+nrxkDi7trPYcpqriDoWs2jMcnS2GHq9M
lsy2XHn+qLjCpl3/XU61xenWs+Rmmj6J/oIs1zYXCwKBgQDywRS/MNgwMst703Wh
ERJO0rNSR0XVzzoKOqc/ghPkeA8mVNwfNkbgWks+83tuAb6IunMIeyQJ3g/jRhjz
KImsqJmO+DoZCioeaR3PeIWibi9I9Irg6dtoNMwxSmmOtCKD0rccxM1V9OnYkn5a
0Fb+irQSgJYiHrF2SLAT0NoWEwKBgQDjXGLHCu/WEy49vROdkTia133Wc7m71/D5
RDUqvSmAEHJyhTlzCbTO+JcNhC6cx3s102GNcVYHlAq3WoE5EV1YykUNJwUg4XPn
AggNkYOiXs6tf+uePmT8MddixFFgFxZ2bIqFhvnY+WqypHuxtwIepqKJjq5xZTiB
+lfp7SziCwKBgAivofdpXwLyfldy7I2T18zcOzBhfn01CgWdrahXFjEhnqEnfizb
u1OBx5l8CtmX1GJ+EWmnRlXYDUd7lZ71v19fNQdpmGKW+4TVDA0Fafqy6Jw6q9F6
bLBg20GUQQyrI2UGICk2XYaK2ec27rB/Le2zttfGpBiaco0h8rLy0SrjAoGBAM4/
UY/UOQsOrUTuT2wBf8LfNtUid9uSIZRNrplNrebxhJCkkB/uLyoN0iE9xncMcpW6
YmVH6c3IGwyHOnBFc1OHcapjukBApL5rVljQpwPVU1GKmHgdi8hHgmajRlqPtx3I
isRkVCPi5kqV8WueY3rgmNOGLnLJasBmE/gt4ihPAoGAG3v93R5tAeSrn7DMHaZt
p+udsNw9mDPYHAzlYtnw1OE/I0ceR5UyCFSzCd00Q8ZYBLf9jRvsO/GUA4F51isE
8/7xyqSxJqDwzv9N8EGkqf/SfMKA3kK3Sc8u+ovhzJu8OxcY+qrpo4+vYWYeW42n
5XBwvWV2ovRMx7Ntw7FUc24=
-----END PRIVATE KEY-----
---
apiVersion: configuration.konghq.com/v1alpha1
kind: KongSNI
metadata:
name: sni-1
namespace: default
spec:
certificateRef:
name: cert-1
name: "test-sni.konghq.com"
16 changes: 14 additions & 2 deletions controller/konnect/conditions/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ const (

const (
// KongUpstreamRefValidConditionType is the type of the condition that indicates
// whether the KongUpstream reference is valid and points to an existing
// KongUpstreamRefValid.
// whether the KongUpstream reference is valid and points to an existing KongUpstream.
KongUpstreamRefValidConditionType = "KongUpstreamRefValid"

// KongUpstreamRefReasonValid is the reason used with the KongUpstreamRefValid
Expand All @@ -128,3 +127,16 @@ const (
// condition type indicating that the KongUpstream reference is invalid.
KongUpstreamRefReasonInvalid = "Invalid"
)

const (
// KongCertificateRefValidConditionType is the type of the condition that indicates
// whether the KongCertificate reference is valid and points to an existing KongCertificate
KongCertificateRefValidConditionType = "KongCertificateRefValid"

// KongCertificateRefReasonValid is the reason used with the KongCertificateRefValid
// condition type indicating that the KongCertificate reference is valid.
KongCertificateRefReasonValid = "Valid"
// KongCertificateRefReasonInvalid is the reason used with the KongCertificateRefValid
// condition type indicating that the KongCertificate reference is invalid.
KongCertificateRefReasonInvalid = "Invalid"
)
3 changes: 2 additions & 1 deletion controller/konnect/constraints/constraints.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ type SupportedKonnectEntityType interface {
configurationv1alpha1.KongTarget |
configurationv1alpha1.KongVault |
configurationv1alpha1.KongKey |
configurationv1alpha1.KongKeySet
configurationv1alpha1.KongKeySet |
configurationv1alpha1.KongSNI
// TODO: add other types

GetTypeName() string
Expand Down
25 changes: 25 additions & 0 deletions controller/konnect/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,28 @@ type ReferencedKongUpstreamDoesNotExist struct {
func (e ReferencedKongUpstreamDoesNotExist) Error() string {
return fmt.Sprintf("referenced Kong Upstream %s does not exist: %v", e.Reference, e.Err)
}

// ReferencedKongCertificateIsBeingDeleted is an error type that is returned when
// a Konnect entity references a Kong Certificate which is being deleted.
type ReferencedKongCertificateIsBeingDeleted struct {
Reference types.NamespacedName
DeletionTimestamp time.Time
}

// Error implements the error interface.
func (e ReferencedKongCertificateIsBeingDeleted) Error() string {
return fmt.Sprintf("referenced Kong Certificate %s is being deleted (deletion timestamp: %s)",
e.Reference, e.DeletionTimestamp)
}

// ReferencedKongCertificateDoesNotExist is an error type that is returned when
// a Konnect entity references a Kong Certificate which does not exist.
type ReferencedKongCertificateDoesNotExist struct {
Reference types.NamespacedName
Err error
}

// Error implements the error interface.
func (e ReferencedKongCertificateDoesNotExist) Error() string {
return fmt.Sprintf("referenced Kong Certificate %s does not exist: %v", e.Reference, e.Err)
}
2 changes: 2 additions & 0 deletions controller/konnect/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ func ReconciliationIndexOptionsForEntity[
return IndexOptionsForCredentialsBasicAuth()
case *configurationv1.KongConsumer:
return IndexOptionsForKongConsumer()
case *configurationv1alpha1.KongSNI:
return IndexOptionsForKongSNI()
}
return nil
}
31 changes: 31 additions & 0 deletions controller/konnect/index_sni.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package konnect

import (
"sigs.k8s.io/controller-runtime/pkg/client"

configurationv1alpha1 "github.com/kong/kubernetes-configuration/api/configuration/v1alpha1"
)

const (
// IndexFieldKongSNIOnCertificateRefNmae is the index field for KongSNI -> Certificate.
IndexFieldKongSNIOnCertificateRefNmae = "kongSNICertificateRefName"
)

// IndexOptionsForKongSNI returns required Index options for KongSNI reconciler.
func IndexOptionsForKongSNI() []ReconciliationIndexOption {
return []ReconciliationIndexOption{
{
IndexObject: &configurationv1alpha1.KongSNI{},
IndexField: IndexFieldKongSNIOnCertificateRefNmae,
ExtractValue: kongSNIReferencesCertificate,
},
}
}

func kongSNIReferencesCertificate(object client.Object) []string {
sni, ok := object.(*configurationv1alpha1.KongSNI)
if !ok {
return nil
}
return []string{sni.Spec.CertificateRef.Name}
}
14 changes: 14 additions & 0 deletions controller/konnect/ops/kongsni.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ops

import (
"context"

sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations"
)

// SNIsSDK is the interface to operate Kong SNIs.
type SNIsSDK interface {
CreateSniWithCertificate(context.Context, sdkkonnectops.CreateSniWithCertificateRequest, ...sdkkonnectops.Option) (*sdkkonnectops.CreateSniWithCertificateResponse, error)
UpsertSniWithCertificate(ctx context.Context, request sdkkonnectops.UpsertSniWithCertificateRequest, opts ...sdkkonnectops.Option) (*sdkkonnectops.UpsertSniWithCertificateResponse, error)
DeleteSniWithCertificate(ctx context.Context, request sdkkonnectops.DeleteSniWithCertificateRequest, opts ...sdkkonnectops.Option) (*sdkkonnectops.DeleteSniWithCertificateResponse, error)
}
Loading

0 comments on commit c84710b

Please sign in to comment.