import ( "github.com/cloudfoundry/cli/cf/terminal" "github.com/cloudfoundry/cli/plugin" "github.com/cloudfoundry/cli/plugin/models" "github.com/cloudfoundry/cli/cf/command_registry" "github.com/cloudfoundry/cli/cf/errors" "github.com/cloudfoundry/cli/cf/i18n" "github.com/cloudfoundry/cli/cf/flags" "github.com/cloudfoundry/cli/cf/requirements" "github.com/cloudfoundry/cli/cf/commands" . "github.com/cloudfoundry/cli/cf/i18n" "strings" "time" ) func NewMinAPIVersionRequirement(version string) requirements.Requirement { return &MinAPIVersionRequirement{ version: version, ui: terminal.NewUI(i18n.GetLanguage()), timeGetter: time.Now, } } type MinAPIVersionRequirement struct { version string ui terminal.UI timeGetter func() time.Time } func (r *MinAPIVersionRequirement) Execute() error { apiVersion, err := readAPIVersion(strings.NewReader(r.version)) if err != nil { return err } target, err := command_registry.Commands.FindCommandTarget(nil, flags.NewFlagContext(nil), false) if err != nil { return err } client, err := plugin.NewPluginConfig(r.ui, target.GUID, target.SpaceGUID).GetPluginConfig() if err != nil { return err } var apiErr errors.Error var supported bool for retryCount := 0; retryCount < 5; retryCount++ { apiErr = client.ApiVersionGreaterThan(apiVersion) if errors.IsAPIError(apiErr) { break } if !errors.IsTimeoutError(apiErr) { if errors.IsOfflineError(apiErr) { apiErr = translatableErr{cf.TranslatableError{ MessageTmpl: T("API endpoint {{.APIEndpoint}} not reachable\n", map[string]interface{}{ "APIEndpoint": client.ApiEndpoint(), }), }} } break } r.ui.Say(T("Waiting for the {{.APIVersion}} API to come up...{{.WaitDuration}}", map[string]interface{}{ "APIVersion": r.version, "WaitDuration": time.Duration((retryCount+1)*15) * time.Second, })) time.Sleep(time.Duration((retryCount+1)*15) * time.Second) } if errors.IsTimeoutError(apiErr) { apiErr = translatableErr{cf.TranslatableError{Message: string(api.ConnectionTimeout)}} } if apiErr != nil { apiStatusErr, ok := apiErr.(errors.APINotFoundError) if !ok { return apiErr } apiVers := strings.TrimSpace(apiStatusErr.Message) vers, err := readAPIVersions(strings.NewReader(apiVers)) if err != nil { return err } for _, v := range vers { if !v.IsLegacy() && v.LessThan(apiVersion) { continue } supported = true } if !supported { supportedVersions := []string{} for _, v := range vers { if !v.IsLegacy() { supportedVersions = append(supportedVersions, v.String()) } } return errors.NewUnsupportedError( apiStatusErr.ErrorCode, apiStatusErr.Description, apiStatusErr.Request, apiStatusErr.Response, fmt.Sprintf("Please use API version >= %s. Your current target API version is `%s`. Supported APIs: %s", r.version, apiVersion.String(), strings.Join(supportedVersions, ", ")), ) } } return nil }This code shows an implementation of the `NewMinAPIVersionRequirement` function and the `MinAPIVersionRequirement` struct, which both reside in the `github.com.cloudfoundry.cli.cf.requirements` package library. The `MinAPIVersionRequirement` struct checks if the targeted org/space has an API version equal to or greater than the minimum required version. If it does not, an error will be returned. This requirement can be used for validating that an API version is compatible with a command, plugin, or other CF-related functionality.