From 7cb5955d1ded37cb10bb69d951796f6d96b5deea Mon Sep 17 00:00:00 2001 From: Pavan Date: Thu, 8 Aug 2024 18:20:41 +0200 Subject: [PATCH] [FEATURE] Operator: CAPTenantOutput introduced Introduce a new custom resource that can be used to provide additional data to saas provisioning callbacks. This is a data only resource that can be created via Tenant Operation(s) and will be merged eventually into the additional data during subscription callback handling in the subscription server. --- cmd/server/internal/handler.go | 53 ++++- cmd/server/internal/handler_test.go | 39 +++- crds/sme.sap.com_capapplications.yaml | 2 +- crds/sme.sap.com_capapplicationversions.yaml | 52 ++++- crds/sme.sap.com_captenantoperations.yaml | 2 +- crds/sme.sap.com_captenantoutputs.yaml | 44 ++++ crds/sme.sap.com_captenants.yaml | 2 +- internal/controller/common_test.go | 1 + internal/controller/reconcile-captenant.go | 21 ++ pkg/apis/sme.sap.com/v1alpha1/register.go | 5 + pkg/apis/sme.sap.com/v1alpha1/types.go | 29 +++ .../v1alpha1/zz_generated.deepcopy.go | 76 +++++++ .../sme.sap.com/v1alpha1/captenantoutput.go | 199 ++++++++++++++++++ .../v1alpha1/captenantoutputspec.go | 28 +++ pkg/client/applyconfiguration/utils.go | 4 + .../sme.sap.com/v1alpha1/captenantoutput.go | 197 +++++++++++++++++ .../v1alpha1/fake/fake_captenantoutput.go | 143 +++++++++++++ .../v1alpha1/fake/fake_sme.sap.com_client.go | 4 + .../v1alpha1/generated_expansion.go | 2 + .../v1alpha1/sme.sap.com_client.go | 5 + .../informers/externalversions/generic.go | 2 + .../sme.sap.com/v1alpha1/captenantoutput.go | 79 +++++++ .../sme.sap.com/v1alpha1/interface.go | 7 + .../sme.sap.com/v1alpha1/captenantoutput.go | 88 ++++++++ .../v1alpha1/expansion_generated.go | 8 + .../docs/usage/resources/captenantoutput.md | 31 +++ website/includes/api-reference.html | 104 ++++++++- 27 files changed, 1208 insertions(+), 19 deletions(-) create mode 100644 crds/sme.sap.com_captenantoutputs.yaml create mode 100644 pkg/client/applyconfiguration/sme.sap.com/v1alpha1/captenantoutput.go create mode 100644 pkg/client/applyconfiguration/sme.sap.com/v1alpha1/captenantoutputspec.go create mode 100644 pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/captenantoutput.go create mode 100644 pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/fake/fake_captenantoutput.go create mode 100644 pkg/client/informers/externalversions/sme.sap.com/v1alpha1/captenantoutput.go create mode 100644 pkg/client/listers/sme.sap.com/v1alpha1/captenantoutput.go create mode 100644 website/content/en/docs/usage/resources/captenantoutput.md diff --git a/cmd/server/internal/handler.go b/cmd/server/internal/handler.go index 64f4f6e..d9f792a 100644 --- a/cmd/server/internal/handler.go +++ b/cmd/server/internal/handler.go @@ -93,6 +93,11 @@ type OAuthResponse struct { AccessToken string `json:"access_token"` } +type tenantInfo struct { + tenantId string + tenantSubDomain string +} + func (s *SubscriptionHandler) CreateTenant(req *http.Request) *Result { util.LogInfo("Create Tenant triggered", TenantProvisioning, "CreateTenant", nil) var created = false @@ -181,7 +186,8 @@ func (s *SubscriptionHandler) CreateTenant(req *http.Request) *Result { // TODO: consider retrying tenant creation if it is in Error state if tenant != nil { - s.initializeCallback(tenant.Name, ca, saasData, req, reqType["subscribedSubdomain"].(string), true) + tenantIn := tenantInfo{tenantId: reqType["subscribedTenantId"].(string), tenantSubDomain: reqType["subscribedSubdomain"].(string)} + s.initializeCallback(tenant.Name, ca, saasData, req, tenantIn, true) } // Tenant created/exists @@ -277,8 +283,8 @@ func (s *SubscriptionHandler) DeleteTenant(req *http.Request) *Result { return &Result{Tenant: nil, Message: err.Error()} } } - - s.initializeCallback(tenantName, ca, saasData, req, reqType["subscribedSubdomain"].(string), false) + tenantIn := tenantInfo{tenantId: reqType["subscribedTenantId"].(string), tenantSubDomain: reqType["subscribedSubdomain"].(string)} + s.initializeCallback(tenantName, ca, saasData, req, tenantIn, false) return &Result{Tenant: tenant, Message: ResourceDeleted} } @@ -321,12 +327,12 @@ func (s *SubscriptionHandler) checkAuthorization(authHeader string, saasData *ut return nil } -func (s *SubscriptionHandler) initializeCallback(tenantName string, ca *v1alpha1.CAPApplication, saasData *util.SaasRegistryCredentials, req *http.Request, tenantSubDomain string, isProvisioning bool) { +func (s *SubscriptionHandler) initializeCallback(tenantName string, ca *v1alpha1.CAPApplication, saasData *util.SaasRegistryCredentials, req *http.Request, tenantIn tenantInfo, isProvisioning bool) { subscriptionDomain := ca.Annotations[AnnotationSubscriptionDomain] if subscriptionDomain == "" { subscriptionDomain = ca.Spec.Domains.Primary } - appUrl := "https://" + tenantSubDomain + "." + subscriptionDomain + appUrl := "https://" + tenantIn.tenantSubDomain + "." + subscriptionDomain asyncCallbackPath := req.Header.Get("STATUS_CALLBACK") util.LogInfo("Callback initialized", TenantProvisioning, ca, nil, "subscription URL", appUrl, "async callback path", asyncCallbackPath, "tenantName", tenantName) @@ -356,6 +362,11 @@ func (s *SubscriptionHandler) initializeCallback(tenantName string, ca *v1alpha1 additionalOutput = nil } } + // Add tenant data to the additional output if it exists + err := s.enrichAdditionalOutput(ca.Namespace, tenantIn.tenantId, additionalOutput) + if err != nil { + util.LogError(err, "Error updating tenant data", step, ca, nil, "tenantId", tenantIn.tenantId) + } } else { additionalOutput = nil } @@ -365,6 +376,38 @@ func (s *SubscriptionHandler) initializeCallback(tenantName string, ca *v1alpha1 util.LogInfo("Waiting for async saas callback after checks...", step, ca, nil, "tenantName", tenantName) } +func (s *SubscriptionHandler) enrichAdditionalOutput(namespace string, tenantId string, additionalOutput *map[string]any) error { + labelSelector, err := labels.ValidatedSelectorFromSet(map[string]string{ + LabelTenantId: tenantId, + }) + if err != nil { + return err + } + + tenantDataList, err := s.Clientset.SmeV1alpha1().CAPTenantOutputs(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: labelSelector.String()}) + if err != nil { + return err + } + + if len(tenantDataList.Items) == 0 { + util.LogInfo("No cap tenant data found", TenantProvisioning, nil, nil, "tenantId", tenantId, "namespace", namespace) + } + + for _, tenantData := range tenantDataList.Items { + // Update relevant data from each CAPTenantOutput to saas callback additional output + tenantDataOutput := &map[string]any{} + err = json.Unmarshal([]byte(tenantData.Spec.SubscriptionCallbackData), tenantDataOutput) + if err != nil { + return err + } + // merge tenant data output into additional output + for k, v := range *tenantDataOutput { + (*additionalOutput)[k] = v + } + } + return nil +} + func (s *SubscriptionHandler) checkCAPTenantStatus(ctx context.Context, tenantNamespace string, tenantName string, provisioning bool, callbackTimeoutMs string) bool { asyncCallbackTimeout := 15 * time.Minute if callbackTimeoutMs != "" { diff --git a/cmd/server/internal/handler_test.go b/cmd/server/internal/handler_test.go index 92c9123..c39421d 100644 --- a/cmd/server/internal/handler_test.go +++ b/cmd/server/internal/handler_test.go @@ -46,7 +46,7 @@ const ( tenantId = "012012012-1234-1234-123456" ) -func setup(ca *v1alpha1.CAPApplication, cat *v1alpha1.CAPTenant, client *http.Client) *SubscriptionHandler { +func setup(ca *v1alpha1.CAPApplication, cat *v1alpha1.CAPTenant, ctout *v1alpha1.CAPTenantOutput, client *http.Client) *SubscriptionHandler { crdObjects := []runtime.Object{} if ca != nil { crdObjects = append(crdObjects, ca) @@ -54,6 +54,9 @@ func setup(ca *v1alpha1.CAPApplication, cat *v1alpha1.CAPTenant, client *http.Cl if cat != nil { crdObjects = append(crdObjects, cat) } + if ctout != nil { + crdObjects = append(crdObjects, ctout) + } subHandler := NewSubscriptionHandler(fake.NewSimpleClientset(crdObjects...), k8sfake.NewSimpleClientset(createSecrets()...)) if client != nil { @@ -221,7 +224,7 @@ func TestMain(m *testing.M) { func Test_IncorrectMethod(t *testing.T) { res := httptest.NewRecorder() req := httptest.NewRequest(http.MethodPatch, RequestPath, strings.NewReader(`{"foo": "bar"}`)) - subHandler := setup(nil, nil, nil) + subHandler := setup(nil, nil, nil, nil) subHandler.HandleRequest(res, req) if res.Code != http.StatusMethodNotAllowed { t.Errorf("Expected status '%d', received '%d'", http.StatusMethodNotAllowed, res.Code) @@ -251,6 +254,7 @@ func Test_provisioning(t *testing.T) { invalidAdditionalData bool withSecretKey bool existingTenant bool + existingTenantOutput bool expectedStatusCode int expectedResponse Result }{ @@ -304,6 +308,19 @@ func Test_provisioning(t *testing.T) { Message: ResourceCreated, }, }, + { + name: "Provisioning Request valid with additional data and existing tenant and existing tenant output", + method: http.MethodPut, + body: `{"subscriptionAppName":"` + appName + `","globalAccountGUID":"` + globalAccountId + `","subscribedTenantId":"` + tenantId + `","subscribedSubdomain":"` + subDomain + `"}`, + createCROs: true, + withAdditionalData: true, + existingTenant: true, + existingTenantOutput: true, + expectedStatusCode: http.StatusAccepted, + expectedResponse: Result{ + Message: ResourceCreated, + }, + }, { name: "Provisioning Request valid with invalid additional data and existing tenant", method: http.MethodPut, @@ -334,6 +351,7 @@ func Test_provisioning(t *testing.T) { t.Run(testData.name, func(t *testing.T) { var ca *v1alpha1.CAPApplication var cat *v1alpha1.CAPTenant + var ctout *v1alpha1.CAPTenantOutput if testData.createCROs { ca = createCA() if testData.withAdditionalData { @@ -347,11 +365,14 @@ func Test_provisioning(t *testing.T) { if testData.existingTenant { cat = createCAT(testData.withAdditionalData) } + if testData.existingTenantOutput { + ctout = &v1alpha1.CAPTenantOutput{ObjectMeta: v1.ObjectMeta{Name: caName + "-provider", Namespace: v1.NamespaceDefault, Labels: map[string]string{LabelTenantId: tenantId}}, Spec: v1alpha1.CAPTenantOutputSpec{SubscriptionCallbackData: "{\"foo3\":\"bar3\"}"}} + } client, tokenString, err := SetupValidTokenAndIssuerForSubscriptionTests("appname!b14") if err != nil { t.Fatal(err.Error()) } - subHandler := setup(ca, cat, client) + subHandler := setup(ca, cat, ctout, client) res := httptest.NewRecorder() req := httptest.NewRequest(testData.method, RequestPath, strings.NewReader(testData.body)) @@ -446,7 +467,7 @@ func Test_deprovisioning(t *testing.T) { if err != nil { t.Fatal(err.Error()) } - subHandler := setup(ca, cat, client) + subHandler := setup(ca, cat, nil, client) res := httptest.NewRecorder() req := httptest.NewRequest(testData.method, RequestPath, strings.NewReader(testData.body)) @@ -614,7 +635,7 @@ func TestAsyncCallback(t *testing.T) { saasData.CredentialType = p.useCredentialType t.Run(p.testName, func(t *testing.T) { client := createCallbackTestServer(context.TODO(), t, &p) - subHandler := setup(nil, nil, client) + subHandler := setup(nil, nil, nil, client) subHandler.handleAsyncCallback( ctx, saasData, @@ -631,7 +652,7 @@ func TestAsyncCallback(t *testing.T) { func TestCheckTenantStatusContextCancellationAsyncTimeout(t *testing.T) { execTestsWithBLI(t, "Check Tenant Status Context Cancellation AsyncTimeout", []string{"ERP4SMEPREPWORKAPPPLAT-2240"}, func(t *testing.T) { // test context cancellation (like deadline) - subHandler := setup(nil, nil, nil) + subHandler := setup(nil, nil, nil, nil) notify := make(chan bool) go func() { r := subHandler.checkCAPTenantStatus(context.Background(), "default", "test-cat", true, "4000") @@ -654,7 +675,7 @@ func TestCheckTenantStatusContextCancellationAsyncTimeout(t *testing.T) { func TestCheckTenantStatusTenantReady(t *testing.T) { // test context cancellation (like deadline) cat := createCAT(true) - subHandler := setup(nil, cat, nil) + subHandler := setup(nil, cat, nil, nil) r := subHandler.checkCAPTenantStatus(context.TODO(), cat.Namespace, cat.Name, true, "") if r != true { @@ -666,7 +687,7 @@ func TestCheckTenantStatusWithCallbacktimeout(t *testing.T) { execTestsWithBLI(t, "Check Tenant Status With Callback timeout", []string{"ERP4SMEPREPWORKAPPPLAT-2240"}, func(t *testing.T) { // test context cancellation (like deadline) cat := createCAT(false) - subHandler := setup(nil, cat, nil) + subHandler := setup(nil, cat, nil, nil) r := subHandler.checkCAPTenantStatus(context.TODO(), cat.Namespace, cat.Name, true, "4000") if r != false { @@ -680,7 +701,7 @@ func TestMultiXSUAA(t *testing.T) { // CA without "sme.sap.com/primary-xsuaa" annotation ca := createCA() - subHandler := setup(ca, nil, nil) + subHandler := setup(ca, nil, nil, nil) uaaCreds := subHandler.getXSUAADetails(ca, "Test") if uaaCreds.AuthUrl != "https://app-domain.auth.service.local" { diff --git a/crds/sme.sap.com_capapplications.yaml b/crds/sme.sap.com_capapplications.yaml index f762f2c..c3bd479 100644 --- a/crds/sme.sap.com_capapplications.yaml +++ b/crds/sme.sap.com_capapplications.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: capapplications.sme.sap.com spec: group: sme.sap.com diff --git a/crds/sme.sap.com_capapplicationversions.yaml b/crds/sme.sap.com_capapplicationversions.yaml index c28a233..9fa8f48 100644 --- a/crds/sme.sap.com_capapplicationversions.yaml +++ b/crds/sme.sap.com_capapplicationversions.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: capapplicationversions.sme.sap.com spec: group: sme.sap.com @@ -868,6 +868,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -974,6 +975,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1055,6 +1057,8 @@ spec: properties: name: type: string + request: + type: string required: - name type: object @@ -1172,6 +1176,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1308,6 +1313,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1425,6 +1431,8 @@ spec: type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string sysctls: items: properties: @@ -1493,6 +1501,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -1564,6 +1573,8 @@ spec: properties: name: type: string + request: + type: string required: - name type: object @@ -1782,10 +1793,12 @@ spec: diskURI: type: string fsType: + default: ext4 type: string kind: type: string readOnly: + default: false type: boolean required: - diskName @@ -2145,6 +2158,13 @@ spec: required: - path type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object iscsi: properties: chapAuthDiscovery: @@ -2158,6 +2178,7 @@ spec: iqn: type: string iscsiInterface: + default: default type: string lun: format: int32 @@ -2406,6 +2427,7 @@ spec: image: type: string keyring: + default: /etc/ceph/keyring type: string monitors: items: @@ -2413,6 +2435,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd type: string readOnly: type: boolean @@ -2424,6 +2447,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin type: string required: - image @@ -2432,6 +2456,7 @@ spec: scaleIO: properties: fsType: + default: xfs type: string gateway: type: string @@ -2449,6 +2474,7 @@ spec: sslEnabled: type: boolean storageMode: + default: ThinProvisioned type: string storagePool: type: string @@ -3298,6 +3324,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -3404,6 +3431,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -3485,6 +3513,8 @@ spec: properties: name: type: string + request: + type: string required: - name type: object @@ -3602,6 +3632,7 @@ spec: format: int32 type: integer service: + default: "" type: string required: - port @@ -3775,6 +3806,8 @@ spec: type: integer type: array x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string sysctls: items: properties: @@ -3809,6 +3842,8 @@ spec: properties: name: type: string + request: + type: string required: - name type: object @@ -4030,10 +4065,12 @@ spec: diskURI: type: string fsType: + default: ext4 type: string kind: type: string readOnly: + default: false type: boolean required: - diskName @@ -4393,6 +4430,13 @@ spec: required: - path type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object iscsi: properties: chapAuthDiscovery: @@ -4406,6 +4450,7 @@ spec: iqn: type: string iscsiInterface: + default: default type: string lun: format: int32 @@ -4654,6 +4699,7 @@ spec: image: type: string keyring: + default: /etc/ceph/keyring type: string monitors: items: @@ -4661,6 +4707,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd type: string readOnly: type: boolean @@ -4672,6 +4719,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin type: string required: - image @@ -4680,6 +4728,7 @@ spec: scaleIO: properties: fsType: + default: xfs type: string gateway: type: string @@ -4697,6 +4746,7 @@ spec: sslEnabled: type: boolean storageMode: + default: ThinProvisioned type: string storagePool: type: string diff --git a/crds/sme.sap.com_captenantoperations.yaml b/crds/sme.sap.com_captenantoperations.yaml index 27dad04..2336c35 100644 --- a/crds/sme.sap.com_captenantoperations.yaml +++ b/crds/sme.sap.com_captenantoperations.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: captenantoperations.sme.sap.com spec: group: sme.sap.com diff --git a/crds/sme.sap.com_captenantoutputs.yaml b/crds/sme.sap.com_captenantoutputs.yaml new file mode 100644 index 0000000..f4d4942 --- /dev/null +++ b/crds/sme.sap.com_captenantoutputs.yaml @@ -0,0 +1,44 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: captenantoutputs.sme.sap.com +spec: + group: sme.sap.com + names: + kind: CAPTenantOutput + listKind: CAPTenantOutputList + plural: captenantoutputs + shortNames: + - ctout + singular: captenantoutput + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + subscriptionCallbackData: + type: string + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/crds/sme.sap.com_captenants.yaml b/crds/sme.sap.com_captenants.yaml index 7435fc1..5f15528 100644 --- a/crds/sme.sap.com_captenants.yaml +++ b/crds/sme.sap.com_captenants.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.15.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: captenants.sme.sap.com spec: group: sme.sap.com diff --git a/internal/controller/common_test.go b/internal/controller/common_test.go index 0f75522..a5dc3ff 100644 --- a/internal/controller/common_test.go +++ b/internal/controller/common_test.go @@ -54,6 +54,7 @@ import ( var gvrKindMap map[string]string = map[string]string{ "dnsentries.dns.gardener.cloud/v1alpha1": "DNSEntry", + "captenantoutputs.sme.sap.com/v1alpha1": "CAPTenantOutput", "captenantoperations.sme.sap.com/v1alpha1": "CAPTenantOperation", "captenants.sme.sap.com/v1alpha1": "CAPTenant", "capapplications.sme.sap.com/v1alpha1": "CAPApplication", diff --git a/internal/controller/reconcile-captenant.go b/internal/controller/reconcile-captenant.go index 56c49ec..4ab420c 100644 --- a/internal/controller/reconcile-captenant.go +++ b/internal/controller/reconcile-captenant.go @@ -423,6 +423,12 @@ func (c *Controller) createCAPTenantOperation(ctx context.Context, cat *v1alpha1 return nil, err } + // Cleanup all cap tenant ourputs for this tenant + err = c.cleanUpTenantOutputs(ctx, cat) + if err != nil { + return nil, err + } + // create CAPTenantOperation ctop := &v1alpha1.CAPTenantOperation{ ObjectMeta: metav1.ObjectMeta{ @@ -443,6 +449,21 @@ func (c *Controller) createCAPTenantOperation(ctx context.Context, cat *v1alpha1 return c.crdClient.SmeV1alpha1().CAPTenantOperations(cat.Namespace).Create(ctx, ctop, metav1.CreateOptions{}) } +func (c *Controller) cleanUpTenantOutputs(ctx context.Context, cat *v1alpha1.CAPTenant) error { + // delete all tenant outputs for this tenant + selector, err := labels.ValidatedSelectorFromSet(map[string]string{ + LabelTenantId: cat.Spec.TenantId, + }) + if err != nil { + return err + } + err = c.crdClient.SmeV1alpha1().CAPTenantOutputs(cat.Namespace).DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: selector.String()}) + if err != nil { + return fmt.Errorf("deletion of cap tenant outputs failed: %s", err.Error()) + } + return nil +} + func deriveStepsForTenantOperation(cav *v1alpha1.CAPApplicationVersion, opType v1alpha1.CAPTenantOperationType) (steps []v1alpha1.CAPTenantOperationStep, err error) { defaultSteps := func() { // if there are no specified steps, add only one step of type TenantOperation diff --git a/pkg/apis/sme.sap.com/v1alpha1/register.go b/pkg/apis/sme.sap.com/v1alpha1/register.go index d9ef124..c8bc76e 100644 --- a/pkg/apis/sme.sap.com/v1alpha1/register.go +++ b/pkg/apis/sme.sap.com/v1alpha1/register.go @@ -53,6 +53,11 @@ func addKnownTypes(scheme *runtime.Scheme) error { &CAPTenantOperation{}, &CAPTenantOperationList{}, ) + scheme.AddKnownTypes( + SchemeGroupVersion, + &CAPTenantOutput{}, + &CAPTenantOutputList{}, + ) metaV1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } diff --git a/pkg/apis/sme.sap.com/v1alpha1/types.go b/pkg/apis/sme.sap.com/v1alpha1/types.go index 219c094..1e65cbd 100644 --- a/pkg/apis/sme.sap.com/v1alpha1/types.go +++ b/pkg/apis/sme.sap.com/v1alpha1/types.go @@ -21,6 +21,8 @@ const ( CAPTenantResource = "captenants" CAPTenantOperationKind = "CAPTenantOperation" CAPTenantOperationResource = "captenantoperations" + CAPTenantOutputKind = "CAPTenantOutput" + CAPTenantOutputResource = "captenantouputs" ) // +kubebuilder:resource:shortName=ca @@ -532,3 +534,30 @@ const ( // Upgrade tenant CAPTenantOperationTypeUpgrade CAPTenantOperationType = "upgrade" ) + +// +kubebuilder:resource:shortName=ctout +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CAPTenantOutput is the schema for captenantoutputs API +type CAPTenantOutput struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + // CAPTenantOutputData spec + Spec CAPTenantOutputSpec `json:"spec"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CAPTenantOutputList contains a list of CAPTenantOutput +type CAPTenantOutputList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CAPTenantOutput `json:"items"` +} + +type CAPTenantOutputSpec struct { + // +kubebuilder:validation:nullable + SubscriptionCallbackData string `json:"subscriptionCallbackData,omitempty"` +} diff --git a/pkg/apis/sme.sap.com/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/sme.sap.com/v1alpha1/zz_generated.deepcopy.go index 2287562..6b27e3f 100644 --- a/pkg/apis/sme.sap.com/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/sme.sap.com/v1alpha1/zz_generated.deepcopy.go @@ -485,6 +485,82 @@ func (in *CAPTenantOperationStep) DeepCopy() *CAPTenantOperationStep { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CAPTenantOutput) DeepCopyInto(out *CAPTenantOutput) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CAPTenantOutput. +func (in *CAPTenantOutput) DeepCopy() *CAPTenantOutput { + if in == nil { + return nil + } + out := new(CAPTenantOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CAPTenantOutput) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CAPTenantOutputList) DeepCopyInto(out *CAPTenantOutputList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CAPTenantOutput, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CAPTenantOutputList. +func (in *CAPTenantOutputList) DeepCopy() *CAPTenantOutputList { + if in == nil { + return nil + } + out := new(CAPTenantOutputList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CAPTenantOutputList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CAPTenantOutputSpec) DeepCopyInto(out *CAPTenantOutputSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CAPTenantOutputSpec. +func (in *CAPTenantOutputSpec) DeepCopy() *CAPTenantOutputSpec { + if in == nil { + return nil + } + out := new(CAPTenantOutputSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CAPTenantSpec) DeepCopyInto(out *CAPTenantSpec) { *out = *in diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/captenantoutput.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/captenantoutput.go new file mode 100644 index 0000000..489c807 --- /dev/null +++ b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/captenantoutput.go @@ -0,0 +1,199 @@ +/* +SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and cap-operator contributors +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// CAPTenantOutputApplyConfiguration represents an declarative configuration of the CAPTenantOutput type for use +// with apply. +type CAPTenantOutputApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *CAPTenantOutputSpecApplyConfiguration `json:"spec,omitempty"` +} + +// CAPTenantOutput constructs an declarative configuration of the CAPTenantOutput type for use with +// apply. +func CAPTenantOutput(name, namespace string) *CAPTenantOutputApplyConfiguration { + b := &CAPTenantOutputApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("CAPTenantOutput") + b.WithAPIVersion("sme.sap.com/v1alpha1") + return b +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithKind(value string) *CAPTenantOutputApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithAPIVersion(value string) *CAPTenantOutputApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithName(value string) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithGenerateName(value string) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithNamespace(value string) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithUID(value types.UID) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithResourceVersion(value string) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithGeneration(value int64) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithCreationTimestamp(value metav1.Time) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *CAPTenantOutputApplyConfiguration) WithLabels(entries map[string]string) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *CAPTenantOutputApplyConfiguration) WithAnnotations(entries map[string]string) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *CAPTenantOutputApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *CAPTenantOutputApplyConfiguration) WithFinalizers(values ...string) *CAPTenantOutputApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *CAPTenantOutputApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *CAPTenantOutputApplyConfiguration) WithSpec(value *CAPTenantOutputSpecApplyConfiguration) *CAPTenantOutputApplyConfiguration { + b.Spec = value + return b +} diff --git a/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/captenantoutputspec.go b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/captenantoutputspec.go new file mode 100644 index 0000000..4336474 --- /dev/null +++ b/pkg/client/applyconfiguration/sme.sap.com/v1alpha1/captenantoutputspec.go @@ -0,0 +1,28 @@ +/* +SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and cap-operator contributors +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// CAPTenantOutputSpecApplyConfiguration represents an declarative configuration of the CAPTenantOutputSpec type for use +// with apply. +type CAPTenantOutputSpecApplyConfiguration struct { + SubscriptionCallbackData *string `json:"subscriptionCallbackData,omitempty"` +} + +// CAPTenantOutputSpecApplyConfiguration constructs an declarative configuration of the CAPTenantOutputSpec type for use with +// apply. +func CAPTenantOutputSpec() *CAPTenantOutputSpecApplyConfiguration { + return &CAPTenantOutputSpecApplyConfiguration{} +} + +// WithSubscriptionCallbackData sets the SubscriptionCallbackData field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SubscriptionCallbackData field is set to the value of the last call. +func (b *CAPTenantOutputSpecApplyConfiguration) WithSubscriptionCallbackData(value string) *CAPTenantOutputSpecApplyConfiguration { + b.SubscriptionCallbackData = &value + return b +} diff --git a/pkg/client/applyconfiguration/utils.go b/pkg/client/applyconfiguration/utils.go index 9e50faf..414cc45 100644 --- a/pkg/client/applyconfiguration/utils.go +++ b/pkg/client/applyconfiguration/utils.go @@ -46,6 +46,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &smesapcomv1alpha1.CAPTenantOperationStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("CAPTenantOperationStep"): return &smesapcomv1alpha1.CAPTenantOperationStepApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("CAPTenantOutput"): + return &smesapcomv1alpha1.CAPTenantOutputApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("CAPTenantOutputSpec"): + return &smesapcomv1alpha1.CAPTenantOutputSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("CAPTenantSpec"): return &smesapcomv1alpha1.CAPTenantSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("CAPTenantStatus"): diff --git a/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/captenantoutput.go b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/captenantoutput.go new file mode 100644 index 0000000..0050c07 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/captenantoutput.go @@ -0,0 +1,197 @@ +/* +SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and cap-operator contributors +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "github.com/sap/cap-operator/pkg/apis/sme.sap.com/v1alpha1" + smesapcomv1alpha1 "github.com/sap/cap-operator/pkg/client/applyconfiguration/sme.sap.com/v1alpha1" + scheme "github.com/sap/cap-operator/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CAPTenantOutputsGetter has a method to return a CAPTenantOutputInterface. +// A group's client should implement this interface. +type CAPTenantOutputsGetter interface { + CAPTenantOutputs(namespace string) CAPTenantOutputInterface +} + +// CAPTenantOutputInterface has methods to work with CAPTenantOutput resources. +type CAPTenantOutputInterface interface { + Create(ctx context.Context, cAPTenantOutput *v1alpha1.CAPTenantOutput, opts v1.CreateOptions) (*v1alpha1.CAPTenantOutput, error) + Update(ctx context.Context, cAPTenantOutput *v1alpha1.CAPTenantOutput, opts v1.UpdateOptions) (*v1alpha1.CAPTenantOutput, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.CAPTenantOutput, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.CAPTenantOutputList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.CAPTenantOutput, err error) + Apply(ctx context.Context, cAPTenantOutput *smesapcomv1alpha1.CAPTenantOutputApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.CAPTenantOutput, err error) + CAPTenantOutputExpansion +} + +// cAPTenantOutputs implements CAPTenantOutputInterface +type cAPTenantOutputs struct { + client rest.Interface + ns string +} + +// newCAPTenantOutputs returns a CAPTenantOutputs +func newCAPTenantOutputs(c *SmeV1alpha1Client, namespace string) *cAPTenantOutputs { + return &cAPTenantOutputs{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cAPTenantOutput, and returns the corresponding cAPTenantOutput object, and an error if there is any. +func (c *cAPTenantOutputs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.CAPTenantOutput, err error) { + result = &v1alpha1.CAPTenantOutput{} + err = c.client.Get(). + Namespace(c.ns). + Resource("captenantoutputs"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CAPTenantOutputs that match those selectors. +func (c *cAPTenantOutputs) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.CAPTenantOutputList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.CAPTenantOutputList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("captenantoutputs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cAPTenantOutputs. +func (c *cAPTenantOutputs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("captenantoutputs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cAPTenantOutput and creates it. Returns the server's representation of the cAPTenantOutput, and an error, if there is any. +func (c *cAPTenantOutputs) Create(ctx context.Context, cAPTenantOutput *v1alpha1.CAPTenantOutput, opts v1.CreateOptions) (result *v1alpha1.CAPTenantOutput, err error) { + result = &v1alpha1.CAPTenantOutput{} + err = c.client.Post(). + Namespace(c.ns). + Resource("captenantoutputs"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cAPTenantOutput). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cAPTenantOutput and updates it. Returns the server's representation of the cAPTenantOutput, and an error, if there is any. +func (c *cAPTenantOutputs) Update(ctx context.Context, cAPTenantOutput *v1alpha1.CAPTenantOutput, opts v1.UpdateOptions) (result *v1alpha1.CAPTenantOutput, err error) { + result = &v1alpha1.CAPTenantOutput{} + err = c.client.Put(). + Namespace(c.ns). + Resource("captenantoutputs"). + Name(cAPTenantOutput.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cAPTenantOutput). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cAPTenantOutput and deletes it. Returns an error if one occurs. +func (c *cAPTenantOutputs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("captenantoutputs"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cAPTenantOutputs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("captenantoutputs"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cAPTenantOutput. +func (c *cAPTenantOutputs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.CAPTenantOutput, err error) { + result = &v1alpha1.CAPTenantOutput{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("captenantoutputs"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied cAPTenantOutput. +func (c *cAPTenantOutputs) Apply(ctx context.Context, cAPTenantOutput *smesapcomv1alpha1.CAPTenantOutputApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.CAPTenantOutput, err error) { + if cAPTenantOutput == nil { + return nil, fmt.Errorf("cAPTenantOutput provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(cAPTenantOutput) + if err != nil { + return nil, err + } + name := cAPTenantOutput.Name + if name == nil { + return nil, fmt.Errorf("cAPTenantOutput.Name must be provided to Apply") + } + result = &v1alpha1.CAPTenantOutput{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("captenantoutputs"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/fake/fake_captenantoutput.go b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/fake/fake_captenantoutput.go new file mode 100644 index 0000000..7e245e4 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/fake/fake_captenantoutput.go @@ -0,0 +1,143 @@ +/* +SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and cap-operator contributors +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + json "encoding/json" + "fmt" + + v1alpha1 "github.com/sap/cap-operator/pkg/apis/sme.sap.com/v1alpha1" + smesapcomv1alpha1 "github.com/sap/cap-operator/pkg/client/applyconfiguration/sme.sap.com/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeCAPTenantOutputs implements CAPTenantOutputInterface +type FakeCAPTenantOutputs struct { + Fake *FakeSmeV1alpha1 + ns string +} + +var captenantoutputsResource = v1alpha1.SchemeGroupVersion.WithResource("captenantoutputs") + +var captenantoutputsKind = v1alpha1.SchemeGroupVersion.WithKind("CAPTenantOutput") + +// Get takes name of the cAPTenantOutput, and returns the corresponding cAPTenantOutput object, and an error if there is any. +func (c *FakeCAPTenantOutputs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.CAPTenantOutput, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(captenantoutputsResource, c.ns, name), &v1alpha1.CAPTenantOutput{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CAPTenantOutput), err +} + +// List takes label and field selectors, and returns the list of CAPTenantOutputs that match those selectors. +func (c *FakeCAPTenantOutputs) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.CAPTenantOutputList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(captenantoutputsResource, captenantoutputsKind, c.ns, opts), &v1alpha1.CAPTenantOutputList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.CAPTenantOutputList{ListMeta: obj.(*v1alpha1.CAPTenantOutputList).ListMeta} + for _, item := range obj.(*v1alpha1.CAPTenantOutputList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested cAPTenantOutputs. +func (c *FakeCAPTenantOutputs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(captenantoutputsResource, c.ns, opts)) + +} + +// Create takes the representation of a cAPTenantOutput and creates it. Returns the server's representation of the cAPTenantOutput, and an error, if there is any. +func (c *FakeCAPTenantOutputs) Create(ctx context.Context, cAPTenantOutput *v1alpha1.CAPTenantOutput, opts v1.CreateOptions) (result *v1alpha1.CAPTenantOutput, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(captenantoutputsResource, c.ns, cAPTenantOutput), &v1alpha1.CAPTenantOutput{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CAPTenantOutput), err +} + +// Update takes the representation of a cAPTenantOutput and updates it. Returns the server's representation of the cAPTenantOutput, and an error, if there is any. +func (c *FakeCAPTenantOutputs) Update(ctx context.Context, cAPTenantOutput *v1alpha1.CAPTenantOutput, opts v1.UpdateOptions) (result *v1alpha1.CAPTenantOutput, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(captenantoutputsResource, c.ns, cAPTenantOutput), &v1alpha1.CAPTenantOutput{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CAPTenantOutput), err +} + +// Delete takes name of the cAPTenantOutput and deletes it. Returns an error if one occurs. +func (c *FakeCAPTenantOutputs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(captenantoutputsResource, c.ns, name, opts), &v1alpha1.CAPTenantOutput{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeCAPTenantOutputs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(captenantoutputsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.CAPTenantOutputList{}) + return err +} + +// Patch applies the patch and returns the patched cAPTenantOutput. +func (c *FakeCAPTenantOutputs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.CAPTenantOutput, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(captenantoutputsResource, c.ns, name, pt, data, subresources...), &v1alpha1.CAPTenantOutput{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CAPTenantOutput), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied cAPTenantOutput. +func (c *FakeCAPTenantOutputs) Apply(ctx context.Context, cAPTenantOutput *smesapcomv1alpha1.CAPTenantOutputApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.CAPTenantOutput, err error) { + if cAPTenantOutput == nil { + return nil, fmt.Errorf("cAPTenantOutput provided to Apply must not be nil") + } + data, err := json.Marshal(cAPTenantOutput) + if err != nil { + return nil, err + } + name := cAPTenantOutput.Name + if name == nil { + return nil, fmt.Errorf("cAPTenantOutput.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(captenantoutputsResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha1.CAPTenantOutput{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CAPTenantOutput), err +} diff --git a/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/fake/fake_sme.sap.com_client.go b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/fake/fake_sme.sap.com_client.go index d07ac32..47765dc 100644 --- a/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/fake/fake_sme.sap.com_client.go +++ b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/fake/fake_sme.sap.com_client.go @@ -33,6 +33,10 @@ func (c *FakeSmeV1alpha1) CAPTenantOperations(namespace string) v1alpha1.CAPTena return &FakeCAPTenantOperations{c, namespace} } +func (c *FakeSmeV1alpha1) CAPTenantOutputs(namespace string) v1alpha1.CAPTenantOutputInterface { + return &FakeCAPTenantOutputs{c, namespace} +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeSmeV1alpha1) RESTClient() rest.Interface { diff --git a/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/generated_expansion.go index 9f73473..0685dfa 100644 --- a/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/generated_expansion.go @@ -14,3 +14,5 @@ type CAPApplicationVersionExpansion interface{} type CAPTenantExpansion interface{} type CAPTenantOperationExpansion interface{} + +type CAPTenantOutputExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/sme.sap.com_client.go b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/sme.sap.com_client.go index 3c81bb2..082b55c 100644 --- a/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/sme.sap.com_client.go +++ b/pkg/client/clientset/versioned/typed/sme.sap.com/v1alpha1/sme.sap.com_client.go @@ -21,6 +21,7 @@ type SmeV1alpha1Interface interface { CAPApplicationVersionsGetter CAPTenantsGetter CAPTenantOperationsGetter + CAPTenantOutputsGetter } // SmeV1alpha1Client is used to interact with features provided by the sme.sap.com group. @@ -44,6 +45,10 @@ func (c *SmeV1alpha1Client) CAPTenantOperations(namespace string) CAPTenantOpera return newCAPTenantOperations(c, namespace) } +func (c *SmeV1alpha1Client) CAPTenantOutputs(namespace string) CAPTenantOutputInterface { + return newCAPTenantOutputs(c, namespace) +} + // NewForConfig creates a new SmeV1alpha1Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 10d3752..ef17c18 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -50,6 +50,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Sme().V1alpha1().CAPTenants().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("captenantoperations"): return &genericInformer{resource: resource.GroupResource(), informer: f.Sme().V1alpha1().CAPTenantOperations().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("captenantoutputs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Sme().V1alpha1().CAPTenantOutputs().Informer()}, nil } diff --git a/pkg/client/informers/externalversions/sme.sap.com/v1alpha1/captenantoutput.go b/pkg/client/informers/externalversions/sme.sap.com/v1alpha1/captenantoutput.go new file mode 100644 index 0000000..95da186 --- /dev/null +++ b/pkg/client/informers/externalversions/sme.sap.com/v1alpha1/captenantoutput.go @@ -0,0 +1,79 @@ +/* +SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and cap-operator contributors +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + smesapcomv1alpha1 "github.com/sap/cap-operator/pkg/apis/sme.sap.com/v1alpha1" + versioned "github.com/sap/cap-operator/pkg/client/clientset/versioned" + internalinterfaces "github.com/sap/cap-operator/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/sap/cap-operator/pkg/client/listers/sme.sap.com/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// CAPTenantOutputInformer provides access to a shared informer and lister for +// CAPTenantOutputs. +type CAPTenantOutputInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.CAPTenantOutputLister +} + +type cAPTenantOutputInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCAPTenantOutputInformer constructs a new informer for CAPTenantOutput type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCAPTenantOutputInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCAPTenantOutputInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCAPTenantOutputInformer constructs a new informer for CAPTenantOutput type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCAPTenantOutputInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SmeV1alpha1().CAPTenantOutputs(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SmeV1alpha1().CAPTenantOutputs(namespace).Watch(context.TODO(), options) + }, + }, + &smesapcomv1alpha1.CAPTenantOutput{}, + resyncPeriod, + indexers, + ) +} + +func (f *cAPTenantOutputInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCAPTenantOutputInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cAPTenantOutputInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&smesapcomv1alpha1.CAPTenantOutput{}, f.defaultInformer) +} + +func (f *cAPTenantOutputInformer) Lister() v1alpha1.CAPTenantOutputLister { + return v1alpha1.NewCAPTenantOutputLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/sme.sap.com/v1alpha1/interface.go b/pkg/client/informers/externalversions/sme.sap.com/v1alpha1/interface.go index b04e48b..760bd7f 100644 --- a/pkg/client/informers/externalversions/sme.sap.com/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/sme.sap.com/v1alpha1/interface.go @@ -21,6 +21,8 @@ type Interface interface { CAPTenants() CAPTenantInformer // CAPTenantOperations returns a CAPTenantOperationInformer. CAPTenantOperations() CAPTenantOperationInformer + // CAPTenantOutputs returns a CAPTenantOutputInformer. + CAPTenantOutputs() CAPTenantOutputInformer } type version struct { @@ -53,3 +55,8 @@ func (v *version) CAPTenants() CAPTenantInformer { func (v *version) CAPTenantOperations() CAPTenantOperationInformer { return &cAPTenantOperationInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } + +// CAPTenantOutputs returns a CAPTenantOutputInformer. +func (v *version) CAPTenantOutputs() CAPTenantOutputInformer { + return &cAPTenantOutputInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/listers/sme.sap.com/v1alpha1/captenantoutput.go b/pkg/client/listers/sme.sap.com/v1alpha1/captenantoutput.go new file mode 100644 index 0000000..f98605c --- /dev/null +++ b/pkg/client/listers/sme.sap.com/v1alpha1/captenantoutput.go @@ -0,0 +1,88 @@ +/* +SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and cap-operator contributors +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/sap/cap-operator/pkg/apis/sme.sap.com/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CAPTenantOutputLister helps list CAPTenantOutputs. +// All objects returned here must be treated as read-only. +type CAPTenantOutputLister interface { + // List lists all CAPTenantOutputs in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.CAPTenantOutput, err error) + // CAPTenantOutputs returns an object that can list and get CAPTenantOutputs. + CAPTenantOutputs(namespace string) CAPTenantOutputNamespaceLister + CAPTenantOutputListerExpansion +} + +// cAPTenantOutputLister implements the CAPTenantOutputLister interface. +type cAPTenantOutputLister struct { + indexer cache.Indexer +} + +// NewCAPTenantOutputLister returns a new CAPTenantOutputLister. +func NewCAPTenantOutputLister(indexer cache.Indexer) CAPTenantOutputLister { + return &cAPTenantOutputLister{indexer: indexer} +} + +// List lists all CAPTenantOutputs in the indexer. +func (s *cAPTenantOutputLister) List(selector labels.Selector) (ret []*v1alpha1.CAPTenantOutput, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.CAPTenantOutput)) + }) + return ret, err +} + +// CAPTenantOutputs returns an object that can list and get CAPTenantOutputs. +func (s *cAPTenantOutputLister) CAPTenantOutputs(namespace string) CAPTenantOutputNamespaceLister { + return cAPTenantOutputNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CAPTenantOutputNamespaceLister helps list and get CAPTenantOutputs. +// All objects returned here must be treated as read-only. +type CAPTenantOutputNamespaceLister interface { + // List lists all CAPTenantOutputs in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.CAPTenantOutput, err error) + // Get retrieves the CAPTenantOutput from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.CAPTenantOutput, error) + CAPTenantOutputNamespaceListerExpansion +} + +// cAPTenantOutputNamespaceLister implements the CAPTenantOutputNamespaceLister +// interface. +type cAPTenantOutputNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CAPTenantOutputs in the indexer for a given namespace. +func (s cAPTenantOutputNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.CAPTenantOutput, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.CAPTenantOutput)) + }) + return ret, err +} + +// Get retrieves the CAPTenantOutput from the indexer for a given namespace and name. +func (s cAPTenantOutputNamespaceLister) Get(name string) (*v1alpha1.CAPTenantOutput, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("captenantoutput"), name) + } + return obj.(*v1alpha1.CAPTenantOutput), nil +} diff --git a/pkg/client/listers/sme.sap.com/v1alpha1/expansion_generated.go b/pkg/client/listers/sme.sap.com/v1alpha1/expansion_generated.go index e6b6f5f..dfbc058 100644 --- a/pkg/client/listers/sme.sap.com/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/sme.sap.com/v1alpha1/expansion_generated.go @@ -38,3 +38,11 @@ type CAPTenantOperationListerExpansion interface{} // CAPTenantOperationNamespaceListerExpansion allows custom methods to be added to // CAPTenantOperationNamespaceLister. type CAPTenantOperationNamespaceListerExpansion interface{} + +// CAPTenantOutputListerExpansion allows custom methods to be added to +// CAPTenantOutputLister. +type CAPTenantOutputListerExpansion interface{} + +// CAPTenantOutputNamespaceListerExpansion allows custom methods to be added to +// CAPTenantOutputNamespaceLister. +type CAPTenantOutputNamespaceListerExpansion interface{} diff --git a/website/content/en/docs/usage/resources/captenantoutput.md b/website/content/en/docs/usage/resources/captenantoutput.md new file mode 100644 index 0000000..6c183fb --- /dev/null +++ b/website/content/en/docs/usage/resources/captenantoutput.md @@ -0,0 +1,31 @@ +--- +title: "CAPTenantOutput" +linkTitle: "CAPTenantOutput" +weight: 40 +type: "docs" +description: > + How to configure the `CAPTenantOutput` resource +--- + +{{< alert color="warning" title="Warning" >}} +The `CAPTenantOutput` may be used to add additonal data to the parameters asynchronous callback from the SaaS provisioning service during tenant onboarding. The resource is not reconciled but just consumed by the subscription server to generate additional data. It has the following structure: +{{< /alert >}} + +```yaml +apiVersion: sme.sap.com/v1alpha1 +kind: CAPTenantOutput +metadata: + name: cap-app-consumer-output + namespace: cap-ns + labels: + sme.sap.com/btp-tenant-id: cb46733-1279-48be-fdf434-aa2bae55d7b5 +spec: + subscriptionCallbackData: '{foo: bar}' + +``` +The example above shows an instance of the resource that is associated with a tenant via the `sme.sap.com/btp-tenant-id` label (which must be set by consumers). +The resource is meant to be created/updated during tenant operations for e.g. the ones created during tenant onboarding. As of now, the primary intention of this resource is to enhance the parameters of subscription callback during tenant onboarding. But the resources may be used for further scenarios in the future. + +Any RBAC related updates needed to create/modify the resources for e.g. in a custom tenant operation needs to be handled by consumers and assigned to the relevant job via `serviceAccountName` config for that workload (job). + +Note that all instances of this resources found for a given tenant will be cleaned up before any `CAPTenantOperation` is created. \ No newline at end of file diff --git a/website/includes/api-reference.html b/website/includes/api-reference.html index 8f948d6..0aeea08 100644 --- a/website/includes/api-reference.html +++ b/website/includes/api-reference.html @@ -14,6 +14,8 @@

sme.sap.com/v1alpha1

CAPTenant
  • CAPTenantOperation +
  • +CAPTenantOutput
  • CAPApplication

    @@ -554,6 +556,79 @@

    CAPTenantOperation +

    CAPTenantOutput +

    +
    +

    CAPTenantOutput is the schema for captenantoutputs API

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    +string
    + +sme.sap.com/v1alpha1 + +
    +kind
    +string +
    CAPTenantOutput
    +metadata
    + + +Kubernetes meta/v1.ObjectMeta + + +
    +Refer to the Kubernetes API documentation for the fields of the +metadata field. +
    +spec
    + + +CAPTenantOutputSpec + + +
    +

    CAPTenantOutputData spec

    +
    +
    + + + + + +
    +subscriptionCallbackData
    + +string + +
    +
    +

    ApplicationDomains

    @@ -1295,6 +1370,33 @@

    CAPTenantOperationType +

    CAPTenantOutputSpec +

    +

    +(Appears on: CAPTenantOutput) +

    +
    +
    + + + + + + + + + + + + + +
    FieldDescription
    +subscriptionCallbackData
    + +string + +
    +

    CAPTenantSpec

    @@ -2374,5 +2476,5 @@

    WorkloadDetails

    Generated with gen-crd-api-reference-docs -on git commit bf6ae8c. +on git commit 22e4ca7.