From 8b9536ba6fde515b413a8a293746adf85ddba9f1 Mon Sep 17 00:00:00 2001 From: Fanny Strudel Date: Thu, 9 Jan 2025 10:26:12 -0800 Subject: [PATCH] govc: enhance VAPI for vSphere Supervisor Services - Update GET for both /supervisor-services and /supervisor-services/{id}/versions - Add GET for specific service and specific version: /supervisor-services/{id} and /supervisor-services/{id}/versions/{version} - Add DELETE for /supervisor-services/{id} and /supervisor-services/{id}/versions/{version}: DELETE for /supervisor-services/{id} and /supervisor-services/{id}/versions/{version} - Add activate/deactivate for a service version too (you can't delete a version of a service if it's not deactivated first): PATCH for superrvisor-services/{id} and /supervisor-services/{id}/versions/{version} - Update namespace.bats tests to test list and get - Update VAPI simulator to use `ServeHTTP` to make sure the path vlaues are set properly - Also update copyrights Fixes #3624 Testing Done: Ran `make check` and ./govc/test/namespace.bats Also ran against a real VC where I added 1 dummy service with 2 versions: `export GOVC_URL=...` ``` $ cat sample-pkg.test.carvel.dev-1.0.0.yaml apiVersion: data.packaging.carvel.dev/v1alpha1 kind: PackageMetadata metadata: name: sample-pkg-testgovc.test.carvel.dev spec: displayName: "sample-service for testing" shortDescription: "Sample core service description" --- apiVersion: data.packaging.carvel.dev/v1alpha1 kind: Package metadata: name: sample-pkg-testgovc.test.carvel.dev.1.0.0 spec: refName: sample-pkg-testgovc.test.carvel.dev version: 1.0.0 releasedAt: 2021-05-05T18:57:06Z template: spec: fetch: - imgpkgBundle: image: wcp-docker-ci.artifactory.eng.vmware.com/carvel/simple-app-bundle:v0.0.0 template: - ytt: paths: - config-step-2-template - config-step-2a-overlays deploy: - kapp: { } $ govc namespace.service.create sample-pkg.test.carvel.dev-1.0.0.yaml $ govc namespace.service.create sample-pkg.test.carvel.dev-1.0.0.yaml govc: 400 Bad Request: {"messages":[{"args":["sample-pkg-testgovc.test.carvel.dev","Supervisor Service"],"default_message":"Failed to create Supervisor Service sample-pkg-testgovc.test.carvel.dev because an instance of Supervisor Service with the same identifier already exists.","localized":"Failed to create Supervisor Service sample-pkg-testgovc.test.carvel.dev because an instance of Supervisor Service with the same identifier already exists.","id":"vcenter.wcp.appplatform.supervisorservice.write.unique_violation"}]} $ govc namespace.service.version.create sample-pkg-testgovc.test.carvel.dev sample-pkg.test.carvel.dev-2.0.0.yaml $ govc namespace.service.version.deactivate sample-pkg-testgovc.test.carvel.dev 2.0.0 $ govc namespace.service.version.activate sample-pkg-testgovc.test.carvel.dev 2.0.0 $ govc namespace.service.version.rm sample-pkg-testgovc.test.carvel.dev 2.0.0 govc: 400 Bad Request: {"messages":[{"args":["sample-pkg-testgovc.test.carvel.dev","2.0.0"],"default_message":"Cannot delete the Supervisor Service (sample-pkg-testgovc.test.carvel.dev) version (2.0.0) because it is active.","localized":"Cannot delete the Supervisor Service (sample-pkg-testgovc.test.carvel.dev) version (2.0.0) because it is active.","id":"vcenter.wcp.appplatform.supervisorserviceversion.delete.activated"}]} $ govc namespace.service.version.deactivate sample-pkg-testgovc.test.carvel.dev 2.0.0 $ govc namespace.service.version.rm sample-pkg-testgovc.test.carvel.dev 2.0.0 $ govc namespace.service.ls sample-pkg-testgovc.test.carvel.dev 2.0.0 $ govc namespace.service.ls -json [...] { "supervisor_service": "sample-pkg-testgovc.test.carvel.dev", "display_name": "sample-service for testing version", "state": "ACTIVATED" }, ] $ govc namespace.service.info -json sample-pkg-testgovc.test.carvel.dev { "display_name": "sample-service for testing version", "state": "ACTIVATED", "description": "Sample core service description", "must_be_installed": false, "has_default_versions_registered": false } { "must_be_installed": false, "has_default_versions_registered": false, "description": "Sample core service description", "state": "ACTIVATED", "display_name": "sample-service for testing version" } ``` --- cli/namespace/service/activate.go | 20 +-- cli/namespace/service/create.go | 68 +++++------ cli/namespace/service/deactivate.go | 20 +-- cli/namespace/service/flag.go | 63 ++++++++++ cli/namespace/service/info.go | 19 +-- cli/namespace/service/ls.go | 20 +-- cli/namespace/service/rm.go | 20 +-- cli/namespace/service/version/activate.go | 57 +++++++++ cli/namespace/service/version/create.go | 87 ++++++++++++++ cli/namespace/service/version/deactivate.go | 57 +++++++++ cli/namespace/service/version/info.go | 104 ++++++++++++++++ cli/namespace/service/version/ls.go | 107 +++++++++++++++++ cli/namespace/service/version/rm.go | 57 +++++++++ govc/USAGE.md | 73 +++++++++-- govc/main.go | 1 + govc/test/namespace.bats | 46 ++++++- vapi/namespace/internal/internal.go | 19 +-- vapi/namespace/simulator/simulator.go | 127 +++++++++++++++----- vapi/namespace/supervisorsvc.go | 126 ++++++++++++++----- vapi/simulator/simulator.go | 22 +--- 20 files changed, 898 insertions(+), 215 deletions(-) create mode 100644 cli/namespace/service/flag.go create mode 100644 cli/namespace/service/version/activate.go create mode 100644 cli/namespace/service/version/create.go create mode 100644 cli/namespace/service/version/deactivate.go create mode 100644 cli/namespace/service/version/info.go create mode 100644 cli/namespace/service/version/ls.go create mode 100644 cli/namespace/service/version/rm.go diff --git a/cli/namespace/service/activate.go b/cli/namespace/service/activate.go index 9285a4fee..e7ccd0b57 100644 --- a/cli/namespace/service/activate.go +++ b/cli/namespace/service/activate.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2021 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package service @@ -39,7 +27,7 @@ func (cmd *activate) Register(ctx context.Context, f *flag.FlagSet) { } func (cmd *activate) Description() string { - return `Activates a vSphere Namespace Supervisor Service. + return `Activates a vSphere Supervisor Service (and all its versions). Examples: govc namespace.service.activate my-supervisor-service other-supervisor-service` diff --git a/cli/namespace/service/create.go b/cli/namespace/service/create.go index 2040e58ec..ae4cd2304 100644 --- a/cli/namespace/service/create.go +++ b/cli/namespace/service/create.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2021 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package service @@ -30,10 +18,7 @@ import ( type create struct { *flags.ClientFlag - - specType string - trustedProvider bool - acceptEULA bool + *ServiceVersionFlag } func init() { @@ -44,13 +29,14 @@ func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) { cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) cmd.ClientFlag.Register(ctx, f) - f.StringVar(&cmd.specType, "spec-type", "vsphere", "Type of Spec: only vsphere is supported right now") - f.BoolVar(&cmd.trustedProvider, "trusted", false, "Define if this is a trusted provider") - f.BoolVar(&cmd.acceptEULA, "accept-eula", false, "Auto accept EULA") + cmd.ServiceVersionFlag = &ServiceVersionFlag{} + cmd.ServiceVersionFlag.Register(ctx, f) } func (cmd *create) Description() string { - return `Creates a vSphere Namespace Supervisor Service. + return `Registers a vSphere Supervisor Service version on vCenter for a new service. +A service version can be registered once on vCenter and then be installed on multiple vSphere Supervisors managed by this vCenter. +A vSphere Supervisor Service contains a list of service versions. Examples: govc namespace.service.create manifest.yaml` @@ -60,30 +46,41 @@ func (cmd *create) Usage() string { return "MANIFEST" } +func (cmd *create) Process(ctx context.Context) error { + if err := cmd.ServiceVersionFlag.Process(ctx); err != nil { + return err + } + return cmd.ClientFlag.Process(ctx) +} + func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { - manifest := f.Args() - if len(manifest) != 1 { + if f.NArg() != 1 { return flag.ErrHelp } - if cmd.specType != "vsphere" { - return fmt.Errorf("only vsphere specs are accepted right now") - } + manifestFile := f.Arg(0) - manifestFile, err := os.ReadFile(manifest[0]) + manifest, err := os.ReadFile(manifestFile) if err != nil { return fmt.Errorf("failed to read manifest file: %s", err) } + content := base64.StdEncoding.EncodeToString(manifest) - content := base64.StdEncoding.EncodeToString(manifestFile) - service := namespace.SupervisorService{ - VsphereService: namespace.SupervisorServicesVSphereSpec{ + service := namespace.SupervisorService{} + if cmd.ServiceVersionFlag.SpecType == "carvel" { + service.CarvelService = &namespace.SupervisorServicesCarvelSpec{ + VersionSpec: namespace.CarvelVersionCreateSpec{ + Content: content, + }, + } + } else { + service.VsphereService = &namespace.SupervisorServicesVSphereSpec{ VersionSpec: namespace.SupervisorServicesVSphereVersionCreateSpec{ Content: content, - AcceptEula: cmd.acceptEULA, - TrustedProvider: cmd.trustedProvider, + AcceptEula: cmd.ServiceVersionFlag.AcceptEULA, + TrustedProvider: cmd.ServiceVersionFlag.TrustedProvider, }, - }, + } } c, err := cmd.RestClient() @@ -93,5 +90,4 @@ func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { m := namespace.NewManager(c) return m.CreateSupervisorService(ctx, &service) - } diff --git a/cli/namespace/service/deactivate.go b/cli/namespace/service/deactivate.go index 0b7be7d38..6f799abb6 100644 --- a/cli/namespace/service/deactivate.go +++ b/cli/namespace/service/deactivate.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2021 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package service @@ -39,7 +27,7 @@ func (cmd *deactivate) Register(ctx context.Context, f *flag.FlagSet) { } func (cmd *deactivate) Description() string { - return `Deactivates a vSphere Namespace Supervisor Service. + return `Deactivates a vSphere Supervisor Service (and all its versions). Examples: govc namespace.service.deactivate my-supervisor-service other-supervisor-service` diff --git a/cli/namespace/service/flag.go b/cli/namespace/service/flag.go new file mode 100644 index 000000000..0b9d944b4 --- /dev/null +++ b/cli/namespace/service/flag.go @@ -0,0 +1,63 @@ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 + +package service + +import ( + "context" + "encoding/base64" + "flag" + "fmt" + "os" + + "github.com/vmware/govmomi/vapi/namespace" +) + +// Common processing of flags for service and service versions creation/update commands. +type ServiceVersionFlag struct { + SpecType string + TrustedProvider bool + AcceptEULA bool + content string +} + +func (svf *ServiceVersionFlag) Register(ctx context.Context, f *flag.FlagSet) { + f.StringVar(&svf.SpecType, "spec-type", "carvel", "Type of Spec: vsphere (deprecated) or carvel") + f.BoolVar(&svf.TrustedProvider, "trusted", false, "Define if this is a trusted provider (only applicable for vSphere spec type)") + f.BoolVar(&svf.AcceptEULA, "accept-eula", false, "Auto accept EULA (only required for vSphere spec type)") +} + +func (svf *ServiceVersionFlag) Process(ctx context.Context) error { + if svf.SpecType != "vsphere" && svf.SpecType != "carvel" { + return fmt.Errorf("Invalid type: '%v', only 'vsphere' and 'carvel' specs are supported", svf.SpecType) + } + return nil +} + +// SupervisorServiceVersionSpec returns a spec for a supervisor service version definition +func (svf *ServiceVersionFlag) SupervisorServiceVersionSpec(manifestFile string) (namespace.SupervisorService, error) { + service := namespace.SupervisorService{} + manifest, err := os.ReadFile(manifestFile) + if err != nil { + return service, fmt.Errorf("failed to read manifest file: %s", err) + } + + content := base64.StdEncoding.EncodeToString(manifest) + if svf.SpecType == "carvel" { + service.CarvelService = &namespace.SupervisorServicesCarvelSpec{ + VersionSpec: namespace.CarvelVersionCreateSpec{ + Content: content, + }, + } + } else { + service.VsphereService = &namespace.SupervisorServicesVSphereSpec{ + VersionSpec: namespace.SupervisorServicesVSphereVersionCreateSpec{ + Content: content, + AcceptEula: svf.AcceptEULA, + TrustedProvider: svf.TrustedProvider, + }, + } + } + return service, nil +} diff --git a/cli/namespace/service/info.go b/cli/namespace/service/info.go index 1ff38b08e..b78df33de 100644 --- a/cli/namespace/service/info.go +++ b/cli/namespace/service/info.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2021-2023 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package service @@ -73,7 +61,6 @@ func (r *infoWriter) Write(w io.Writer) error { fmt.Fprintf(tw, "%s", r.Service.Name) fmt.Fprintf(tw, "\t%s", r.Service.State) fmt.Fprintf(tw, "\t%s", r.Service.Description) - fmt.Fprintf(tw, "\n") return tw.Flush() diff --git a/cli/namespace/service/ls.go b/cli/namespace/service/ls.go index 10c8cd6c5..be8c5fa82 100644 --- a/cli/namespace/service/ls.go +++ b/cli/namespace/service/ls.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2021-2023 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package service @@ -58,7 +46,7 @@ func (cmd *ls) Process(ctx context.Context) error { } func (cmd *ls) Description() string { - return `List namepace registered supervisor services. + return `List all registered vSphere Supervisor Services. Examples: govc namespace.service.ls diff --git a/cli/namespace/service/rm.go b/cli/namespace/service/rm.go index a584d9190..8d95c3b55 100644 --- a/cli/namespace/service/rm.go +++ b/cli/namespace/service/rm.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2021 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package service @@ -40,7 +28,7 @@ func (cmd *rm) Register(ctx context.Context, f *flag.FlagSet) { } func (cmd *rm) Description() string { - return `Removes a vSphere Namespace Supervisor Service. + return `Removes a vSphere Supervisor Service. Examples: govc namespace.service.rm my-supervisor-service other-supervisor-service` diff --git a/cli/namespace/service/version/activate.go b/cli/namespace/service/version/activate.go new file mode 100644 index 000000000..6cb439410 --- /dev/null +++ b/cli/namespace/service/version/activate.go @@ -0,0 +1,57 @@ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 + +package version + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/cli" + "github.com/vmware/govmomi/cli/flags" + "github.com/vmware/govmomi/vapi/namespace" +) + +type activate struct { + *flags.ClientFlag +} + +func init() { + cli.Register("namespace.service.version.activate", &activate{}) +} + +func (cmd *activate) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) +} + +func (cmd *activate) Description() string { + return `Activates a vSphere Supervisor Service version. + +Examples: + govc namespace.service.version.activate my-supervisor-service 1.0.0` +} + +func (cmd *activate) Usage() string { + return "NAME VERSION" +} + +func (cmd *activate) Run(ctx context.Context, f *flag.FlagSet) error { + service := f.Arg(0) + if len(service) == 0 { + return flag.ErrHelp + } + version := f.Arg(1) + if len(version) == 0 { + return flag.ErrHelp + } + + c, err := cmd.RestClient() + if err != nil { + return err + } + + m := namespace.NewManager(c) + return m.ActivateSupervisorServiceVersion(ctx, service, version) +} diff --git a/cli/namespace/service/version/create.go b/cli/namespace/service/version/create.go new file mode 100644 index 000000000..286a1acc8 --- /dev/null +++ b/cli/namespace/service/version/create.go @@ -0,0 +1,87 @@ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 + +package version + +import ( + "context" + "encoding/base64" + "flag" + "fmt" + "os" + + "github.com/vmware/govmomi/cli" + "github.com/vmware/govmomi/cli/flags" + "github.com/vmware/govmomi/cli/namespace/service" + "github.com/vmware/govmomi/vapi/namespace" +) + +type create struct { + *flags.ClientFlag + *service.ServiceVersionFlag +} + +func init() { + cli.Register("namespace.service.version.create", &create{}) +} + +func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) + + cmd.ServiceVersionFlag = &service.ServiceVersionFlag{} + cmd.ServiceVersionFlag.Register(ctx, f) +} + +func (cmd *create) Process(ctx context.Context) error { + if err := cmd.ServiceVersionFlag.Process(ctx); err != nil { + return err + } + return cmd.ClientFlag.Process(ctx) +} + +func (cmd *create) Description() string { + return `Registers a new version for a registered vSphere Supervisor Service. + +Examples: + govc namespace.service.create my-service manifest-2.0.0.yaml` +} + +func (cmd *create) Usage() string { + return "SERVICE MANIFEST" +} + +func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { + if f.NArg() != 2 { + return flag.ErrHelp + } + + id := f.Arg(0) + manifestFile := f.Arg(1) + manifest, err := os.ReadFile(manifestFile) + if err != nil { + return fmt.Errorf("failed to read manifest file: %s", err) + } + + content := base64.StdEncoding.EncodeToString(manifest) + serviceVersion := namespace.SupervisorServiceVersion{} + if cmd.ServiceVersionFlag.SpecType == "carvel" { + serviceVersion.CarvelService = &namespace.CarvelVersionCreateSpec{ + Content: content, + } + } else { + serviceVersion.VsphereService = &namespace.SupervisorServicesVSphereVersionCreateSpec{ + Content: content, + AcceptEula: cmd.ServiceVersionFlag.AcceptEULA, + TrustedProvider: cmd.ServiceVersionFlag.TrustedProvider, + } + } + c, err := cmd.RestClient() + if err != nil { + return err + } + + m := namespace.NewManager(c) + return m.CreateSupervisorServiceVersion(ctx, id, &serviceVersion) +} diff --git a/cli/namespace/service/version/deactivate.go b/cli/namespace/service/version/deactivate.go new file mode 100644 index 000000000..e5578599a --- /dev/null +++ b/cli/namespace/service/version/deactivate.go @@ -0,0 +1,57 @@ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 + +package version + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/cli" + "github.com/vmware/govmomi/cli/flags" + "github.com/vmware/govmomi/vapi/namespace" +) + +type deactivate struct { + *flags.ClientFlag +} + +func init() { + cli.Register("namespace.service.version.deactivate", &deactivate{}) +} + +func (cmd *deactivate) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) +} + +func (cmd *deactivate) Description() string { + return `Deactivates a vSphere Supervisor Service version. + +Examples: + govc namespace.service.version.deactivate my-supervisor-service 1.0.0` +} + +func (cmd *deactivate) Usage() string { + return "NAME VERSION" +} + +func (cmd *deactivate) Run(ctx context.Context, f *flag.FlagSet) error { + service := f.Arg(0) + if len(service) == 0 { + return flag.ErrHelp + } + version := f.Arg(1) + if len(version) == 0 { + return flag.ErrHelp + } + + c, err := cmd.RestClient() + if err != nil { + return err + } + + m := namespace.NewManager(c) + return m.DeactivateSupervisorServiceVersion(ctx, service, version) +} diff --git a/cli/namespace/service/version/info.go b/cli/namespace/service/version/info.go new file mode 100644 index 000000000..e33b612f5 --- /dev/null +++ b/cli/namespace/service/version/info.go @@ -0,0 +1,104 @@ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 + +package version + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "io" + "os" + "text/tabwriter" + + "github.com/vmware/govmomi/cli" + "github.com/vmware/govmomi/cli/flags" + "github.com/vmware/govmomi/vapi/namespace" +) + +type info struct { + *flags.ClientFlag + *flags.OutputFlag +} + +func init() { + cli.Register("namespace.service.version.info", &info{}) +} + +func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.ClientFlag.Register(ctx, f) + cmd.OutputFlag.Register(ctx, f) + +} + +func (cmd *info) Process(ctx context.Context) error { + if err := cmd.ClientFlag.Process(ctx); err != nil { + return err + } + return cmd.OutputFlag.Process(ctx) +} + +func (cmd *info) Description() string { + return `Gets information of a specific vSphere Supervisor Service version. + +Examples: + govc namespace.service.version.info my-supervisor-service 2.0.0 + govc namespace.service.version.info -json my-supervisor-service 2.0.0 | jq .` +} + +type infoWriter struct { + cmd *info + Service namespace.SupervisorServiceVersionInfo `json:"service"` +} + +func (r *infoWriter) Write(w io.Writer) error { + tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) + + fmt.Fprintf(tw, "%s", r.Service.Name) + fmt.Fprintf(tw, "\t%s", r.Service.State) + fmt.Fprintf(tw, "\t%s", r.Service.Description) + + fmt.Fprintf(tw, "\n") + + return tw.Flush() +} + +func (r *infoWriter) MarshalJSON() ([]byte, error) { + return json.Marshal(r.Service) +} + +func (r *infoWriter) Dump() interface{} { + return r.Service +} + +func (cmd *info) Usage() string { + return "NAME" +} + +func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { + service := f.Arg(0) + if len(service) == 0 { + return flag.ErrHelp + } + version := f.Arg(1) + if len(version) == 0 { + return flag.ErrHelp + } + + c, err := cmd.RestClient() + if err != nil { + return err + } + + m := namespace.NewManager(c) + serviceVersion, err := m.GetSupervisorServiceVersion(ctx, service, version) + if err != nil { + return err + } + + return cmd.WriteResult(&infoWriter{cmd, serviceVersion}) +} diff --git a/cli/namespace/service/version/ls.go b/cli/namespace/service/version/ls.go new file mode 100644 index 000000000..c4a3ebd1b --- /dev/null +++ b/cli/namespace/service/version/ls.go @@ -0,0 +1,107 @@ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 + +package version + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "io" + "os" + "text/tabwriter" + + "github.com/vmware/govmomi/cli" + "github.com/vmware/govmomi/cli/flags" + "github.com/vmware/govmomi/vapi/namespace" +) + +type ls struct { + *flags.ClientFlag + *flags.OutputFlag + + long bool +} + +func init() { + cli.Register("namespace.service.version.ls", &ls{}) +} + +func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.ClientFlag.Register(ctx, f) + cmd.OutputFlag.Register(ctx, f) + + f.BoolVar(&cmd.long, "l", false, "Long listing format") +} + +func (cmd *ls) Process(ctx context.Context) error { + if err := cmd.ClientFlag.Process(ctx); err != nil { + return err + } + return cmd.OutputFlag.Process(ctx) +} + +func (cmd *ls) Description() string { + return `List all registered versions for a given vSphere Supervisor Service. + +Examples: + govc namespace.service.version.ls my-service + govc namespace.service.version.ls -l my-service + govc namespace.service.version.ls -json my-service | jq .` +} + +func (cmd *ls) Usage() string { + return "NAME" +} + +type lsWriter struct { + cmd *ls + service string + Versions []namespace.SupervisorServiceVersionSummary `json:"versions"` +} + +func (r *lsWriter) Write(w io.Writer) error { + tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) + fmt.Fprintf(tw, "%s:\n", r.service) + for _, svc := range r.Versions { + fmt.Fprintf(tw, "%s", svc.Version) + if r.cmd.long { + fmt.Fprintf(tw, "\t%s", svc.Name) + fmt.Fprintf(tw, "\t%s", svc.State) + fmt.Fprintf(tw, "\t%s", svc.Description) + } + fmt.Fprintf(tw, "\n") + } + return tw.Flush() +} + +func (r *lsWriter) MarshalJSON() ([]byte, error) { + return json.Marshal(r.Versions) +} + +func (r *lsWriter) Dump() interface{} { + return r.Versions +} + +func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { + service := f.Arg(0) + if len(service) == 0 { + return flag.ErrHelp + } + c, err := cmd.RestClient() + if err != nil { + return err + } + + m := namespace.NewManager(c) + versions, err := m.ListSupervisorServiceVersions(ctx, service) + if err != nil { + return err + } + + return cmd.WriteResult(&lsWriter{cmd, service, versions}) +} diff --git a/cli/namespace/service/version/rm.go b/cli/namespace/service/version/rm.go new file mode 100644 index 000000000..141d47913 --- /dev/null +++ b/cli/namespace/service/version/rm.go @@ -0,0 +1,57 @@ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 + +package version + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/cli" + "github.com/vmware/govmomi/cli/flags" + "github.com/vmware/govmomi/vapi/namespace" +) + +type rm struct { + *flags.ClientFlag +} + +func init() { + cli.Register("namespace.service.version.rm", &rm{}) +} + +func (cmd *rm) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) +} + +func (cmd *rm) Description() string { + return `Removes a vSphere Supervisor Service version. + +Examples: + govc namespace.service.version.rm my-supervisor-service 1.0.0` +} + +func (cmd *rm) Usage() string { + return "NAME VERSION" +} + +func (cmd *rm) Run(ctx context.Context, f *flag.FlagSet) error { + service := f.Arg(0) + if len(service) == 0 { + return flag.ErrHelp + } + version := f.Arg(1) + if len(version) == 0 { + return flag.ErrHelp + } + + c, err := cmd.RestClient() + if err != nil { + return err + } + + m := namespace.NewManager(c) + return m.RemoveSupervisorServiceVersion(ctx, service, version) +} diff --git a/govc/USAGE.md b/govc/USAGE.md index f676f260d..88079b704 100644 --- a/govc/USAGE.md +++ b/govc/USAGE.md @@ -4736,7 +4736,7 @@ Options: ``` Usage: govc namespace.service.activate [OPTIONS] NAME... -Activates a vSphere Namespace Supervisor Service. +Activates a vSphere Supervisor Service. Examples: govc namespace.service.activate my-supervisor-service other-supervisor-service @@ -4749,15 +4749,17 @@ Options: ``` Usage: govc namespace.service.create [OPTIONS] MANIFEST -Creates a vSphere Namespace Supervisor Service. +Registers a vSphere Supervisor Service version on vCenter for a new service. +A service version can be registered once on vCenter and then be installed on multiple vSphere Supervisors managed by this vCenter. +A vSphere Supervisor Service contains a list of service versions, this call will create a service and its first version. Examples: govc namespace.service.create manifest.yaml Options: - -accept-eula=false Auto accept EULA - -spec-type=vsphere Type of Spec: only vsphere is supported right now - -trusted=false Define if this is a trusted provider + -accept-eula=false Auto accept EULA (only required for vSphere spec type) + -spec-type=vsphere Type of Spec: vsphere (deprecated) or carvel + -trusted=false Define if this is a trusted provider (only applicable for vSphere spec type) ``` ## namespace.service.deactivate @@ -4765,7 +4767,7 @@ Options: ``` Usage: govc namespace.service.deactivate [OPTIONS] NAME... -Deactivates a vSphere Namespace Supervisor Service. +Deactivates a vSphere Namespace Supervisor Service. This deactivates all the versions of that service. Examples: govc namespace.service.deactivate my-supervisor-service other-supervisor-service @@ -4778,7 +4780,7 @@ Options: ``` Usage: govc namespace.service.info [OPTIONS] NAME -Gets information of a specific supervisor service. +Gets information about a specific vSphere Supervisor Service. Examples: govc namespace.service.info my-supervisor-service @@ -4792,7 +4794,7 @@ Options: ``` Usage: govc namespace.service.ls [OPTIONS] -List namepace registered supervisor services. +List all registered vSphere Supervisor Services. Examples: govc namespace.service.ls @@ -4808,7 +4810,8 @@ Options: ``` Usage: govc namespace.service.rm [OPTIONS] NAME... -Removes a vSphere Namespace Supervisor Service. +Removes a vSphere Supervisor Service. +Note that a service must be deactivated and all versions must be removed before being deleted. Examples: govc namespace.service.rm my-supervisor-service other-supervisor-service @@ -4816,6 +4819,58 @@ Examples: Options: ``` +## namespace.service.version.create + +``` +Usage: govc namespace.service.version.create [OPTIONS] NAME MANIFEST + +Registers a new version for a registered vSphere Supervisor Service. + +Examples: + govc namespace.service.create my-existing-service manifest-2.0.0.yaml + +Options: + -accept-eula=false Auto accept EULA (only required for vSphere spec type) + -spec-type=vsphere Type of Spec: vsphere (deprecated) or carvel + -trusted=false Define if this is a trusted provider (only applicable for vSphere spec type) +``` + +## namespace.service.version.info + +``` +Usage: govc namespace.service.version.info [OPTIONS] NAME VERSION + +Gets information about a specific vSphere Supervisor Service version. + +Examples: + govc namespace.service.version.info my-supervisor-service 2.0.0. +Options: +``` + +## namespace.service.version.list + +``` +Usage: govc namespace.service.version.list [OPTIONS] NAME + +List all registered versions for a given vSphere Supervisor Service. + +Examples: + govc namespace.service.version.list my-supervisor-service +Options: +``` +## namespace.service.version.rm + +``` +Usage: govc namespace.service.version.rm [OPTIONS] NAME VERSION + +Removes a vSphere Supervisor Service version. +Note that a service version must be deactivated before being deleted. + +Examples: + govc namespace.service.version.rm my-supervisor-service 1.0.0 + +Options: +``` ## namespace.update ``` diff --git a/govc/main.go b/govc/main.go index 95840de76..33b334e45 100644 --- a/govc/main.go +++ b/govc/main.go @@ -87,6 +87,7 @@ import ( _ "github.com/vmware/govmomi/cli/namespace" _ "github.com/vmware/govmomi/cli/namespace/cluster" _ "github.com/vmware/govmomi/cli/namespace/service" + _ "github.com/vmware/govmomi/cli/namespace/service/version" _ "github.com/vmware/govmomi/cli/namespace/vmclass" _ "github.com/vmware/govmomi/cli/object" _ "github.com/vmware/govmomi/cli/option" diff --git a/govc/test/namespace.bats b/govc/test/namespace.bats index 09a4c4194..304051f4c 100755 --- a/govc/test/namespace.bats +++ b/govc/test/namespace.bats @@ -99,6 +99,16 @@ load test_helper assert_success assert_matches ACTIVATED assert_matches mock-service-1 + assert_matches mock-service-2 + assert_matches DEACTIVATED +} + +@test "namespace.service.info notfound" { + vcsim_env + + run govc namespace.service.info non-existing-service + assert_failure + assert_matches "404 Not Found" } @test "namespace.service.info" { @@ -108,10 +118,40 @@ load test_helper assert_success assert_matches mock-service-1 assert_matches ACTIVATED - assert_matches "Description of service1" run govc namespace.service.info -json service2 - assert_matches DE-ACTIVATED + assert_matches DEACTIVATED +} + +@test "namespace.service.version.ls" { + vcsim_env + + versions=$(govc namespace.service.version.ls -json service1) + assert_equal "2" $(echo $versions | jq '. | length') + + run govc namespace.service.version.ls service1 + assert_success + assert_matches "1.0.0" + assert_matches "2.0.0" +} + +@test "namespace.service.version.info notfound" { + vcsim_env + + run govc namespace.service.version.info service2 9.9.9 + assert_failure + assert_matches "404 Not Found" +} + +@test "namespace.service.version.info" { + vcsim_env + + v=$(govc namespace.service.version.info -json service2 1.1.0 | jq) + + assert_equal "ACTIVATED" $(echo $v | jq -r .state) + assert_equal "This is service 2 version 1.1.0" "$(echo $v | jq -r .description)" + assert_equal "CARVEL_APPS_YAML" $(echo $v | jq -r .content_type) + assert_equal "abc" $(echo $v | jq -r .content) } @test "namespace.create" { @@ -335,3 +375,5 @@ load test_helper run govc namespace.registervm -vm $vm test-namespace-1 assert_success } + + diff --git a/vapi/namespace/internal/internal.go b/vapi/namespace/internal/internal.go index 103caeaef..739423f7d 100644 --- a/vapi/namespace/internal/internal.go +++ b/vapi/namespace/internal/internal.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2020-2024 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package internal @@ -22,6 +10,7 @@ const ( NamespaceDistributedSwitchCompatibility = "/api/vcenter/namespace-management/distributed-switch-compatibility" NamespaceEdgeClusterCompatibility = "/api/vcenter/namespace-management/edge-cluster-compatibility" SupervisorServicesPath = "/api/vcenter/namespace-management/supervisor-services" + SupervisorServicesVersionsPath = "/versions" NamespacesPath = "/api/vcenter/namespaces/instances" VmClassesPath = "/api/vcenter/namespace-management/virtual-machine-classes" diff --git a/vapi/namespace/simulator/simulator.go b/vapi/namespace/simulator/simulator.go index a4ddac8a2..5664996c0 100644 --- a/vapi/namespace/simulator/simulator.go +++ b/vapi/namespace/simulator/simulator.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2020-2024 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package simulator @@ -48,7 +36,7 @@ func init() { }) } -// Handler implements the Cluster Modules API simulator +// Handler implements the Namespace Management Modules API simulator type Handler struct { URL *url.URL } @@ -72,6 +60,8 @@ func (h *Handler) Register(s *simulator.Service, r *simulator.Registry) { s.HandleFunc(internal.SupervisorServicesPath, h.listServices) s.HandleFunc(internal.SupervisorServicesPath+"/", h.getService) + s.HandleFunc(internal.SupervisorServicesPath+"/{id}"+internal.SupervisorServicesVersionsPath, h.versionsForService) + s.HandleFunc(internal.SupervisorServicesPath+"/{id}"+internal.SupervisorServicesVersionsPath+"/{version}", h.getServiceVersion) s.HandleFunc(internal.VmClassesPath, h.vmClasses) s.HandleFunc(internal.VmClassesPath+"/", h.vmClasses) @@ -209,22 +199,61 @@ func (h *Handler) listCompatibleEdgeClusters(w http.ResponseWriter, r *http.Requ } } -var supervisorServices []namespace.SupervisorServiceSummary = []namespace.SupervisorServiceSummary{ - { +// Some fake services, service 1 has 2 versions, service 2 has 1 version +// Summary for services +var supervisorServicesMap = map[string]namespace.SupervisorServiceSummary{ + "service1": { ID: "service1", Name: "mock-service-1", State: "ACTIVATED", }, - { + "service2": { ID: "service2", Name: "mock-service-2", - State: "DE-ACTIVATED", + State: "DEACTIVATED", + }, +} + +// Summary for service versions +var supervisorServiceVersionsMap = map[string][]namespace.SupervisorServiceVersionSummary{ + "service1": { + { + SupervisorServiceInfo: namespace.SupervisorServiceInfo{ + Name: "mock-service-1 v1 display name", + State: "ACTIVATED", + Description: "This is service 1 version 1.0.0", + }, + Version: "1.0.0", + }, + { + SupervisorServiceInfo: namespace.SupervisorServiceInfo{ + Name: "mock-service-1 v2 display name", + State: "DEACTIVATED", + Description: "This is service 1 version 2.0.0", + }, + Version: "2.0.0", + }}, + "service2": { + { + SupervisorServiceInfo: namespace.SupervisorServiceInfo{ + Name: "mock-service-2 v1 display name", + State: "ACTIVATED", + Description: "This is service 2 version 1.1.0", + }, + Version: "1.1.0", + }, }, } func (h *Handler) listServices(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: + supervisorServices := make([]namespace.SupervisorServiceSummary, len(supervisorServicesMap)) + i := 0 + for _, service := range supervisorServicesMap { + supervisorServices[i] = service + i++ + } vapi.StatusOK(w, supervisorServices) } } @@ -233,18 +262,58 @@ func (h *Handler) getService(w http.ResponseWriter, r *http.Request) { id := path.Base(r.URL.Path) switch r.Method { case http.MethodGet: - for _, svc := range supervisorServices { - if svc.ID == id { - svcInfo := namespace.SupervisorServiceInfo{ - Name: svc.Name, - State: svc.State, - Description: fmt.Sprintf("Description of %s", svc.ID), + if result, contains := supervisorServicesMap[id]; contains { + vapi.StatusOK(w, result) + } else { + vapi.ApiErrorNotFound(w) + } + return + } +} + +// versionsForService returns the list of versions for a particular service +func (h *Handler) versionsForService(w http.ResponseWriter, r *http.Request) { + fmt.Printf("In versionsForService: %v\n", r.URL.Path) + id := r.PathValue("id") + switch r.Method { + case http.MethodGet: + if result, contains := supervisorServiceVersionsMap[id]; contains { + vapi.StatusOK(w, result) + } else { + vapi.ApiErrorNotFound(w) + } + return + } +} + +// getServiceVersion returns info on a particular service version +func (h *Handler) getServiceVersion(w http.ResponseWriter, r *http.Request) { + id := r.PathValue("id") + version := r.PathValue("version") + + switch r.Method { + case http.MethodGet: + if versions, contains := supervisorServiceVersionsMap[id]; contains { + for _, v := range versions { + if v.Version == version { + info := namespace.SupervisorServiceVersionInfo{ + SupervisorServiceInfo: namespace.SupervisorServiceInfo{ + Description: v.Description, + State: v.State, + Name: v.Name, + }, + ContentType: "CARVEL_APPS_YAML", // return Carvel by default + Content: "abc", // in reality this is base 64 encoded of content + } + vapi.StatusOK(w, info) + return } - vapi.StatusOK(w, svcInfo) - return } + vapi.ApiErrorNotFound(w) + } else { + vapi.ApiErrorNotFound(w) } - w.WriteHeader(http.StatusNotFound) + return } } diff --git a/vapi/namespace/supervisorsvc.go b/vapi/namespace/supervisorsvc.go index 2292647a3..ce7fa912c 100644 --- a/vapi/namespace/supervisorsvc.go +++ b/vapi/namespace/supervisorsvc.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2021 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package namespace @@ -33,14 +21,43 @@ type SupervisorServiceSummary struct { // SupervisorServiceInfo for a supervisor service existent in vSphere. type SupervisorServiceInfo struct { - Name string `json:"display_name"` - State string `json:"state"` - Description string `json:"description"` + Name string `json:"display_name"` + State string `json:"state"` + Description string `json:"description"` + MustBeInstalled bool `json:"must_be_installed"` + HasDefaultVersionsRegistered bool `json:"has_default_versions_registered"` +} + +// SupervisorServiceVersionSummary describes a vSphere Supervisor Service version. +type SupervisorServiceVersionSummary struct { + SupervisorServiceInfo + Version string `json:"version"` +} + +// SupervisorServiceVersionInfo details a vSphere Supervisor Service version. +type SupervisorServiceVersionInfo struct { + SupervisorServiceInfo + Eula string `json:"EULA"` + Content string `json:"content"` + ContentType string `json:"content_type"` + TrustVerified bool `json:"trust_verified"` + RegisteredByDefault bool `json:"registered_by_default"` } // SupervisorService defines a new SupervisorService specification type SupervisorService struct { - VsphereService SupervisorServicesVSphereSpec `json:"vsphere_spec,omitempty"` + // The specification required to create a Supervisor Service with a version from inline content that is based on the vSphere application service format. + VsphereService *SupervisorServicesVSphereSpec `json:"vsphere_spec,omitempty"` + // The specification required to create a Supervisor Service with a version from inline content that is based on the Carvel application package format. + CarvelService *SupervisorServicesCarvelSpec `json:"carvel_spec,omitempty"` +} + +// SupervisorServiceVersion defines a new SupervisorService version specification +type SupervisorServiceVersion struct { + // The specification required to create a Supervisor Service with a version from inline content that is based on the vSphere application service format. + VsphereService *SupervisorServicesVSphereVersionCreateSpec `json:"vsphere_spec,omitempty"` + // The specification required to create a Supervisor Service with a version from inline content that is based on the Carvel application package format. + CarvelService *CarvelVersionCreateSpec `json:"carvel_spec,omitempty"` } // SupervisorServicesVSphereSpec defines a new SupervisorService specification of vSphere type @@ -55,20 +72,32 @@ type SupervisorServicesVSphereVersionCreateSpec struct { AcceptEula bool `json:"accept_EULA,omitempty"` } -// CreateSupervisorService creates a new Supervisor Service on vSphere Namespaces endpoint. +// The “SupervisorServicesCarvelSpec“ class provides a specification required to create a Supervisor Service with a version from Carvel application package format (Package and PackageMetadata resources should be declared). +type SupervisorServicesCarvelSpec struct { + // Supervisor service version specification that provides the service definitions for one Supervisor Service version. + VersionSpec CarvelVersionCreateSpec `json:"version_spec"` +} + +// The “CarvelVersionCreateSpec“ class provides a specification required to create a Supervisor Service version from Carvel application package format (Package and PackageMetadata resources should be declared). +type CarvelVersionCreateSpec struct { + // Inline content that contains all service definition of the version in Carvel application package format, which shall be base64 encoded. + Content string `json:"content"` +} + +// CreateSupervisorService creates a new Supervisor Service on vCenter. func (c *Manager) CreateSupervisorService(ctx context.Context, service *SupervisorService) error { url := c.Resource(internal.SupervisorServicesPath) return c.Do(ctx, url.Request(http.MethodPost, service), nil) } -// ListSupervisorServices returns a summary of all clusters with vSphere Namespaces enabled. +// ListSupervisorServices returns a summary of registered Supervisor Services. func (c *Manager) ListSupervisorServices(ctx context.Context) ([]SupervisorServiceSummary, error) { var res []SupervisorServiceSummary url := c.Resource(internal.SupervisorServicesPath) return res, c.Do(ctx, url.Request(http.MethodGet), &res) } -// GetSupervisorService gets the information of a specific supervisor service. +// GetSupervisorService gets the information of a specific Supervisor Service. func (c *Manager) GetSupervisorService(ctx context.Context, id string) (SupervisorServiceInfo, error) { var res SupervisorServiceInfo url := c.Resource(path.Join(internal.SupervisorServicesPath, id)) @@ -78,20 +107,63 @@ func (c *Manager) GetSupervisorService(ctx context.Context, id string) (Supervis // ActivateSupervisorServices activates a previously registered Supervisor Service. func (c *Manager) ActivateSupervisorServices(ctx context.Context, id string) error { url := c.Resource(path.Join(internal.SupervisorServicesPath, id)).WithParam("action", "activate") - err := c.Do(ctx, url.Request(http.MethodPatch, nil), nil) - return err + return c.Do(ctx, url.Request(http.MethodPatch, nil), nil) } // DeactivateSupervisorServices deactivates a previously registered Supervisor Service. func (c *Manager) DeactivateSupervisorServices(ctx context.Context, id string) error { url := c.Resource(path.Join(internal.SupervisorServicesPath, id)).WithParam("action", "deactivate") - err := c.Do(ctx, url.Request(http.MethodPatch, nil), nil) - return err + return c.Do(ctx, url.Request(http.MethodPatch, nil), nil) } -// RemoveSupervisorService removes a previously deactivated supervisor service. +// RemoveSupervisorService removes a previously deactivated Supervisor Service. func (c *Manager) RemoveSupervisorService(ctx context.Context, id string) error { url := c.Resource(path.Join(internal.SupervisorServicesPath, id)) err := c.Do(ctx, url.Request(http.MethodDelete, nil), nil) return err } + +// ListSupervisorServiceVersions lists all versions of the given Supervisor Service. +// https://developer.broadcom.com/xapis/vsphere-automation-api/8.0.3/vcenter/api/vcenter/namespace-management/supervisor-services/supervisor_service/versions/get/ +func (c *Manager) ListSupervisorServiceVersions(ctx context.Context, id string) ([]SupervisorServiceVersionSummary, error) { + var res []SupervisorServiceVersionSummary + url := c.Resource(path.Join(internal.SupervisorServicesPath, id, internal.SupervisorServicesVersionsPath)) + return res, c.Do(ctx, url.Request(http.MethodGet), &res) +} + +// RemoveSupervisorServiceVersion removes a previously deactivated Supervisor Service version. +// https://developer.broadcom.com/xapis/vsphere-automation-api/8.0.3/vcenter/api/vcenter/namespace-management/supervisor-services/supervisor_service/versions/version/delete/ +func (c *Manager) RemoveSupervisorServiceVersion(ctx context.Context, id string, version string) error { + url := c.Resource(path.Join(internal.SupervisorServicesPath, id, internal.SupervisorServicesVersionsPath, version)) + err := c.Do(ctx, url.Request(http.MethodDelete, nil), nil) + return err +} + +// CreateSupervisorServiceVersion creates a new version for an existing Supervisor Service. +// https://developer.broadcom.com/xapis/vsphere-automation-api/8.0.3/vcenter/api/vcenter/namespace-management/supervisor-services/supervisor_service/versions/post/ +func (c *Manager) CreateSupervisorServiceVersion(ctx context.Context, id string, service *SupervisorServiceVersion) error { + url := c.Resource(path.Join(internal.SupervisorServicesPath, id, internal.SupervisorServicesVersionsPath)) + return c.Do(ctx, url.Request(http.MethodPost, service), nil) +} + +// DeactivateSupervisorServiceVersion deactivates a version of an existing Supervisor Service. +// https://developer.broadcom.com/xapis/vsphere-automation-api/8.0.3/vcenter/api/vcenter/namespace-management/supervisor-services/supervisor_service/versions/versionactiondeactivate/patch/ +func (c *Manager) DeactivateSupervisorServiceVersion(ctx context.Context, id string, version string) error { + url := c.Resource(path.Join(internal.SupervisorServicesPath, id, internal.SupervisorServicesVersionsPath, version)).WithParam("action", "deactivate") + return c.Do(ctx, url.Request(http.MethodPatch, nil), nil) +} + +// ActivateSupervisorServiceVersion activates a version of an existing Supervisor Service. +// https://developer.broadcom.com/xapis/vsphere-automation-api/8.0.3/vcenter/api/vcenter/namespace-management/supervisor-services/supervisor_service/versions/versionactiondeactivate/patch/ +func (c *Manager) ActivateSupervisorServiceVersion(ctx context.Context, id string, version string) error { + url := c.Resource(path.Join(internal.SupervisorServicesPath, id, internal.SupervisorServicesVersionsPath, version)).WithParam("action", "activate") + return c.Do(ctx, url.Request(http.MethodPatch, nil), nil) +} + +// GetSupervisorServiceVersion gets the information of a specific Supervisor Service version. +// https://developer.broadcom.com/xapis/vsphere-automation-api/8.0.3/vcenter/api/vcenter/namespace-management/supervisor-services/supervisor_service/versions/version/get/ +func (c *Manager) GetSupervisorServiceVersion(ctx context.Context, id string, version string) (SupervisorServiceVersionInfo, error) { + var res SupervisorServiceVersionInfo + url := c.Resource(path.Join(internal.SupervisorServicesPath, id, internal.SupervisorServicesVersionsPath, version)) + return res, c.Do(ctx, url.Request(http.MethodGet, nil), &res) +} diff --git a/vapi/simulator/simulator.go b/vapi/simulator/simulator.go index b6f95a0bd..a98a8b01d 100644 --- a/vapi/simulator/simulator.go +++ b/vapi/simulator/simulator.go @@ -1,18 +1,6 @@ -/* -Copyright (c) 2018-2024 VMware, Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// © Broadcom. All Rights Reserved. +// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +// SPDX-License-Identifier: Apache-2.0 package simulator @@ -503,8 +491,8 @@ func (s *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - h, _ := s.ServeMux.Handler(r) - h.ServeHTTP(w, r) + // Use ServeHTTP directly and not via handler otherwise the path values like "{id}" are not set + s.ServeMux.ServeHTTP(w, r) } func (s *handler) decode(r *http.Request, w http.ResponseWriter, val interface{}) bool {