Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAPOperator CRD change #23

Merged
merged 4 commits into from
Sep 26, 2023
Merged
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
17 changes: 10 additions & 7 deletions api/v1alpha1/capoperator_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
Expand All @@ -39,18 +38,22 @@ type CAPOperatorStatus struct {
type CAPOperatorSpec struct {
// SubscriptionServer info
SubscriptionServer SubscriptionServer `json:"subscriptionServer"`
// IngressGatewayLabels
IngressGatewayLabels IngressGatewayLabels `json:"ingressGatewayLabels"`
// +kubebuilder:validation:Pattern=^[a-z0-9-.]*$
// Public ingress URL for the cluster Load Balancer
DNSTarget string `json:"dnsTarget,omitempty"`
// +kubebuilder:validation:MinItems=1
// Labels used to identify the istio ingress-gateway component and its corresponding namespace. Usually {"app":"istio-ingressgateway","istio":"ingressgateway"}
IngressGatewayLabels []NameValue `json:"ingressGatewayLabels,omitempty"`
}

type SubscriptionServer struct {
DNSTarget string `json:"dnsTarget,omitempty"`
Subdomain string `json:"subDomain"`
}

type IngressGatewayLabels struct {
Istio string `json:"istio"`
App string `json:"app"`
// Generic Name/Value configuration
type NameValue struct {
Name string `json:"name"`
Value string `json:"value"`
}

var _ component.Component = &CAPOperator{}
Expand Down
16 changes: 10 additions & 6 deletions api/v1alpha1/zz_generated.deepcopy.go

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

12 changes: 1 addition & 11 deletions config/busola/capoperator_configMap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,9 @@ data:
required: true
name: CAP Operator Subscription Server Subdomain
- simple: true
path: spec.subscriptionServer.dnsTarget
path: spec.dnsTarget
required: false
name: CAP Operator DNS Target
- simple: true
path: spec.ingressGatewayLabels.istio
required: false
name: Istio ingress gateway label - istio
placeholder: ingressgateway
- simple: true
path: spec.ingressGatewayLabels.app
required: false
name: Istio ingress gateway label - app
placeholder: istio-ingressgateway

general: |
resource:
Expand Down
37 changes: 24 additions & 13 deletions config/crd/operator.sme.sap.com_capoperators.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,41 @@ spec:
type: object
spec:
description: CAPOperatorSpec defines the desired state of CAPOperator
oneOf:
- required:
- ingressGatewayLabels
- required:
- dnsTarget
properties:
dnsTarget:
description: Public ingress URL for the cluster Load Balancer
pattern: ^[a-z0-9-.]*$
type: string
ingressGatewayLabels:
description: IngressGatewayLabels
properties:
app:
type: string
istio:
type: string
required:
- app
- istio
type: object
description: Labels used to identify the istio ingress-gateway component
and its corresponding namespace. Usually {"app":"istio-ingressgateway","istio":"ingressgateway"}
items:
description: Generic Name/Value configuration
properties:
name:
type: string
value:
type: string
required:
- name
- value
type: object
minItems: 1
type: array
subscriptionServer:
description: SubscriptionServer info
properties:
dnsTarget:
type: string
subDomain:
type: string
required:
- subDomain
type: object
required:
- ingressGatewayLabels
- subscriptionServer
type: object
status:
Expand Down
6 changes: 4 additions & 2 deletions config/samples/operator_v1alpha1_capoperator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ spec:
subscriptionServer:
subDomain: cap-op
ingressGatewayLabels:
istio: ingressgateway
app: istio-ingressgateway
- name: istio
value: ingressgateway
- name: app
value: istio-ingressgateway

31 changes: 16 additions & 15 deletions internal/transformer/transformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
apitypes "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/sap/cap-operator-lifecycle/api/v1alpha1"
componentoperatorruntimetypes "github.com/sap/component-operator-runtime/pkg/types"
)

Expand Down Expand Up @@ -61,8 +60,9 @@ func trimDNSTarget(dnsTarget string) string {
func (t *transformer) fillDNSTarget(parameters map[string]any) error {
// get DNSTarget
subscriptionServer := parameters["subscriptionServer"].(map[string]interface{})
if subscriptionServer["dnsTarget"] != nil { // already filled in CRO
subscriptionServer["dnsTarget"] = trimDNSTarget(subscriptionServer["dnsTarget"].(string))
if parameters["dnsTarget"] != nil { // already filled in CRO
subscriptionServer["dnsTarget"] = trimDNSTarget(parameters["dnsTarget"].(string))
delete(parameters, "dnsTarget")
return nil
}

Expand All @@ -71,27 +71,22 @@ func (t *transformer) fillDNSTarget(parameters map[string]any) error {
return fmt.Errorf("cannot get dnsTarget; provide either dnsTarget or ingressGatewayLabels in the CRO")
}

ingressGatewayLabels := parameters["ingressGatewayLabels"].(map[string]interface{})
if ingressGatewayLabels["app"] == nil || ingressGatewayLabels["istio"] == nil {
return fmt.Errorf("cannot get dnsTarget; provide ingressGatewayLabels/app and ingressGatewayLabels/istio values in the CRO")
}

dnsTarget, err := t.getDNSTarget(&v1alpha1.IngressGatewayLabels{App: ingressGatewayLabels["app"].(string), Istio: ingressGatewayLabels["istio"].(string)})
dnsTarget, err := t.getDNSTarget(parameters["ingressGatewayLabels"].([]interface{}))
if err != nil {
return err
}

subscriptionServer["dnsTarget"] = trimDNSTarget(dnsTarget)

delete(parameters, "ingressGatewayLabels")
return nil
}

func (t *transformer) getDNSTarget(ingressGatewayLabels *v1alpha1.IngressGatewayLabels) (dnsTarget string, err error) {
func (t *transformer) getDNSTarget(ingressGatewayLabels []interface{}) (dnsTarget string, err error) {

ctx := context.TODO()

// create ingress gateway selector from labels
ingressLabelSelector, err := labels.ValidatedSelectorFromSet(getIngressGatewayLabels(ingressGatewayLabels))
ingressLabelSelector, err := labels.ValidatedSelectorFromSet(convertIngressGatewayLabelsToMap(ingressGatewayLabels))
if err != nil {
return "", err
}
Expand Down Expand Up @@ -138,11 +133,13 @@ func (t *transformer) getDNSTarget(ingressGatewayLabels *v1alpha1.IngressGateway
return dnsTarget, nil
}

func getIngressGatewayLabels(ingressGatewayLabels *v1alpha1.IngressGatewayLabels) map[string]string {
func convertIngressGatewayLabelsToMap(ingressGatewayLabels []interface{}) map[string]string {
ingressLabels := map[string]string{}

ingressLabels["app"] = ingressGatewayLabels.App
ingressLabels["istio"] = ingressGatewayLabels.Istio
for _, label := range ingressGatewayLabels {
labelMap := label.(map[string]interface{})
ingressLabels[labelMap["name"].(string)] = labelMap["value"].(string)
}

return ingressLabels
}
Expand Down Expand Up @@ -205,6 +202,10 @@ func (t *transformer) fillDomain(parameters map[string]any) error {
return err
}

if len(domain) > 64 {
return fmt.Errorf("subscription server domain '%s' is longer than 64 characters; use a smaller subDomain", domain)
}

subscriptionServer["domain"] = domain
delete(subscriptionServer, "subDomain")

Expand Down
34 changes: 26 additions & 8 deletions internal/transformer/transformer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ func TestTransformer(t *testing.T) {
name string
dnsTargetFilled bool
ingressGatewayLabelsFilled bool
longDomain bool
expectError bool
}{
{
name: "Test with all fields filled",
name: "Test with dnsTarget and without ingress gateway labels",
dnsTargetFilled: true,
ingressGatewayLabelsFilled: true,
ingressGatewayLabelsFilled: false,
expectError: false,
},
{
name: "Test without dnsTarget",
name: "Test without dnsTarget and with ingress gateway labels",
dnsTargetFilled: false,
ingressGatewayLabelsFilled: true,
expectError: false,
Expand All @@ -39,6 +40,12 @@ func TestTransformer(t *testing.T) {
ingressGatewayLabelsFilled: false,
expectError: true,
},
{
name: "Test with more than 64 character domain",
ingressGatewayLabelsFilled: true,
longDomain: true,
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -95,15 +102,26 @@ func TestTransformer(t *testing.T) {

parameter["subscriptionServer"] = map[string]interface{}{}
subscriptionServer := parameter["subscriptionServer"].(map[string]interface{})
subscriptionServer["subDomain"] = "cop"

if tt.longDomain {
subscriptionServer["subDomain"] = "long-subdomain-for-the-test-to-fail-to-check-the-error-case"
} else {
subscriptionServer["subDomain"] = "cop"
}
if tt.dnsTargetFilled {
subscriptionServer["dnsTarget"] = "public-ingress.some.cluster.sap"
parameter["dnsTarget"] = "public-ingress.some.cluster.sap"
}

if tt.ingressGatewayLabelsFilled {
parameter["ingressGatewayLabels"] = map[string]interface{}{
"istio": "ingress",
"app": "istio-ingress",
parameter["ingressGatewayLabels"] = []interface{}{
map[string]interface{}{
"name": "app",
"value": "istio-ingress",
},
map[string]interface{}{
"name": "istio",
"value": "ingress",
},
}
}

Expand Down
Loading