From 7850bbee3438e06a4fd5351442e7bd26bb287e00 Mon Sep 17 00:00:00 2001 From: Tamal Saha Date: Sat, 24 Feb 2024 15:52:34 -0800 Subject: [PATCH] Organize codebase Signed-off-by: Tamal Saha --- .github/.kodiak.toml | 18 + .github/workflows/ci-docs-only.yaml | 40 - .github/workflows/ci.yaml | 64 - .github/workflows/ci.yml | 39 + .github/workflows/goreleaser.yml | 39 - .github/workflows/image.yaml | 63 - .github/workflows/release-tracker.yml | 41 + .github/workflows/release.yml | 86 + .gitignore | 3 +- .goreleaser.yaml | 43 - .ko.yaml | 12 - CONTRIBUTING.md | 98 - Dockerfile.dbg | 34 + Dockerfile => Dockerfile.in | 18 +- GOVERNANCE.md | 139 - LICENSE | 201 - LICENSE.md | 5 + Makefile | 703 +- OWNERS | 6 - README.md | 30 +- SECURITY.md | 3 - .../v1alpha1/apiservicebinding_types.go | 13 +- .../v1alpha1/apiserviceexport_types.go | 15 +- .../v1alpha1/apiserviceexportrequest_types.go | 15 +- .../v1alpha1/apiservicenamespace_types.go | 15 +- .../v1alpha1/bindingprovider_types.go | 6 +- .../v1alpha1/bindingresponse_types.go | 6 +- .../kubebind/v1alpha1/clusterbinding_types.go | 15 +- apis/kubebind/v1alpha1/crds.go | 43 + {pkg/apis => apis}/kubebind/v1alpha1/doc.go | 6 +- .../kubebind/v1alpha1/helpers/crd.go | 12 +- .../v1alpha1/helpers/serviceexport.go | 10 +- .../v1alpha1/helpers/serviceexport_test.go | 10 +- .../kubebind/v1alpha1/register.go | 14 +- .../v1alpha1/zz_generated.deepcopy.go | 9 +- .../clientset/versioned/clientset.go | 10 +- .../versioned/fake/clientset_generated.go | 14 +- client/clientset/versioned/fake/doc.go | 20 + .../clientset/versioned/fake/register.go | 10 +- .../clientset/versioned/scheme/doc.go | 6 +- .../clientset/versioned/scheme/register.go | 10 +- .../kubebind/v1alpha1/apiservicebinding.go | 12 +- .../kubebind/v1alpha1/apiserviceexport.go | 12 +- .../v1alpha1/apiserviceexportrequest.go | 12 +- .../kubebind/v1alpha1/apiservicenamespace.go | 12 +- .../typed/kubebind/v1alpha1/clusterbinding.go | 12 +- .../versioned/typed/kubebind/v1alpha1/doc.go | 20 + .../typed/kubebind/v1alpha1/fake/doc.go | 20 + .../v1alpha1/fake/fake_apiservicebinding.go | 10 +- .../v1alpha1/fake/fake_apiserviceexport.go | 10 +- .../fake/fake_apiserviceexportrequest.go | 10 +- .../v1alpha1/fake/fake_apiservicenamespace.go | 10 +- .../v1alpha1/fake/fake_clusterbinding.go | 10 +- .../v1alpha1/fake/fake_kubebind_client.go | 10 +- .../kubebind/v1alpha1/generated_expansion.go | 6 +- .../kubebind/v1alpha1/kubebind_client.go | 12 +- .../informers/externalversions/factory.go | 14 +- .../informers/externalversions/generic.go | 10 +- .../internalinterfaces/factory_interfaces.go | 10 +- .../externalversions/kubebind/interface.go | 10 +- .../kubebind/v1alpha1/apiservicebinding.go | 16 +- .../kubebind/v1alpha1/apiserviceexport.go | 16 +- .../v1alpha1/apiserviceexportrequest.go | 16 +- .../kubebind/v1alpha1/apiservicenamespace.go | 16 +- .../kubebind/v1alpha1/clusterbinding.go | 16 +- .../kubebind/v1alpha1/interface.go | 8 +- .../kubebind/v1alpha1/apiservicebinding.go | 10 +- .../kubebind/v1alpha1/apiserviceexport.go | 10 +- .../v1alpha1/apiserviceexportrequest.go | 10 +- .../kubebind/v1alpha1/apiservicenamespace.go | 10 +- .../kubebind/v1alpha1/clusterbinding.go | 10 +- .../kubebind/v1alpha1/expansion_generated.go | 6 +- cmd/example-backend/main.go | 13 +- cmd/konnector/cmd/konnector.go | 15 +- cmd/konnector/cmd/leaderelection.go | 6 +- cmd/konnector/main.go | 10 +- cmd/kubectl-connect/main.go | 19 +- code-of-conduct.md | 75 - contrib/example-backend/config.go | 14 +- .../clusterbinding_controller.go | 32 +- .../clusterbinding_reconcile.go | 43 +- .../serviceexport/serviceexport_controller.go | 26 +- .../serviceexport/serviceexport_reconcile.go | 17 +- .../serviceexportrequest_controller.go | 38 +- .../serviceexportrequest_reconcile.go | 47 +- .../servicenamespace_controller.go | 36 +- .../servicenamespace_reconcile.go | 22 +- contrib/example-backend/cookie/cookie.go | 6 +- contrib/example-backend/cookie/session.go | 6 +- contrib/example-backend/deploy/bootstrap.go | 10 +- contrib/example-backend/http/handler.go | 59 +- contrib/example-backend/http/oidc.go | 6 +- contrib/example-backend/http/server.go | 10 +- .../example-backend/kubernetes/indexers.go | 10 +- contrib/example-backend/kubernetes/manager.go | 18 +- .../kubernetes/resources/cluster_binding.go | 18 +- .../kubernetes/resources/kubeconfig.go | 8 +- .../kubernetes/resources/namespace.go | 6 +- .../kubernetes/resources/rbac.go | 6 +- .../kubernetes/resources/resources.go | 8 +- .../kubernetes/resources/secret.go | 6 +- contrib/example-backend/options/cookie.go | 6 +- contrib/example-backend/options/oidc.go | 6 +- contrib/example-backend/options/options.go | 29 +- contrib/example-backend/options/serve.go | 6 +- contrib/example-backend/server.go | 26 +- contrib/example-backend/template/files.go | 6 +- ...-bind.appscode.com_apiservicebindings.yaml | 3 +- ...appscode.com_apiserviceexportrequests.yaml | 4 +- ...e-bind.appscode.com_apiserviceexports.yaml | 3 +- ...ind.appscode.com_apiservicenamespaces.yaml | 3 +- ...ube-bind.appscode.com_clusterbindings.yaml | 3 +- crds/lib.go | 60 + deploy/crd/bootstrap.go | 181 - deploy/examples/crd-mangodb.yaml | 41 - deploy/examples/crd-tangodb.yaml | 41 - deploy/examples/servicenamespace-example.yaml | 5 - deploy/konnector/bootstrap.go | 10 +- ...de.com_apiserviceexportrequests.yaml-patch | 3 - go.mod | 13 +- go.sum | 36 +- hack/boilerplate/boilerplate.Dockerfile.txt | 14 - hack/boilerplate/boilerplate.Makefile.txt | 14 - hack/boilerplate/boilerplate.py.txt | 14 - hack/build.sh | 80 + hack/dex-config-dev.yaml | 149 - hack/e2e.sh | 44 + hack/fmt.sh | 62 + hack/go-install.sh | 62 - hack/import_hacks.go | 25 + hack/krew/plugin.yaml | 71 + hack/lib.sh | 434 - .../boilerplate.sh.txt => license/bash.txt} | 7 +- hack/license/dockerfile.txt | 1 + .../sets/doc.go => hack/license/go.txt | 10 +- hack/license/makefile.txt | 1 + hack/scripts/update-release-tracker.sh | 86 + hack/test.sh | 41 + hack/update-codegen-clients.sh | 35 - hack/update-codegen.sh | 46 - hack/verify-codegen-clients.sh | 35 - hack/verify-go-versions.sh | 28 - hack/verify-imports.sh | 35 - pkg/bootstrap/bootstrap.go | 12 +- pkg/committer/committer.go | 7 +- pkg/indexers/crd.go | 20 +- pkg/indexers/servicebinding.go | 8 +- pkg/indexers/serviceexport.go | 8 +- pkg/indexers/serviceexportrequest.go | 8 +- pkg/indexers/servicenamespace.go | 8 +- pkg/indexers/util.go | 8 +- pkg/konnector/config.go | 14 +- .../controllers/cluster/cluster_controller.go | 33 +- .../clusterbinding_controller.go | 51 +- .../clusterbinding_reconcile.go | 17 +- .../namespacedeletion_controller.go | 16 +- .../servicebinding_controller.go | 47 +- .../servicebinding_reconcile.go | 65 +- .../servicebinding_reconcile_test.go | 33 +- .../serviceexport/cluster-scoped/utils.go | 6 +- .../cluster-scoped/utils_test.go | 7 +- .../serviceexport/multinsinformer/informer.go | 16 +- .../serviceexport/serviceexport_controller.go | 38 +- .../serviceexport/serviceexport_reconcile.go | 47 +- .../serviceexport_reconcile_test.go | 13 +- .../serviceexport/spec/spec_controller.go | 18 +- .../serviceexport/spec/spec_reconcile.go | 24 +- .../serviceexport/status/status_controller.go | 27 +- .../serviceexport/status/status_reconcile.go | 12 +- .../controllers/dynamic/eventhandler.go | 6 +- .../servicebinding_controller.go | 26 +- .../servicebinding_reconcile.go | 13 +- pkg/konnector/konnector_controller.go | 35 +- pkg/konnector/konnector_reconcile.go | 12 +- pkg/konnector/models/helper.go | 16 + pkg/konnector/models/provider.go | 28 +- pkg/konnector/options/options.go | 7 +- pkg/konnector/server.go | 20 +- pkg/kubectl/base/kubeconfig.go | 8 +- pkg/kubectl/base/options.go | 7 +- pkg/kubectl/bind-apiservice/cmd/cmd.go | 15 +- pkg/kubectl/bind-apiservice/plugin/bind.go | 21 +- .../bind-apiservice/plugin/konnector.go | 17 +- pkg/kubectl/bind-apiservice/plugin/secret.go | 10 +- .../bind-apiservice/plugin/servicebindings.go | 33 +- .../plugin/serviceexportrequest.go | 28 +- .../bind/authenticator/authenticator.go | 10 +- pkg/kubectl/bind/cmd/cmd.go | 17 +- pkg/kubectl/bind/plugin/authenticate.go | 13 +- pkg/kubectl/bind/plugin/authenticate_test.go | 6 +- pkg/kubectl/bind/plugin/bind.go | 31 +- pkg/kubectl/bind/plugin/flags.go | 6 +- pkg/kubectl/bind/plugin/flags_test.go | 7 +- pkg/version/version.go | 6 +- pkg/version/version_test.go | 6 +- test/e2e/bind/fixtures/provider/bootstrap.go | 11 +- test/e2e/bind/happy-case_test.go | 17 +- test/e2e/framework/backend.go | 30 +- test/e2e/framework/bind.go | 13 +- test/e2e/framework/browser.go | 7 +- test/e2e/framework/clients.go | 7 +- test/e2e/framework/env.go | 10 +- test/e2e/framework/kcp.go | 11 +- test/e2e/framework/konnector.go | 26 +- test/e2e/framework/kubeconfig.go | 7 +- test/e2e/framework/logs.go | 7 +- vendor/github.com/gobuffalo/flect/.gitignore | 29 - .../gobuffalo/flect/.gometalinter.json | 3 - vendor/github.com/gobuffalo/flect/LICENSE | 21 - vendor/github.com/gobuffalo/flect/Makefile | 61 - vendor/github.com/gobuffalo/flect/README.md | 36 - .../github.com/gobuffalo/flect/SHOULDERS.md | 10 - vendor/github.com/gobuffalo/flect/acronyms.go | 152 - vendor/github.com/gobuffalo/flect/camelize.go | 44 - .../github.com/gobuffalo/flect/capitalize.go | 24 - .../github.com/gobuffalo/flect/custom_data.go | 83 - .../github.com/gobuffalo/flect/dasherize.go | 34 - vendor/github.com/gobuffalo/flect/flect.go | 43 - vendor/github.com/gobuffalo/flect/humanize.go | 35 - vendor/github.com/gobuffalo/flect/ident.go | 122 - .../github.com/gobuffalo/flect/lower_upper.go | 13 - .../github.com/gobuffalo/flect/ordinalize.go | 43 - .../github.com/gobuffalo/flect/pascalize.go | 32 - .../gobuffalo/flect/plural_rules.go | 287 - .../github.com/gobuffalo/flect/pluralize.go | 59 - vendor/github.com/gobuffalo/flect/rule.go | 10 - .../gobuffalo/flect/singular_rules.go | 23 - .../github.com/gobuffalo/flect/singularize.go | 57 - vendor/github.com/gobuffalo/flect/titleize.go | 30 - .../github.com/gobuffalo/flect/underscore.go | 35 - vendor/github.com/gobuffalo/flect/version.go | 4 - vendor/github.com/gorilla/mux/.editorconfig | 20 + vendor/github.com/gorilla/mux/.gitignore | 1 + vendor/github.com/gorilla/mux/AUTHORS | 8 - vendor/github.com/gorilla/mux/LICENSE | 2 +- vendor/github.com/gorilla/mux/Makefile | 34 + vendor/github.com/gorilla/mux/README.md | 61 +- vendor/github.com/gorilla/mux/doc.go | 25 +- vendor/github.com/gorilla/mux/mux.go | 16 +- vendor/github.com/gorilla/mux/regexp.go | 10 +- vendor/github.com/gorilla/mux/route.go | 109 +- .../vmihailenco/msgpack/v4/decode_value.go | 6 + .../vmihailenco/msgpack/v4/encode.go | 11 +- .../github.com/vmihailenco/msgpack/v4/time.go | 6 + vendor/golang.org/x/exp/maps/maps.go | 94 + vendor/golang.org/x/mod/LICENSE | 27 - vendor/golang.org/x/mod/PATENTS | 22 - .../x/mod/internal/lazyregexp/lazyre.go | 78 - vendor/golang.org/x/mod/module/module.go | 841 -- vendor/golang.org/x/mod/module/pseudo.go | 250 - vendor/golang.org/x/mod/semver/semver.go | 401 - vendor/golang.org/x/tools/LICENSE | 27 - vendor/golang.org/x/tools/PATENTS | 22 - .../x/tools/go/ast/astutil/enclosing.go | 634 - .../x/tools/go/ast/astutil/imports.go | 485 - .../x/tools/go/ast/astutil/rewrite.go | 486 - .../golang.org/x/tools/go/ast/astutil/util.go | 18 - .../x/tools/go/gcexportdata/gcexportdata.go | 186 - .../x/tools/go/gcexportdata/importer.go | 75 - .../tools/go/internal/packagesdriver/sizes.go | 53 - vendor/golang.org/x/tools/go/packages/doc.go | 240 - .../x/tools/go/packages/external.go | 101 - .../golang.org/x/tools/go/packages/golist.go | 1107 -- .../x/tools/go/packages/golist_overlay.go | 83 - .../x/tools/go/packages/loadmode_string.go | 57 - .../x/tools/go/packages/packages.go | 1347 -- .../golang.org/x/tools/go/packages/visit.go | 59 - .../x/tools/go/types/objectpath/objectpath.go | 752 - vendor/golang.org/x/tools/imports/forward.go | 77 - .../x/tools/internal/event/core/event.go | 85 - .../x/tools/internal/event/core/export.go | 70 - .../x/tools/internal/event/core/fast.go | 77 - .../golang.org/x/tools/internal/event/doc.go | 7 - .../x/tools/internal/event/event.go | 127 - .../x/tools/internal/event/keys/keys.go | 564 - .../x/tools/internal/event/keys/standard.go | 22 - .../x/tools/internal/event/keys/util.go | 21 - .../x/tools/internal/event/label/label.go | 215 - .../x/tools/internal/event/tag/tag.go | 59 - .../x/tools/internal/gcimporter/bimport.go | 150 - .../x/tools/internal/gcimporter/exportdata.go | 99 - .../x/tools/internal/gcimporter/gcimporter.go | 273 - .../x/tools/internal/gcimporter/iexport.go | 1321 -- .../x/tools/internal/gcimporter/iimport.go | 1082 -- .../internal/gcimporter/newInterface10.go | 22 - .../internal/gcimporter/newInterface11.go | 14 - .../internal/gcimporter/support_go117.go | 16 - .../internal/gcimporter/support_go118.go | 37 - .../x/tools/internal/gcimporter/unified_no.go | 10 - .../tools/internal/gcimporter/unified_yes.go | 10 - .../x/tools/internal/gcimporter/ureader_no.go | 19 - .../tools/internal/gcimporter/ureader_yes.go | 728 - .../x/tools/internal/gocommand/invoke.go | 465 - .../x/tools/internal/gocommand/vendor.go | 109 - .../x/tools/internal/gocommand/version.go | 71 - .../x/tools/internal/gopathwalk/walk.go | 331 - .../x/tools/internal/imports/fix.go | 1769 --- .../x/tools/internal/imports/imports.go | 356 - .../x/tools/internal/imports/mod.go | 723 - .../x/tools/internal/imports/mod_cache.go | 236 - .../x/tools/internal/imports/sortimports.go | 297 - .../x/tools/internal/imports/zstdlib.go | 11345 ---------------- .../internal/packagesinternal/packages.go | 22 - .../x/tools/internal/pkgbits/codes.go | 77 - .../x/tools/internal/pkgbits/decoder.go | 517 - .../x/tools/internal/pkgbits/doc.go | 32 - .../x/tools/internal/pkgbits/encoder.go | 383 - .../x/tools/internal/pkgbits/flags.go | 9 - .../x/tools/internal/pkgbits/frames_go1.go | 21 - .../x/tools/internal/pkgbits/frames_go17.go | 28 - .../x/tools/internal/pkgbits/reloc.go | 42 - .../x/tools/internal/pkgbits/support.go | 17 - .../x/tools/internal/pkgbits/sync.go | 113 - .../internal/pkgbits/syncmarker_string.go | 89 - .../internal/tokeninternal/tokeninternal.go | 151 - .../x/tools/internal/typeparams/common.go | 204 - .../x/tools/internal/typeparams/coretype.go | 122 - .../x/tools/internal/typeparams/normalize.go | 218 - .../x/tools/internal/typeparams/termlist.go | 163 - .../x/tools/internal/typeparams/typeterm.go | 169 - .../tools/internal/typesinternal/errorcode.go | 1560 --- .../typesinternal/errorcode_string.go | 179 - .../x/tools/internal/typesinternal/types.go | 52 - .../tools/internal/typesinternal/types_118.go | 19 - .../x/tools/internal/versions/gover.go | 172 - .../x/tools/internal/versions/types.go | 19 - .../x/tools/internal/versions/types_go121.go | 20 - .../x/tools/internal/versions/types_go122.go | 24 - .../tools/internal/versions/versions_go121.go | 49 - .../tools/internal/versions/versions_go122.go | 38 - vendor/k8s.io/code-generator/CONTRIBUTING.md | 7 - vendor/k8s.io/code-generator/LICENSE | 202 - vendor/k8s.io/code-generator/OWNERS | 15 - vendor/k8s.io/code-generator/README.md | 25 - .../cmd/applyconfiguration-gen/args/args.go | 81 - .../args/externaltypes.go | 122 - .../generators/applyconfiguration.go | 423 - .../generators/internal.go | 99 - .../generators/jsontagutil.go | 99 - .../generators/openapi.go | 198 - .../generators/packages.go | 297 - .../generators/refgraph.go | 179 - .../generators/types.go | 33 - .../applyconfiguration-gen/generators/util.go | 163 - .../cmd/applyconfiguration-gen/main.go | 54 - .../code-generator/cmd/client-gen/OWNERS | 11 - .../code-generator/cmd/client-gen/README.md | 2 - .../cmd/client-gen/args/args.go | 133 - .../cmd/client-gen/args/gvpackages.go | 173 - .../cmd/client-gen/args/gvtype.go | 110 - .../client-gen/generators/client_generator.go | 393 - .../generators/fake/fake_client_generator.go | 131 - .../fake/generator_fake_for_clientset.go | 170 - .../fake/generator_fake_for_group.go | 130 - .../fake/generator_fake_for_type.go | 570 - .../generators/generator_for_clientset.go | 209 - .../generators/generator_for_expansion.go | 54 - .../generators/generator_for_group.go | 267 - .../generators/generator_for_type.go | 760 -- .../generators/scheme/generator_for_scheme.go | 187 - .../cmd/client-gen/generators/util/tags.go | 344 - .../code-generator/cmd/client-gen/main.go | 63 - .../cmd/client-gen/path/path.go | 31 - .../cmd/client-gen/types/helpers.go | 121 - .../cmd/client-gen/types/types.go | 97 - .../cmd/conversion-gen/args/args.go | 90 - .../conversion-gen/generators/conversion.go | 1222 -- .../code-generator/cmd/conversion-gen/main.go | 139 - .../cmd/deepcopy-gen/args/args.go | 54 - .../code-generator/cmd/deepcopy-gen/main.go | 81 - .../cmd/defaulter-gen/args/args.go | 54 - .../code-generator/cmd/defaulter-gen/main.go | 77 - .../cmd/go-to-protobuf/.gitignore | 1 - .../code-generator/cmd/go-to-protobuf/OWNERS | 6 - .../code-generator/cmd/go-to-protobuf/main.go | 41 - .../cmd/go-to-protobuf/protobuf/cmd.go | 480 - .../cmd/go-to-protobuf/protobuf/generator.go | 773 -- .../go-to-protobuf/protobuf/import_tracker.go | 50 - .../cmd/go-to-protobuf/protobuf/namer.go | 208 - .../cmd/go-to-protobuf/protobuf/package.go | 215 - .../cmd/go-to-protobuf/protobuf/parser.go | 463 - .../cmd/go-to-protobuf/protobuf/tags.go | 33 - .../code-generator/cmd/import-boss/.gitignore | 1 - .../code-generator/cmd/import-boss/README.md | 97 - .../code-generator/cmd/import-boss/main.go | 45 - .../cmd/informer-gen/args/args.go | 83 - .../cmd/informer-gen/generators/factory.go | 340 - .../generators/factoryinterface.go | 90 - .../cmd/informer-gen/generators/generic.go | 184 - .../informer-gen/generators/groupinterface.go | 118 - .../cmd/informer-gen/generators/informer.go | 186 - .../cmd/informer-gen/generators/packages.go | 347 - .../cmd/informer-gen/generators/types.go | 43 - .../generators/versioninterface.go | 109 - .../code-generator/cmd/informer-gen/main.go | 60 - .../cmd/lister-gen/args/args.go | 64 - .../cmd/lister-gen/generators/expansion.go | 67 - .../cmd/lister-gen/generators/lister.go | 376 - .../code-generator/cmd/lister-gen/main.go | 57 - .../code-generator/cmd/openapi-gen/main.go | 57 - .../cmd/register-gen/generators/packages.go | 137 - .../generators/register_external.go | 117 - .../code-generator/cmd/register-gen/main.go | 49 - .../code-generator/cmd/set-gen/.gitignore | 1 - .../k8s.io/code-generator/cmd/set-gen/main.go | 53 - .../k8s.io/code-generator/generate-groups.sh | 66 - .../generate-internal-groups.sh | 272 - vendor/k8s.io/code-generator/kube_codegen.sh | 651 - .../code-generator/pkg/namer/tag-override.go | 58 - .../k8s.io/code-generator/pkg/util/build.go | 60 - .../pkg/util/plural_exceptions.go | 37 - .../third_party/forked/golang/LICENSE | 27 - .../third_party/forked/golang/PATENTS | 22 - .../third_party/forked/golang/reflect/type.go | 91 - vendor/k8s.io/code-generator/tools.go | 37 - vendor/k8s.io/component-base/config/OWNERS | 13 + .../k8s.io/component-base/config/doc.go | 5 +- vendor/k8s.io/component-base/config/types.go | 80 + .../config/v1alpha1/conversion.go | 53 + .../config/v1alpha1/defaults.go | 98 + .../component-base/config/v1alpha1/doc.go | 20 + .../config/v1alpha1/register.go | 31 + .../component-base/config/v1alpha1/types.go | 82 + .../v1alpha1/zz_generated.conversion.go | 133 + .../config/v1alpha1/zz_generated.deepcopy.go | 88 + .../config/zz_generated.deepcopy.go | 73 + vendor/k8s.io/gengo/LICENSE | 202 - vendor/k8s.io/gengo/args/args.go | 199 - .../deepcopy-gen/generators/deepcopy.go | 935 -- .../defaulter-gen/generators/defaulter.go | 1260 -- .../import-boss/generators/import_restrict.go | 443 - .../gengo/examples/set-gen/generators/sets.go | 378 - .../gengo/examples/set-gen/sets/byte.go | 221 - .../k8s.io/gengo/examples/set-gen/sets/int.go | 221 - .../gengo/examples/set-gen/sets/int64.go | 221 - .../gengo/examples/set-gen/sets/string.go | 221 - .../gengo/generator/default_generator.go | 62 - .../k8s.io/gengo/generator/default_package.go | 75 - vendor/k8s.io/gengo/generator/doc.go | 31 - .../k8s.io/gengo/generator/error_tracker.go | 50 - vendor/k8s.io/gengo/generator/execute.go | 329 - vendor/k8s.io/gengo/generator/generator.go | 259 - .../k8s.io/gengo/generator/import_tracker.go | 89 - .../k8s.io/gengo/generator/snippet_writer.go | 154 - .../gengo/generator/transitive_closure.go | 65 - vendor/k8s.io/gengo/namer/doc.go | 31 - vendor/k8s.io/gengo/namer/import_tracker.go | 121 - vendor/k8s.io/gengo/namer/namer.go | 395 - vendor/k8s.io/gengo/namer/order.go | 72 - vendor/k8s.io/gengo/namer/plural_namer.go | 120 - vendor/k8s.io/gengo/parser/doc.go | 19 - vendor/k8s.io/gengo/parser/parse.go | 925 -- vendor/k8s.io/gengo/types/comments.go | 82 - vendor/k8s.io/gengo/types/doc.go | 19 - vendor/k8s.io/gengo/types/flatten.go | 57 - vendor/k8s.io/gengo/types/types.go | 537 - .../kube-openapi/cmd/openapi-gen/args/args.go | 76 - .../kube-openapi/pkg/generators/README.md | 49 - .../kube-openapi/pkg/generators/api_linter.go | 219 - .../kube-openapi/pkg/generators/config.go | 91 - .../kube-openapi/pkg/generators/enum.go | 162 - .../kube-openapi/pkg/generators/extension.go | 202 - .../kube-openapi/pkg/generators/openapi.go | 871 -- .../kube-openapi/pkg/generators/rules/OWNERS | 4 - .../pkg/generators/rules/idl_tag.go | 53 - .../pkg/generators/rules/names_match.go | 178 - .../generators/rules/omitempty_match_case.go | 64 - .../kube-openapi/pkg/generators/union.go | 207 - .../kube-openapi/pkg/util/sets/empty.go | 27 - .../kube-openapi/pkg/util/sets/string.go | 207 - .../client-go/apiextensions/controller.go | 87 + .../client-go/apiextensions/kubernetes.go | 131 + .../client-go/apiextensions/types.go} | 16 +- .../client-go/apiextensions/v1/crd.go | 95 + vendor/modules.txt | 155 +- .../sigs.k8s.io/controller-runtime/.gitignore | 27 + .../controller-runtime/.golangci.yml | 170 + .../controller-runtime/CONTRIBUTING.md | 19 + vendor/sigs.k8s.io/controller-runtime/FAQ.md | 81 + .../sigs.k8s.io/controller-runtime/Makefile | 134 + vendor/sigs.k8s.io/controller-runtime/OWNERS | 10 + .../controller-runtime/OWNERS_ALIASES | 41 + .../sigs.k8s.io/controller-runtime/README.md | 66 + .../sigs.k8s.io/controller-runtime/RELEASE.md | 51 + .../controller-runtime}/SECURITY_CONTACTS | 11 +- .../controller-runtime/TMP-LOGGING.md | 169 + .../controller-runtime/VERSIONING.md | 30 + .../sigs.k8s.io/controller-runtime/alias.go | 159 + .../controller-runtime}/code-of-conduct.md | 0 vendor/sigs.k8s.io/controller-runtime/doc.go | 128 + .../pkg/builder/controller.go | 413 + .../controller-runtime/pkg/builder}/doc.go | 17 +- .../controller-runtime/pkg/builder/options.go | 156 + .../controller-runtime/pkg/builder/webhook.go | 252 + .../controller-runtime/pkg/cache/cache.go | 517 + .../pkg/cache/delegating_by_gvk_cache.go | 135 + .../controller-runtime/pkg/cache/doc.go | 19 + .../pkg/cache/informer_cache.go | 260 + .../pkg/cache/internal/cache_reader.go | 255 + .../pkg/cache/internal/informers.go | 587 + .../pkg/cache/internal/selector.go | 39 + .../pkg/cache/multi_namespace_cache.go | 424 + .../pkg/certwatcher/certwatcher.go | 204 + .../pkg/certwatcher/doc.go} | 21 +- .../pkg/certwatcher/metrics/metrics.go | 45 + .../pkg/client/config/config.go | 181 + .../pkg/client/config}/doc.go | 8 +- .../controller-runtime/pkg/cluster/cluster.go | 316 + .../pkg/cluster/internal.go | 105 + .../controller-runtime/pkg/config/config.go | 112 + .../pkg/config/controller.go | 49 + .../controller-runtime/pkg/config}/doc.go | 9 +- .../pkg/config/v1alpha1}/doc.go | 13 +- .../pkg/config/v1alpha1/register.go | 43 + .../pkg/config/v1alpha1/types.go | 179 + .../config/v1alpha1/zz_generated.deepcopy.go | 157 + .../pkg/controller/controller.go | 176 + .../controllerutil/controllerutil.go | 478 + .../pkg/controller/controllerutil}/doc.go | 10 +- .../controller-runtime/pkg/controller/doc.go | 25 + .../pkg/conversion/conversion.go | 40 + .../controller-runtime/pkg/event/doc.go | 28 + .../controller-runtime/pkg/event/event.go | 55 + .../controller-runtime/pkg/handler/doc.go | 38 + .../controller-runtime/pkg/handler/enqueue.go | 92 + .../pkg/handler/enqueue_mapped.go | 88 + .../pkg/handler/enqueue_owner.go | 199 + .../pkg/handler/eventhandler.go | 106 + .../controller-runtime/pkg/healthz/doc.go | 32 + .../controller-runtime/pkg/healthz/healthz.go | 206 + .../pkg/internal/controller/controller.go | 378 + .../internal/controller/metrics/metrics.go | 86 + .../pkg/internal/field/selector/utils.go | 37 + .../pkg/internal/httpserver/server.go | 16 + .../pkg/internal/log/log.go | 23 +- .../pkg/internal/recorder/recorder.go | 181 + .../pkg/internal/source/event_handler.go | 170 + .../pkg/internal/source/kind.go | 117 + .../pkg/internal/syncs/syncs.go | 38 + .../pkg/leaderelection/doc.go | 24 + .../pkg/leaderelection/leader_election.go | 127 + .../controller-runtime/pkg/manager/doc.go | 21 + .../pkg/manager/internal.go | 605 + .../controller-runtime/pkg/manager/manager.go | 669 + .../pkg/manager/runnable_group.go | 301 + .../controller-runtime/pkg/manager/server.go | 61 + .../pkg/manager/signals/doc.go | 20 + .../pkg/manager/signals/signal.go | 45 + .../pkg/manager/signals/signal_posix.go | 27 + .../pkg/manager/signals/signal_windows.go} | 10 +- .../pkg/metrics/client_go_adapter.go | 71 + .../controller-runtime/pkg/metrics/doc.go | 6 +- .../pkg/metrics/leaderelection.go | 40 + .../pkg/metrics/registry.go} | 27 +- .../pkg/metrics/server/doc.go | 26 + .../pkg/metrics/server/server.go | 312 + .../pkg/metrics/workqueue.go | 130 + .../controller-runtime/pkg/predicate/doc.go | 20 + .../pkg/predicate/predicate.go | 360 + .../controller-runtime/pkg/ratelimiter/doc.go | 22 + .../pkg/ratelimiter/ratelimiter.go | 30 + .../controller-runtime/pkg/reconcile/doc.go | 21 + .../pkg/reconcile/reconcile.go | 170 + .../pkg/recorder/recorder.go} | 28 +- .../controller-runtime/pkg/scheme/scheme.go | 93 + .../controller-runtime/pkg/source/doc.go | 22 + .../controller-runtime/pkg/source/source.go | 225 + .../pkg/webhook/admission/decode.go | 79 + .../pkg/webhook/admission/defaulter.go | 84 + .../pkg/webhook/admission/defaulter_custom.go | 94 + .../pkg/webhook/admission/doc.go | 22 + .../pkg/webhook/admission/http.go | 173 + .../pkg/webhook/admission/multi.go | 95 + .../pkg/webhook/admission/response.go | 124 + .../pkg/webhook/admission/validator.go | 127 + .../pkg/webhook/admission/validator_custom.go | 125 + .../pkg/webhook/admission/webhook.go | 251 + .../controller-runtime/pkg/webhook/alias.go | 81 + .../pkg/webhook/conversion/conversion.go | 343 + .../pkg/webhook/conversion/decoder.go | 50 + .../controller-runtime/pkg/webhook/doc.go | 28 + .../pkg/webhook/internal/metrics/metrics.go | 85 + .../controller-runtime/pkg/webhook/server.go | 302 + vendor/sigs.k8s.io/controller-tools/LICENSE | 201 - .../cmd/controller-gen/main.go | 263 - .../controller-tools/pkg/crd/conv.go | 43 - .../controller-tools/pkg/crd/desc_visitor.go | 78 - .../controller-tools/pkg/crd/doc.go | 63 - .../controller-tools/pkg/crd/flatten.go | 445 - .../controller-tools/pkg/crd/gen.go | 307 - .../controller-tools/pkg/crd/known_types.go | 180 - .../controller-tools/pkg/crd/markers/crd.go | 347 - .../controller-tools/pkg/crd/markers/doc.go | 46 - .../pkg/crd/markers/package.go | 40 - .../pkg/crd/markers/register.go | 83 - .../pkg/crd/markers/topology.go | 163 - .../pkg/crd/markers/validation.go | 495 - .../crd/markers/zz_generated.markerhelp.go | 489 - .../controller-tools/pkg/crd/parser.go | 243 - .../controller-tools/pkg/crd/schema.go | 464 - .../pkg/crd/schema_visitor.go | 131 - .../controller-tools/pkg/crd/spec.go | 168 - .../pkg/crd/zz_generated.markerhelp.go | 58 - .../controller-tools/pkg/deepcopy/gen.go | 305 - .../controller-tools/pkg/deepcopy/traverse.go | 829 -- .../pkg/deepcopy/zz_generated.markerhelp.go | 46 - .../controller-tools/pkg/genall/doc.go | 58 - .../controller-tools/pkg/genall/genall.go | 269 - .../controller-tools/pkg/genall/help/doc.go | 23 - .../pkg/genall/help/pretty/doc.go | 30 - .../pkg/genall/help/pretty/help.go | 171 - .../pkg/genall/help/pretty/print.go | 304 - .../pkg/genall/help/pretty/table.go | 64 - .../controller-tools/pkg/genall/help/sort.go | 106 - .../controller-tools/pkg/genall/help/types.go | 215 - .../controller-tools/pkg/genall/input.go | 37 - .../controller-tools/pkg/genall/options.go | 194 - .../controller-tools/pkg/genall/output.go | 160 - .../pkg/genall/zz_generated.markerhelp.go | 90 - .../controller-tools/pkg/loader/doc.go | 60 - .../controller-tools/pkg/loader/errors.go | 67 - .../controller-tools/pkg/loader/loader.go | 625 - .../controller-tools/pkg/loader/paths.go | 32 - .../controller-tools/pkg/loader/refs.go | 273 - .../controller-tools/pkg/loader/visit.go | 81 - .../controller-tools/pkg/markers/collect.go | 422 - .../controller-tools/pkg/markers/doc.go | 113 - .../controller-tools/pkg/markers/help.go | 81 - .../controller-tools/pkg/markers/parse.go | 963 -- .../controller-tools/pkg/markers/reg.go | 154 - .../controller-tools/pkg/markers/regutil.go | 36 - .../controller-tools/pkg/markers/zip.go | 201 - .../controller-tools/pkg/rbac/parser.go | 267 - .../pkg/rbac/zz_generated.markerhelp.go | 78 - .../controller-tools/pkg/schemapatcher/gen.go | 433 - .../schemapatcher/internal/yaml/convert.go | 61 - .../pkg/schemapatcher/internal/yaml/nested.go | 87 - .../pkg/schemapatcher/internal/yaml/set.go | 80 - .../schemapatcher/zz_generated.markerhelp.go | 50 - .../controller-tools/pkg/version/version.go | 49 - .../controller-tools/pkg/webhook/parser.go | 431 - .../pkg/webhook/zz_generated.markerhelp.go | 101 - 642 files changed, 17519 insertions(+), 73698 deletions(-) create mode 100644 .github/.kodiak.toml delete mode 100644 .github/workflows/ci-docs-only.yaml delete mode 100644 .github/workflows/ci.yaml create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/goreleaser.yml delete mode 100644 .github/workflows/image.yaml create mode 100644 .github/workflows/release-tracker.yml create mode 100644 .github/workflows/release.yml delete mode 100644 .goreleaser.yaml delete mode 100644 .ko.yaml delete mode 100644 CONTRIBUTING.md create mode 100644 Dockerfile.dbg rename Dockerfile => Dockerfile.in (60%) delete mode 100644 GOVERNANCE.md delete mode 100644 LICENSE create mode 100644 LICENSE.md delete mode 100644 OWNERS delete mode 100644 SECURITY.md rename {pkg/apis => apis}/kubebind/v1alpha1/apiservicebinding_types.go (93%) rename {pkg/apis => apis}/kubebind/v1alpha1/apiserviceexport_types.go (96%) rename {pkg/apis => apis}/kubebind/v1alpha1/apiserviceexportrequest_types.go (94%) rename {pkg/apis => apis}/kubebind/v1alpha1/apiservicenamespace_types.go (83%) rename {pkg/apis => apis}/kubebind/v1alpha1/bindingprovider_types.go (93%) rename {pkg/apis => apis}/kubebind/v1alpha1/bindingresponse_types.go (93%) rename {pkg/apis => apis}/kubebind/v1alpha1/clusterbinding_types.go (94%) create mode 100644 apis/kubebind/v1alpha1/crds.go rename {pkg/apis => apis}/kubebind/v1alpha1/doc.go (77%) rename {pkg/apis => apis}/kubebind/v1alpha1/helpers/crd.go (75%) rename {pkg/apis => apis}/kubebind/v1alpha1/helpers/serviceexport.go (94%) rename {pkg/apis => apis}/kubebind/v1alpha1/helpers/serviceexport_test.go (86%) rename {pkg/apis => apis}/kubebind/v1alpha1/register.go (90%) rename {pkg/apis => apis}/kubebind/v1alpha1/zz_generated.deepcopy.go (99%) rename {pkg/client => client}/clientset/versioned/clientset.go (92%) rename {pkg/client => client}/clientset/versioned/fake/clientset_generated.go (83%) create mode 100644 client/clientset/versioned/fake/doc.go rename {pkg/client => client}/clientset/versioned/fake/register.go (86%) rename {pkg/client => client}/clientset/versioned/scheme/doc.go (74%) rename {pkg/client => client}/clientset/versioned/scheme/register.go (86%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/apiservicebinding.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexport.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexportrequest.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/apiservicenamespace.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/clusterbinding.go (95%) create mode 100644 client/clientset/versioned/typed/kubebind/v1alpha1/doc.go create mode 100644 client/clientset/versioned/typed/kubebind/v1alpha1/fake/doc.go rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicebinding.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexport.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexportrequest.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicenamespace.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_clusterbinding.go (95%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_kubebind_client.go (84%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/generated_expansion.go (79%) rename {pkg/client => client}/clientset/versioned/typed/kubebind/v1alpha1/kubebind_client.go (91%) rename {pkg/client => client}/informers/externalversions/factory.go (95%) rename {pkg/client => client}/informers/externalversions/generic.go (91%) rename {pkg/client => client}/informers/externalversions/internalinterfaces/factory_interfaces.go (82%) rename {pkg/client => client}/informers/externalversions/kubebind/interface.go (76%) rename {pkg/client => client}/informers/externalversions/kubebind/v1alpha1/apiservicebinding.go (86%) rename {pkg/client => client}/informers/externalversions/kubebind/v1alpha1/apiserviceexport.go (86%) rename {pkg/client => client}/informers/externalversions/kubebind/v1alpha1/apiserviceexportrequest.go (87%) rename {pkg/client => client}/informers/externalversions/kubebind/v1alpha1/apiservicenamespace.go (86%) rename {pkg/client => client}/informers/externalversions/kubebind/v1alpha1/clusterbinding.go (86%) rename {pkg/client => client}/informers/externalversions/kubebind/v1alpha1/interface.go (90%) rename {pkg/client => client}/listers/kubebind/v1alpha1/apiservicebinding.go (89%) rename {pkg/client => client}/listers/kubebind/v1alpha1/apiserviceexport.go (93%) rename {pkg/client => client}/listers/kubebind/v1alpha1/apiserviceexportrequest.go (94%) rename {pkg/client => client}/listers/kubebind/v1alpha1/apiservicenamespace.go (93%) rename {pkg/client => client}/listers/kubebind/v1alpha1/clusterbinding.go (93%) rename {pkg/client => client}/listers/kubebind/v1alpha1/expansion_generated.go (91%) delete mode 100644 code-of-conduct.md rename {deploy/crd => crds}/kube-bind.appscode.com_apiservicebindings.yaml (99%) rename {deploy/crd => crds}/kube-bind.appscode.com_apiserviceexportrequests.yaml (99%) rename {deploy/crd => crds}/kube-bind.appscode.com_apiserviceexports.yaml (99%) rename {deploy/crd => crds}/kube-bind.appscode.com_apiservicenamespaces.yaml (97%) rename {deploy/crd => crds}/kube-bind.appscode.com_clusterbindings.yaml (99%) create mode 100644 crds/lib.go delete mode 100644 deploy/crd/bootstrap.go delete mode 100644 deploy/examples/crd-mangodb.yaml delete mode 100644 deploy/examples/crd-tangodb.yaml delete mode 100644 deploy/examples/servicenamespace-example.yaml delete mode 100644 deploy/patches/kube-bind.appscode.com_apiserviceexportrequests.yaml-patch delete mode 100644 hack/boilerplate/boilerplate.Dockerfile.txt delete mode 100644 hack/boilerplate/boilerplate.Makefile.txt delete mode 100644 hack/boilerplate/boilerplate.py.txt create mode 100755 hack/build.sh delete mode 100644 hack/dex-config-dev.yaml create mode 100755 hack/e2e.sh create mode 100755 hack/fmt.sh delete mode 100755 hack/go-install.sh create mode 100644 hack/import_hacks.go create mode 100644 hack/krew/plugin.yaml delete mode 100755 hack/lib.sh rename hack/{boilerplate/boilerplate.sh.txt => license/bash.txt} (68%) create mode 100644 hack/license/dockerfile.txt rename vendor/k8s.io/gengo/examples/set-gen/sets/doc.go => hack/license/go.txt (62%) create mode 100644 hack/license/makefile.txt create mode 100755 hack/scripts/update-release-tracker.sh create mode 100755 hack/test.sh delete mode 100755 hack/update-codegen-clients.sh delete mode 100755 hack/update-codegen.sh delete mode 100755 hack/verify-codegen-clients.sh delete mode 100755 hack/verify-go-versions.sh delete mode 100755 hack/verify-imports.sh delete mode 100644 vendor/github.com/gobuffalo/flect/.gitignore delete mode 100644 vendor/github.com/gobuffalo/flect/.gometalinter.json delete mode 100644 vendor/github.com/gobuffalo/flect/LICENSE delete mode 100644 vendor/github.com/gobuffalo/flect/Makefile delete mode 100644 vendor/github.com/gobuffalo/flect/README.md delete mode 100644 vendor/github.com/gobuffalo/flect/SHOULDERS.md delete mode 100644 vendor/github.com/gobuffalo/flect/acronyms.go delete mode 100644 vendor/github.com/gobuffalo/flect/camelize.go delete mode 100644 vendor/github.com/gobuffalo/flect/capitalize.go delete mode 100644 vendor/github.com/gobuffalo/flect/custom_data.go delete mode 100644 vendor/github.com/gobuffalo/flect/dasherize.go delete mode 100644 vendor/github.com/gobuffalo/flect/flect.go delete mode 100644 vendor/github.com/gobuffalo/flect/humanize.go delete mode 100644 vendor/github.com/gobuffalo/flect/ident.go delete mode 100644 vendor/github.com/gobuffalo/flect/lower_upper.go delete mode 100644 vendor/github.com/gobuffalo/flect/ordinalize.go delete mode 100644 vendor/github.com/gobuffalo/flect/pascalize.go delete mode 100644 vendor/github.com/gobuffalo/flect/plural_rules.go delete mode 100644 vendor/github.com/gobuffalo/flect/pluralize.go delete mode 100644 vendor/github.com/gobuffalo/flect/rule.go delete mode 100644 vendor/github.com/gobuffalo/flect/singular_rules.go delete mode 100644 vendor/github.com/gobuffalo/flect/singularize.go delete mode 100644 vendor/github.com/gobuffalo/flect/titleize.go delete mode 100644 vendor/github.com/gobuffalo/flect/underscore.go delete mode 100644 vendor/github.com/gobuffalo/flect/version.go create mode 100644 vendor/github.com/gorilla/mux/.editorconfig create mode 100644 vendor/github.com/gorilla/mux/.gitignore delete mode 100644 vendor/github.com/gorilla/mux/AUTHORS create mode 100644 vendor/github.com/gorilla/mux/Makefile create mode 100644 vendor/golang.org/x/exp/maps/maps.go delete mode 100644 vendor/golang.org/x/mod/LICENSE delete mode 100644 vendor/golang.org/x/mod/PATENTS delete mode 100644 vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go delete mode 100644 vendor/golang.org/x/mod/module/module.go delete mode 100644 vendor/golang.org/x/mod/module/pseudo.go delete mode 100644 vendor/golang.org/x/mod/semver/semver.go delete mode 100644 vendor/golang.org/x/tools/LICENSE delete mode 100644 vendor/golang.org/x/tools/PATENTS delete mode 100644 vendor/golang.org/x/tools/go/ast/astutil/enclosing.go delete mode 100644 vendor/golang.org/x/tools/go/ast/astutil/imports.go delete mode 100644 vendor/golang.org/x/tools/go/ast/astutil/rewrite.go delete mode 100644 vendor/golang.org/x/tools/go/ast/astutil/util.go delete mode 100644 vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go delete mode 100644 vendor/golang.org/x/tools/go/gcexportdata/importer.go delete mode 100644 vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go delete mode 100644 vendor/golang.org/x/tools/go/packages/doc.go delete mode 100644 vendor/golang.org/x/tools/go/packages/external.go delete mode 100644 vendor/golang.org/x/tools/go/packages/golist.go delete mode 100644 vendor/golang.org/x/tools/go/packages/golist_overlay.go delete mode 100644 vendor/golang.org/x/tools/go/packages/loadmode_string.go delete mode 100644 vendor/golang.org/x/tools/go/packages/packages.go delete mode 100644 vendor/golang.org/x/tools/go/packages/visit.go delete mode 100644 vendor/golang.org/x/tools/go/types/objectpath/objectpath.go delete mode 100644 vendor/golang.org/x/tools/imports/forward.go delete mode 100644 vendor/golang.org/x/tools/internal/event/core/event.go delete mode 100644 vendor/golang.org/x/tools/internal/event/core/export.go delete mode 100644 vendor/golang.org/x/tools/internal/event/core/fast.go delete mode 100644 vendor/golang.org/x/tools/internal/event/doc.go delete mode 100644 vendor/golang.org/x/tools/internal/event/event.go delete mode 100644 vendor/golang.org/x/tools/internal/event/keys/keys.go delete mode 100644 vendor/golang.org/x/tools/internal/event/keys/standard.go delete mode 100644 vendor/golang.org/x/tools/internal/event/keys/util.go delete mode 100644 vendor/golang.org/x/tools/internal/event/label/label.go delete mode 100644 vendor/golang.org/x/tools/internal/event/tag/tag.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/bimport.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/exportdata.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/iexport.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/iimport.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/support_go117.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/support_go118.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/unified_no.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go delete mode 100644 vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go delete mode 100644 vendor/golang.org/x/tools/internal/gocommand/invoke.go delete mode 100644 vendor/golang.org/x/tools/internal/gocommand/vendor.go delete mode 100644 vendor/golang.org/x/tools/internal/gocommand/version.go delete mode 100644 vendor/golang.org/x/tools/internal/gopathwalk/walk.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/fix.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/imports.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/mod.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/mod_cache.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/sortimports.go delete mode 100644 vendor/golang.org/x/tools/internal/imports/zstdlib.go delete mode 100644 vendor/golang.org/x/tools/internal/packagesinternal/packages.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/codes.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/decoder.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/doc.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/encoder.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/flags.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/reloc.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/support.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/sync.go delete mode 100644 vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go delete mode 100644 vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/common.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/coretype.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/normalize.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/termlist.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/typeterm.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/types.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/types_118.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/gover.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/types.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/types_go121.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/types_go122.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/versions_go121.go delete mode 100644 vendor/golang.org/x/tools/internal/versions/versions_go122.go delete mode 100644 vendor/k8s.io/code-generator/CONTRIBUTING.md delete mode 100644 vendor/k8s.io/code-generator/LICENSE delete mode 100644 vendor/k8s.io/code-generator/OWNERS delete mode 100644 vendor/k8s.io/code-generator/README.md delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/args/args.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/args/externaltypes.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/applyconfiguration.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/internal.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/jsontagutil.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/openapi.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/packages.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/refgraph.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/types.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/util.go delete mode 100644 vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/OWNERS delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/README.md delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/args/args.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/args/gvtype.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_group.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_type.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_expansion.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_group.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_type.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/generators/util/tags.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/path/path.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/types/helpers.go delete mode 100644 vendor/k8s.io/code-generator/cmd/client-gen/types/types.go delete mode 100644 vendor/k8s.io/code-generator/cmd/conversion-gen/args/args.go delete mode 100644 vendor/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go delete mode 100644 vendor/k8s.io/code-generator/cmd/conversion-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go delete mode 100644 vendor/k8s.io/code-generator/cmd/deepcopy-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/defaulter-gen/args/args.go delete mode 100644 vendor/k8s.io/code-generator/cmd/defaulter-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/.gitignore delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/OWNERS delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/import_tracker.go delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/namer.go delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/package.go delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/parser.go delete mode 100644 vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/tags.go delete mode 100644 vendor/k8s.io/code-generator/cmd/import-boss/.gitignore delete mode 100644 vendor/k8s.io/code-generator/cmd/import-boss/README.md delete mode 100644 vendor/k8s.io/code-generator/cmd/import-boss/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/args/args.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/generators/factoryinterface.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/generators/generic.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/generators/informer.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/generators/packages.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/generators/types.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/generators/versioninterface.go delete mode 100644 vendor/k8s.io/code-generator/cmd/informer-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/lister-gen/args/args.go delete mode 100644 vendor/k8s.io/code-generator/cmd/lister-gen/generators/expansion.go delete mode 100644 vendor/k8s.io/code-generator/cmd/lister-gen/generators/lister.go delete mode 100644 vendor/k8s.io/code-generator/cmd/lister-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/openapi-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/register-gen/generators/packages.go delete mode 100644 vendor/k8s.io/code-generator/cmd/register-gen/generators/register_external.go delete mode 100644 vendor/k8s.io/code-generator/cmd/register-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/cmd/set-gen/.gitignore delete mode 100644 vendor/k8s.io/code-generator/cmd/set-gen/main.go delete mode 100644 vendor/k8s.io/code-generator/generate-groups.sh delete mode 100644 vendor/k8s.io/code-generator/generate-internal-groups.sh delete mode 100644 vendor/k8s.io/code-generator/kube_codegen.sh delete mode 100644 vendor/k8s.io/code-generator/pkg/namer/tag-override.go delete mode 100644 vendor/k8s.io/code-generator/pkg/util/build.go delete mode 100644 vendor/k8s.io/code-generator/pkg/util/plural_exceptions.go delete mode 100644 vendor/k8s.io/code-generator/third_party/forked/golang/LICENSE delete mode 100644 vendor/k8s.io/code-generator/third_party/forked/golang/PATENTS delete mode 100644 vendor/k8s.io/code-generator/third_party/forked/golang/reflect/type.go delete mode 100644 vendor/k8s.io/code-generator/tools.go create mode 100644 vendor/k8s.io/component-base/config/OWNERS rename hack/boilerplate/boilerplate.generatego.txt => vendor/k8s.io/component-base/config/doc.go (80%) create mode 100644 vendor/k8s.io/component-base/config/types.go create mode 100644 vendor/k8s.io/component-base/config/v1alpha1/conversion.go create mode 100644 vendor/k8s.io/component-base/config/v1alpha1/defaults.go create mode 100644 vendor/k8s.io/component-base/config/v1alpha1/doc.go create mode 100644 vendor/k8s.io/component-base/config/v1alpha1/register.go create mode 100644 vendor/k8s.io/component-base/config/v1alpha1/types.go create mode 100644 vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go create mode 100644 vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go create mode 100644 vendor/k8s.io/component-base/config/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/gengo/LICENSE delete mode 100644 vendor/k8s.io/gengo/args/args.go delete mode 100644 vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go delete mode 100644 vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go delete mode 100644 vendor/k8s.io/gengo/examples/import-boss/generators/import_restrict.go delete mode 100644 vendor/k8s.io/gengo/examples/set-gen/generators/sets.go delete mode 100644 vendor/k8s.io/gengo/examples/set-gen/sets/byte.go delete mode 100644 vendor/k8s.io/gengo/examples/set-gen/sets/int.go delete mode 100644 vendor/k8s.io/gengo/examples/set-gen/sets/int64.go delete mode 100644 vendor/k8s.io/gengo/examples/set-gen/sets/string.go delete mode 100644 vendor/k8s.io/gengo/generator/default_generator.go delete mode 100644 vendor/k8s.io/gengo/generator/default_package.go delete mode 100644 vendor/k8s.io/gengo/generator/doc.go delete mode 100644 vendor/k8s.io/gengo/generator/error_tracker.go delete mode 100644 vendor/k8s.io/gengo/generator/execute.go delete mode 100644 vendor/k8s.io/gengo/generator/generator.go delete mode 100644 vendor/k8s.io/gengo/generator/import_tracker.go delete mode 100644 vendor/k8s.io/gengo/generator/snippet_writer.go delete mode 100644 vendor/k8s.io/gengo/generator/transitive_closure.go delete mode 100644 vendor/k8s.io/gengo/namer/doc.go delete mode 100644 vendor/k8s.io/gengo/namer/import_tracker.go delete mode 100644 vendor/k8s.io/gengo/namer/namer.go delete mode 100644 vendor/k8s.io/gengo/namer/order.go delete mode 100644 vendor/k8s.io/gengo/namer/plural_namer.go delete mode 100644 vendor/k8s.io/gengo/parser/doc.go delete mode 100644 vendor/k8s.io/gengo/parser/parse.go delete mode 100644 vendor/k8s.io/gengo/types/comments.go delete mode 100644 vendor/k8s.io/gengo/types/doc.go delete mode 100644 vendor/k8s.io/gengo/types/flatten.go delete mode 100644 vendor/k8s.io/gengo/types/types.go delete mode 100644 vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/README.md delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/config.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/enum.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/extension.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/openapi.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/rules/OWNERS delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/rules/idl_tag.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/rules/omitempty_match_case.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/generators/union.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/util/sets/empty.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/util/sets/string.go create mode 100644 vendor/kmodules.xyz/client-go/apiextensions/controller.go create mode 100644 vendor/kmodules.xyz/client-go/apiextensions/kubernetes.go rename vendor/{k8s.io/gengo/examples/set-gen/sets/empty.go => kmodules.xyz/client-go/apiextensions/types.go} (60%) create mode 100644 vendor/kmodules.xyz/client-go/apiextensions/v1/crd.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/.gitignore create mode 100644 vendor/sigs.k8s.io/controller-runtime/.golangci.yml create mode 100644 vendor/sigs.k8s.io/controller-runtime/CONTRIBUTING.md create mode 100644 vendor/sigs.k8s.io/controller-runtime/FAQ.md create mode 100644 vendor/sigs.k8s.io/controller-runtime/Makefile create mode 100644 vendor/sigs.k8s.io/controller-runtime/OWNERS create mode 100644 vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES create mode 100644 vendor/sigs.k8s.io/controller-runtime/README.md create mode 100644 vendor/sigs.k8s.io/controller-runtime/RELEASE.md rename vendor/{k8s.io/code-generator => sigs.k8s.io/controller-runtime}/SECURITY_CONTACTS (57%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md create mode 100644 vendor/sigs.k8s.io/controller-runtime/VERSIONING.md create mode 100644 vendor/sigs.k8s.io/controller-runtime/alias.go rename vendor/{k8s.io/code-generator => sigs.k8s.io/controller-runtime}/code-of-conduct.md (100%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go rename vendor/{k8s.io/kube-openapi/pkg/generators/rules => sigs.k8s.io/controller-runtime/pkg/builder}/doc.go (57%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cache/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go rename vendor/{k8s.io/code-generator/cmd/client-gen/generators/util/gvpackages.go => sigs.k8s.io/controller-runtime/pkg/certwatcher/doc.go} (63%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics/metrics.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go rename {pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake => vendor/sigs.k8s.io/controller-runtime/pkg/client/config}/doc.go (77%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/config/controller.go rename {pkg/client/clientset/versioned/fake => vendor/sigs.k8s.io/controller-runtime/pkg/config}/doc.go (76%) rename vendor/sigs.k8s.io/{controller-tools/pkg/deepcopy => controller-runtime/pkg/config/v1alpha1}/doc.go (54%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go rename {pkg/client/clientset/versioned/typed/kubebind/v1alpha1 => vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil}/doc.go (76%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/conversion/conversion.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/event/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/event/event.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/healthz/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/internal/httpserver/server.go rename hack/tools.go => vendor/sigs.k8s.io/controller-runtime/pkg/internal/log/log.go (64%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/manager/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/manager/server.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go rename vendor/{k8s.io/code-generator/doc.go => sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go} (81%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go rename hack/boilerplate/boilerplate.go.txt => vendor/sigs.k8s.io/controller-runtime/pkg/metrics/doc.go (81%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go rename vendor/{k8s.io/gengo/examples/set-gen/generators/tags.go => sigs.k8s.io/controller-runtime/pkg/metrics/registry.go} (53%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/metrics/server/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/metrics/server/server.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/predicate/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/ratelimiter/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/ratelimiter/ratelimiter.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go rename vendor/{k8s.io/code-generator/cmd/register-gen/args/args.go => sigs.k8s.io/controller-runtime/pkg/recorder/recorder.go} (53%) create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/source/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/doc.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics/metrics.go create mode 100644 vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/LICENSE delete mode 100644 vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/conv.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/desc_visitor.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/doc.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/flatten.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/gen.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/known_types.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/crd.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/doc.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/package.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/register.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/topology.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/validation.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/zz_generated.markerhelp.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/parser.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/schema.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/schema_visitor.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/spec.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/crd/zz_generated.markerhelp.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/gen.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/traverse.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/zz_generated.markerhelp.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/doc.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/genall.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/help/doc.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/doc.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/help.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/print.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/table.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/help/sort.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/help/types.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/input.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/options.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/output.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/genall/zz_generated.markerhelp.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/loader/doc.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/loader/errors.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/loader/loader.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/loader/paths.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/loader/refs.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/loader/visit.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/markers/collect.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/markers/doc.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/markers/help.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/markers/parse.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/markers/reg.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/markers/regutil.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/markers/zip.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/rbac/parser.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/rbac/zz_generated.markerhelp.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/gen.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/convert.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/nested.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/set.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/zz_generated.markerhelp.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/version/version.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/webhook/parser.go delete mode 100644 vendor/sigs.k8s.io/controller-tools/pkg/webhook/zz_generated.markerhelp.go diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml new file mode 100644 index 00000000..ded81e43 --- /dev/null +++ b/.github/.kodiak.toml @@ -0,0 +1,18 @@ +version = 1 + +[merge] +method = "squash" # default: "merge" +delete_branch_on_merge = true # default: false +optimistic_updates = true # default: true +prioritize_ready_to_merge = true # default: false + +[merge.message] +title = "pull_request_title" # default: "github_default" +body = "github_default" # default: "github_default" +strip_html_comments = true # default: false + +[update] +always = true # default: false + +[approve] +auto_approve_usernames = ["1gtm", "tamalsaha"] diff --git a/.github/workflows/ci-docs-only.yaml b/.github/workflows/ci-docs-only.yaml deleted file mode 100644 index f1e712d8..00000000 --- a/.github/workflows/ci-docs-only.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: CI - -# To satisfy required status checks for docs-only changes, configure jobs that match those in ci.yaml that -# always return true. -on: - pull_request: - branches: - - main - - 'release-*' - paths: - - "docs/**" - - "**/*.md" - - ".github/ISSUE_TEMPLATE/*" - - ".goreleaser.yaml" - - "contrib/manifests/**" - -jobs: - go-test-e2e: - name: go-test-e2e - runs-on: ubuntu-latest - steps: - - run: 'echo "No build required"' - - go-test: - name: go-test - runs-on: ubuntu-latest - steps: - - run: 'echo "No build required"' - - lint: - name: lint - runs-on: ubuntu-latest - steps: - - run: 'echo "No build required"' - - verify: - name: verify - runs-on: ubuntu-latest - steps: - - run: 'echo "No build required"' diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml deleted file mode 100644 index 3e93253d..00000000 --- a/.github/workflows/ci.yaml +++ /dev/null @@ -1,64 +0,0 @@ -name: CI - -on: - push: - branches: - - main - - 'release-*' - pull_request: - branches: - - main - - 'release-*' - paths-ignore: - - "docs/**" - - "**/*.md" - - ".github/ISSUE_TEMPLATE/*" - - ".goreleaser.yaml" - - "contrib/manifests/**" - -# NOTE!!! -# -# If you add a job here that is a REQUIRED status check in GitHub, you MUST add a job with the same name to ci-docs-only.yaml -# -# NOTE!!! - -jobs: - go-test-e2e: - name: go-test-e2e - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: v1.21.5 - - run: make test-e2e - - go-test: - name: go-test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: v1.21.5 - - run: make test - - lint: - name: lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: v1.21.5 - - run: make lint - - verify: - name: verify - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: v1.21.5 - - run: make verify \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..3be24bae --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: CI + +on: + pull_request: + branches: + - '*' + push: + branches: + - master + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build + runs-on: ubuntu-20.04 + steps: + + - name: Set up Go 1.21 + uses: actions/setup-go@v1 + with: + go-version: '1.21' + id: go + + - uses: actions/checkout@v2 + + - name: Set up QEMU + id: qemu + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Run checks + run: | + make ci diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml deleted file mode 100644 index 81f93bc1..00000000 --- a/.github/workflows/goreleaser.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: goreleaser - -on: - push: - tags: - - 'v*' - -permissions: - contents: write - -jobs: - goreleaser: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: actions/setup-go@v3 - with: - go-version: v1.21.5 - - name: Delete non-semver tags - run: 'git tag -d $(git tag -l | grep -v "^v")' - - name: Set LDFLAGS - run: echo LDFLAGS="$(make ldflags)" | tee -a >> $GITHUB_ENV - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v3 - with: - distribution: goreleaser - version: latest - args: release --timeout 60m - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - KREW_GITHUB_TOKEN: ${{ secrets.KREW_GITHUB_TOKEN }} - - uses: cytopia/upload-artifact-retry-action@v0.1.2 - if: ${{ always() }} - with: - name: binaries - path: dist/*.tar.gz diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml deleted file mode 100644 index 0f736b02..00000000 --- a/.github/workflows/image.yaml +++ /dev/null @@ -1,63 +0,0 @@ -name: image - -on: - push: - tags: - - 'v*' - -permissions: - contents: read - packages: write - id-token: write - -jobs: - image: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: v1.21.5 - check-latest: true - - uses: sigstore/cosign-installer@v2.7.0 - - name: Install ko - run: go install github.com/google/ko@latest - - - name: Set LDFLAGS - run: echo LDFLAGS="$(make ldflags)" | tee -a >> $GITHUB_ENV - - # Build ko from HEAD, build and push an image tagged with the commit SHA, - # then keylessly sign it with cosign. - - name: Publish and sign konnector image - env: - KO_DOCKER_REPO: ghcr.io/${{ github.repository_owner }}/konnector - COSIGN_EXPERIMENTAL: 'true' - run: | - echo "${{ github.token }}" | ko login ghcr.io --username "${{ github.actor }}" --password-stdin - img=$(ko build --bare --platform=all -t latest -t ${{ github.sha }} -t ${{github.ref_name}} ./cmd/konnector) - echo "built ${img}" - cosign sign ${img} \ - -a sha=${{ github.sha }} \ - -a ref=${{ github.ref }} \ - -a run_id=${{ github.run_id }} \ - -a run_attempt=${{ github.run_attempt }} - - - name: Publish and sign example-backend image - env: - KO_DOCKER_REPO: ghcr.io/${{ github.repository_owner }}/example-backend - COSIGN_EXPERIMENTAL: 'true' - run: | - echo "${{ github.token }}" | ko login ghcr.io --username "${{ github.actor }}" --password-stdin - img=$(ko build --bare --platform=all -t latest -t ${{ github.sha }} -t ${{github.ref_name}} ./cmd/example-backend) - echo "built ${img}" - cosign sign ${img} \ - -a sha=${{ github.sha }} \ - -a ref=${{ github.ref }} \ - -a run_id=${{ github.run_id }} \ - -a run_attempt=${{ github.run_attempt }} - - - uses: actions/delete-package-versions@v3 - with: - package-name: 'kube-bind' - min-versions-to-keep: 10 - delete-only-pre-release-versions: "true" \ No newline at end of file diff --git a/.github/workflows/release-tracker.yml b/.github/workflows/release-tracker.yml new file mode 100644 index 00000000..c53fdf2f --- /dev/null +++ b/.github/workflows/release-tracker.yml @@ -0,0 +1,41 @@ +name: release-tracker + +on: + pull_request: + types: [closed] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v1 + + - name: Prepare git + env: + GITHUB_USER: 1gtm + GITHUB_TOKEN: ${{ secrets.LGTM_GITHUB_TOKEN }} + run: | + git config --global user.name "${GITHUB_USER}" + git config --global user.email "${GITHUB_USER}@appscode.com" + git remote set-url origin https://${GITHUB_USER}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git + + - name: Install GitHub CLI + run: | + curl -fsSL https://github.com/github/hub/raw/master/script/get | bash -s 2.14.1 + sudo mv bin/hub /usr/local/bin + + - name: Update release tracker + if: | + github.event.action == 'closed' && + github.event.pull_request.merged == true + env: + GITHUB_USER: 1gtm + GITHUB_TOKEN: ${{ secrets.LGTM_GITHUB_TOKEN }} + run: | + ./hack/scripts/update-release-tracker.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..7dcb8d7e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,86 @@ +name: Release + +on: + push: + tags: + - "*.*" + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v1 + + - name: Print version info + id: semver + run: | + make version + + - name: Set up QEMU + id: qemu + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Log in to the GitHub Container registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.LGTM_GITHUB_TOKEN }} + + - name: Build + env: + APPSCODE_ENV: prod + run: | + make release COMPRESS=yes + + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: | + bin/kubectl-connect-darwin-amd64.tar.gz + bin/kubectl-connect-darwin-arm64.tar.gz + bin/kubectl-connect-linux-amd64.tar.gz + bin/kubectl-connect-linux-arm.tar.gz + bin/kubectl-connect-linux-arm64.tar.gz + bin/kubectl-connect-windows-amd64.zip + bin/kubectl-connect-checksums.txt + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install GitHub CLI + run: | + curl -fsSL https://github.com/github/hub/raw/master/script/get | bash -s 2.14.1 + sudo mv bin/hub /usr/local/bin + + - name: Clone krew-index repository + env: + GITHUB_USER: 1gtm + GITHUB_TOKEN: ${{ secrets.LGTM_GITHUB_TOKEN }} + run: | + KREW_INDEX_REPOSITORY=github.com/appscode/krew-index + url="https://${GITHUB_USER}:${GITHUB_TOKEN}@${KREW_INDEX_REPOSITORY}.git" + cd $RUNNER_WORKSPACE + git clone $url + cd $(basename $KREW_INDEX_REPOSITORY) + git config user.name "${GITHUB_USER}" + git config user.email "${GITHUB_USER}@appscode.com" + + - name: Publish krew manifest + env: + GITHUB_USER: 1gtm + GITHUB_TOKEN: ${{ secrets.LGTM_GITHUB_TOKEN }} + if: startsWith(github.event.ref, 'refs/tags/') && (contains(github.ref, '-alpha.') || contains(github.ref, '-beta.') || contains(github.ref, '-rc.')) == false + run: | + cd $RUNNER_WORKSPACE/krew-index + ./hack/scripts/open-pr.sh $GITHUB_WORKSPACE dba diff --git a/.gitignore b/.gitignore index 16cb5387..486bd81f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ coverage.* /hack/tools /build /dex -/bin \ No newline at end of file +/bin +/.config diff --git a/.goreleaser.yaml b/.goreleaser.yaml deleted file mode 100644 index 01141da0..00000000 --- a/.goreleaser.yaml +++ /dev/null @@ -1,43 +0,0 @@ -builds: -- id: "kubectl-bind" - main: ./cmd/kubectl-bind - binary: bin/kubectl-bind - ldflags: - - "{{ .Env.LDFLAGS }}" - goos: - - linux - - darwin - - windows - goarch: - - amd64 - - arm64 - - ppc64le - ignore: - - goos: darwin - goarch: ppc64le - - goos: windows - goarch: ppc64le -archives: -- id: kubectl-bind - builds: - - kubectl-bind - name_template: "kubectl-bind_{{ .Version }}_{{ .Os }}_{{ .Arch }}" -release: - prerelease: auto - mode: keep-existing - -krews: -- name: bind - ids: - - kubectl-bind - index: - owner: kube-bind - name: krew-index - token: "{{ .Env.KREW_GITHUB_TOKEN }}" - homepage: "https://kubectl-bind.io/" - description: | - Binds API services and other remote types into the current cluster. API services - are CRDs that are operated by a service provider without anything by that service - provider running in the local cluster. Real SaaS for Kubernetes. - short_description: "Bind API services and other remote types into the current cluster." - skip_upload: auto diff --git a/.ko.yaml b/.ko.yaml deleted file mode 100644 index 17634541..00000000 --- a/.ko.yaml +++ /dev/null @@ -1,12 +0,0 @@ -baseImageOverrides: - github.com/google/ko: golang:1.21.5 - -builds: -- id: konnector - dir: ./cmd/konnector - ldflags: - - "{{ .Env.LDFLAGS }}" -- id: example-backend - dir: ./cmd/example-backend - ldflags: - - "{{ .Env.LDFLAGS }}" \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 48ee2dad..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,98 +0,0 @@ -# Contributing to kube-bind - -kube-bind is [Apache 2.0 licensed](LICENSE) and we accept contributions via -GitHub pull requests. - -Please read the following guide if you're interested in contributing to kube-bind. - -## Certificate of Origin - -By contributing to this project you agree to the Developer Certificate of -Origin (DCO). This document was created by the Linux Kernel community and is a -simple statement that you, as a contributor, have the legal right to make the -contribution. See the [DCO](DCO) file for details. - -## Getting started - -### Prerequisites - -1. Clone this repository. -2. [Install Go](https://golang.org/doc/install) (1.18+). -3. Install [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl). - -### Build & verify -1. In one terminal, build and start `bin/kubectl-bind`: -``` -make -bin/kubectl-bind -``` - -## Finding areas to contribute - -Starting to participate in a new project can sometimes be overwhelming, and you may not know where to begin. Fortunately, we are here to help! We track all of our tasks here in GitHub, and we label our issues to categorize them. Here are a couple of handy links to check out: - -* [Good first issue](https://github.com/kube-bind/kube-bind/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) issues -* [Help wanted](https://github.com/kube-bind/kube-bind/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issues - -You're certainly not limited to only these kinds of issues, though! If you're comfortable, please feel free to try working on anything that is open. - -We do use the assignee feature in GitHub for issues. If you find an unassigned issue, comment asking if you can be assigned, and ideally wait for a maintainer to respond. If you find an assigned issue and you want to work on it or help out, please reach out to the assignee first. - -Sometimes you might get an amazing idea and start working on a huge amount of code. We love and encourage excitement like this, but we do ask that before you embarking on a giant pull request, please reach out to the community first for an initial discussion. You could [file an issue](https://github.com/kube-bind/kube-bind/issues/new/choose). - -Finally, we welcome and value all types of contributions, beyond "just code"! Other types include triaging bugs, tracking down and fixing flaky tests, improving our documentation, helping answer community questions, proposing and reviewing designs, etc. - -## Coding guidelines & conventions - -- Logging: - - We use klog's contextual logging: `logging := klog.FromContext(ctx)`. - - Default log-level is 2. - - Controllers should generally log (a) **one** line (not more) non-error progress per item with `klog.Info` (b) actions like create/update/delete via `klog.V(1).Info` and (c) skipped actions, i.e. what was not done for reasons via `klog.V(2).Info`. -- Go Proverbs are good guidelines for style: https://go-proverbs.github.io/ – watch https://www.youtube.com/watch?v=PAAkCSZUG1c. -- We use [https://github.com/stretchr/testify/tree/master/require](github.com/stretchr/testify/require) a lot in tests, and avoid - [https://github.com/stretchr/testify/tree/master/assert](https://github.com/stretchr/testify/assert). - - Note this subtle distinction of nested `require` statements: - ```Golang - require.Eventually(t, func() bool { - foos, err := client.List(...) - require.NoError(err) // fail fast, including failing require.Eventually immediately - return someCondition(foos) - }, ...) - ``` - and - ```Golang - require.Eventually(t, func() bool { - foos, err := client.List(...) - if err != nil { - return false // keep trying - } - return someCondition(foos) - }, ...) - ``` - The first fails fast on every client error. The second ignores client errors and keeps trying. Either - has its place, depending on whether the client error is to be expected (e.g. because of asynchronicity making the resource available), - or signals a real test problem. - -### Using Kubebuilder CRD Validation Annotations - -All of the API resources for `kube-bind` are `CustomResourceDefinitions`, and we generate YAML spec for them from our Go types using [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder). - -When adding a field that requires validation, custom annotations are used to translate this logic into the generated OpenAPI spec. [This doc](https://book.kubebuilder.io/reference/markers/crd-validation.html) gives an overview of possible validations. These annotations map directly to concepts in the [OpenAPI Spec](https://swagger.io/specification/#data-type-format) so, for instance, the `format` of strings is defined there, not in kubebuilder. Furthermore, Kubernetes has forked the OpenAPI project [here](https://github.com/kubernetes/kube-openapi/tree/master/pkg/validation) and extends more formats in the extensions-apiserver [here](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go#L27). - -## Community Roles - -### Reviewers - -Reviewers are responsible for reviewing code for correctness and adherence to standards. Oftentimes reviewers will -be able to advise on code efficiency and style as it relates to golang or project conventions as well as other considerations -that might not be obvious to the contributor. - -### Approvers - -Approvers are responsible for sign-off on the acceptance of the contribution. In essence, approval indicates that the -change is desired and good for the project, aligns with code, api, and system conventions, and appears to follow all required -process including adequate testing, documentation, follow ups, or notifications to other areas who might be interested -or affected by the change. - -Approvers are also reviewers. diff --git a/Dockerfile.dbg b/Dockerfile.dbg new file mode 100644 index 00000000..1c16abeb --- /dev/null +++ b/Dockerfile.dbg @@ -0,0 +1,34 @@ + +# Copyright AppsCode Inc. and Contributors. +# +# 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. + +FROM ghcr.io/appscode/dlv:1.22.0 + +FROM {ARG_FROM} + +LABEL org.opencontainers.image.source https://github.com/bytebuilders/kube-bind + +RUN set -x \ + && apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends ca-certificates \ + && rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man /tmp/* \ + && echo 'Etc/UTC' > /etc/timezone + +ADD bin/{ARG_BIN}-{ARG_OS}-{ARG_ARCH} /{ARG_BIN} +COPY --from=0 /usr/local/bin/dlv /bin/dlv + +EXPOSE 40000 + +ENTRYPOINT ["/bin/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "exec", "/{ARG_BIN}", "--"] diff --git a/Dockerfile b/Dockerfile.in similarity index 60% rename from Dockerfile rename to Dockerfile.in index 9f2ef633..8e6d9019 100644 --- a/Dockerfile +++ b/Dockerfile.in @@ -1,4 +1,5 @@ -# Copyright 2022 The Kube Bind Authors. + +# Copyright AppsCode Inc. and Contributors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,9 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -#FROM golang:1.21.5 AS builder -FROM debian:latest +FROM {ARG_FROM} + +LABEL org.opencontainers.image.source https://github.com/bytebuilders/kube-bind + +RUN set -x \ + && apk add --update --upgrade --no-cache pcre2 ca-certificates tzdata \ + && echo 'Etc/UTC' > /etc/timezone + +ADD bin/{ARG_BIN}-{ARG_OS}-{ARG_ARCH} /{ARG_BIN} -COPY bin/konnector /konnector +USER 65534 -ENTRYPOINT ["/konnector"] \ No newline at end of file +ENTRYPOINT ["/{ARG_BIN}"] diff --git a/GOVERNANCE.md b/GOVERNANCE.md deleted file mode 100644 index 5f95811e..00000000 --- a/GOVERNANCE.md +++ /dev/null @@ -1,139 +0,0 @@ -# kube-bind Project Governance - -The kube-bind project is dedicated to build a vendor-neutral mechanism to bind -services of different kinds into Kubernetes clusters using Kubernetes-native APIs. -This governance explains how the project is run. - -- [Values](#values) -- [Maintainers](#maintainers) -- [Code of Conduct Enforcement](#code-of-conduct) -- [Security Response Team](#security-response-team) -- [Voting](#voting) -- [Modifying this Charter](#modifying-this-charter) - -## Values - -The kube-bind and its leadership embrace the following values: - - * *Openness*: Communication and decision-making happens in the open and is - discoverable for future reference. As much as possible, all discussions and - work take place in public forums and open repositories. - * *Fairness*: All stakeholders have the opportunity to provide feedback and - submit contributions, which will be considered on their merits. - * *Community over Product or Company*: Sustaining and growing our community - takes priority over shipping code or sponsors' organizational goals. Each - contributor participates in the project as an individual. - * *Inclusivity*: We innovate through different perspectives and skill sets, - which can only be accomplished in a welcoming and respectful environment. - * *Participation*: Responsibilities within the project are earned through - participation, and there is a clear path up the contributor ladder into - leadership positions. - -## Maintainers - -kube-bind Maintainers have write access to the [project GitHub repository](https://github.com/kube-bind/kube-bind). -They can merge their own patches or patches from others. The current maintainers -can be found as top-level approvers in [OWNERS](./OWNERS). Maintainers collectively -manage the project's resources and contributors. - -This privilege is granted with some expectation of responsibility: maintainers -are people who care about the kube-bind project and want to help it grow and -improve. A maintainer is not just someone who can make changes, but someone who -has demonstrated their ability to collaborate with the team, get the most -knowledgeable people to review code and docs, contribute high-quality code, and -follow through to fix issues (in code or tests). - -A maintainer is a contributor to the project's success and a citizen helping -the project succeed. - -The collective team of all Maintainers is known as the Maintainer Council, which -is the governing body for the project. - -## Becoming a Maintainer - - - -To become a Maintainer you need to demonstrate the following: - - * commitment to the project: - * participate in discussions, contributions, code and documentation reviews - for 3 months or more, - * perform reviews for 5 non-trivial pull requests, - * contribute 5 non-trivial pull requests and have them merged, - * ability to write quality code and/or documentation, - * ability to collaborate with the team, - * understanding of how the team works (policies, processes for testing and code review, etc), - * understanding of the project's code base and coding and documentation style. - - -A new Maintainer must be proposed by an existing maintainer by sending a message to the -[developer mailing list](https://groups.google.com/g/kube-bind-dev). A simple majority -vote of existing Maintainers approves the application. - -Maintainers who are selected will be granted the necessary GitHub rights, -and invited to the [private maintainer mailing list](https://groups.google.com/g/kube-bind-dev-private). - -### Bootstrapping Maintainers - -To bootstrap the process, 3 maintainers are defined (in the initial PR adding -this to the repository) that do not necessarily follow the above rules. When a -new maintainer is added following the above rules, the existing maintainers -define one not following the rules to step down, until all of them follow the -rules. - -### Removing a Maintainer - -Maintainers may resign at any time if they feel that they will not be able to -continue fulfilling their project duties. - -Maintainers may also be removed after being inactive, failure to fulfill their -Maintainer responsibilities, violating the Code of Conduct, or other reasons. -Inactivity is defined as a period of very low or no activity in the project for -a year or more, with no definite schedule to return to full Maintainer activity. - -A Maintainer may be removed at any time by a 2/3 vote of the remaining maintainers. - -Depending on the reason for removal, a Maintainer may be converted to Emeritus -status. Emeritus Maintainers will still be consulted on some project matters, -and can be rapidly returned to Maintainer status if their availability changes. - -## Code of Conduct - - - -[Code of Conduct](./code-of-conduct.md) -violations by community members will be discussed and resolved -on the [private Maintainer mailing list](https://groups.google.com/g/kube-bind-dev-private). - -## Security Response Team - -The Maintainers will appoint a Security Response Team to handle security reports. -This committee may simply consist of the Maintainer Council themselves. If this -responsibility is delegated, the Maintainers will appoint a team of at least two -contributors to handle it. The Maintainers will review who is assigned to this -at least once a year. - -The Security Response Team is responsible for handling all reports of security -holes and breaches according to the [security policy](./SECURITY.md). - -## Voting - -While most business in kube-bind is conducted by "lazy consensus", periodically -the Maintainers may need to vote on specific actions or changes. -A vote can be taken on [the developer mailing list](https://groups.google.com/g/kube-bind-dev) or -[the private Maintainer mailing list](https://groups.google.com/g/kube-bind-dev-private) -for security or conduct matters. Votes may also be taken at the community call -meeting. Any Maintainer may demand a vote be taken. - -Most votes require a simple majority of all Maintainers to succeed. Maintainers -can be removed by a 2/3 majority vote of all Maintainers, and changes to this -Governance require a 2/3 vote of all Maintainers. - -## Modifying this Charter - -Changes to this Governance and its supporting documents may be approved by a -2/3 vote of the Maintainers. \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..dc16ee16 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,5 @@ +## License + +Source code in this repository, Binaries, Docker images and Charts produced by the build process are licensed under the AppsCode Community License 1.0.0. You may obtain a copy of the License at + + - [AppsCode-Community-1.0.0](https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md) diff --git a/Makefile b/Makefile index b44a388c..65eac1aa 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ -# Copyright 2021 The Kube Bind Authors. + +# Copyright AppsCode Inc. and Contributors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,259 +13,505 @@ # See the License for the specific language governing permissions and # limitations under the License. -# We need bash for some conditional logic below. -SHELL := /usr/bin/env bash -e +SHELL=/bin/bash -o pipefail + +PRODUCT_OWNER_NAME := appscode +PRODUCT_NAME := kube-bind +ENFORCE_LICENSE ?= + +GO_PKG := go.bytebuilders.dev +REPO := $(notdir $(shell pwd)) +BIN := kubectl-connect +COMPRESS ?= no -GO_INSTALL = ./hack/go-install.sh +CRD_OPTIONS ?= "crd:crdVersions={v1},allowDangerousTypes=true,generateEmbeddedObjectMeta=true" +CODE_GENERATOR_IMAGE ?= ghcr.io/appscode/gengo:release-1.29 +API_GROUPS ?= kubebind:v1alpha1 -TOOLS_DIR=hack/tools -TOOLS_GOBIN_DIR := $(abspath $(TOOLS_DIR)) -GOBIN_DIR=$(abspath ./bin ) -PATH := $(GOBIN_DIR):$(TOOLS_GOBIN_DIR):$(PATH) -TMPDIR := $(shell mktemp -d) +# Where to push the docker image. +REGISTRY ?= ghcr.io/appscode +SRC_REG ?= -# Detect the path used for the install target -ifeq (,$(shell go env GOBIN)) -INSTALL_GOBIN=$(shell go env GOPATH)/bin +# This version-strategy uses git tags to set the version string +git_branch := $(shell git rev-parse --abbrev-ref HEAD) +git_tag := $(shell git describe --exact-match --abbrev=0 2>/dev/null || echo "") +commit_hash := $(shell git rev-parse --verify HEAD) +commit_timestamp := $(shell date --date="@$$(git show -s --format=%ct)" --utc +%FT%T) + +VERSION := $(shell git describe --tags --always --dirty) +version_strategy := commit_hash +ifdef git_tag + VERSION := $(git_tag) + version_strategy := tag else -INSTALL_GOBIN=$(shell go env GOBIN) + ifeq (,$(findstring $(git_branch),master HEAD)) + ifneq (,$(patsubst release-%,,$(git_branch))) + VERSION := $(git_branch) + version_strategy := branch + endif + endif endif -CONTROLLER_GEN_VER := v0.10.0 -CONTROLLER_GEN_BIN := controller-gen -CONTROLLER_GEN := $(TOOLS_DIR)/$(CONTROLLER_GEN_BIN)-$(CONTROLLER_GEN_VER) -export CONTROLLER_GEN # so hack scripts can use it - -YAML_PATCH_VER ?= v0.0.11 -YAML_PATCH_BIN := yaml-patch -YAML_PATCH := $(TOOLS_DIR)/$(YAML_PATCH_BIN)-$(YAML_PATCH_VER) -export YAML_PATCH # so hack scripts can use it - -OPENSHIFT_GOIMPORTS_VER := c72f1dc2e3aacfa00aece3391d938c9bc734e791 -OPENSHIFT_GOIMPORTS_BIN := openshift-goimports -OPENSHIFT_GOIMPORTS := $(TOOLS_DIR)/$(OPENSHIFT_GOIMPORTS_BIN)-$(OPENSHIFT_GOIMPORTS_VER) -export OPENSHIFT_GOIMPORTS # so hack scripts can use it - -GOLANGCI_LINT_VER := v1.49.0 -GOLANGCI_LINT_BIN := golangci-lint -GOLANGCI_LINT := $(TOOLS_GOBIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER) - -STATICCHECK_VER := 2022.1 -STATICCHECK_BIN := staticcheck -STATICCHECK := $(TOOLS_GOBIN_DIR)/$(STATICCHECK_BIN)-$(STATICCHECK_VER) - -GOTESTSUM_VER := v1.8.1 -GOTESTSUM_BIN := gotestsum -GOTESTSUM := $(abspath $(TOOLS_DIR))/$(GOTESTSUM_BIN)-$(GOTESTSUM_VER) - -LOGCHECK_VER := v0.2.0 -LOGCHECK_BIN := logcheck -LOGCHECK := $(TOOLS_GOBIN_DIR)/$(LOGCHECK_BIN)-$(LOGCHECK_VER) -export LOGCHECK # so hack scripts can use it - -KCP_VER := v0.11.0 -KCP_BIN := kcp -KCP := $(TOOLS_GOBIN_DIR)/$(KCP_BIN)-$(KCP_VER) - -DEX_VER := v2.35.2 -DEX_BIN := dex -DEX := $(TOOLS_GOBIN_DIR)/$(DEX_BIN)-$(DEX_VER) - -ARCH := $(shell go env GOARCH) -OS := $(shell go env GOOS) - -KUBE_MAJOR_VERSION := 1 -KUBE_MINOR_VERSION := $(shell go mod edit -json | jq '.Require[] | select(.Path == "k8s.io/client-go") | .Version' --raw-output | sed "s/v[0-9]*\.\([0-9]*\).*/\1/") -GIT_COMMIT := $(shell git rev-parse --short HEAD || echo 'local') -GIT_DIRTY := $(shell git diff --quiet && echo 'clean' || echo 'dirty') -GIT_VERSION := $(shell go mod edit -json | jq '.Require[] | select(.Path == "k8s.io/client-go") | .Version' --raw-output | sed 's/v0/v1/')+kube-bind-$(shell git describe --tags --match='v*' --abbrev=14 "$(GIT_COMMIT)^{commit}" 2>/dev/null || echo v0.0.0-$(GIT_COMMIT)) -BUILD_DATE := $(shell date -u +'%Y-%m-%dT%H:%M:%SZ') -LDFLAGS := \ - -X k8s.io/client-go/pkg/version.gitCommit=${GIT_COMMIT} \ - -X k8s.io/client-go/pkg/version.gitTreeState=${GIT_DIRTY} \ - -X k8s.io/client-go/pkg/version.gitVersion=${GIT_VERSION} \ - -X k8s.io/client-go/pkg/version.gitMajor=${KUBE_MAJOR_VERSION} \ - -X k8s.io/client-go/pkg/version.gitMinor=${KUBE_MINOR_VERSION} \ - -X k8s.io/client-go/pkg/version.buildDate=${BUILD_DATE} \ - \ - -X k8s.io/component-base/version.gitCommit=${GIT_COMMIT} \ - -X k8s.io/component-base/version.gitTreeState=${GIT_DIRTY} \ - -X k8s.io/component-base/version.gitVersion=${GIT_VERSION} \ - -X k8s.io/component-base/version.gitMajor=${KUBE_MAJOR_VERSION} \ - -X k8s.io/component-base/version.gitMinor=${KUBE_MINOR_VERSION} \ - -X k8s.io/component-base/version.buildDate=${BUILD_DATE} -all: build -.PHONY: all - -ldflags: - @echo $(LDFLAGS) - -.PHONY: require-% -require-%: - @if ! command -v $* 1> /dev/null 2>&1; then echo "$* not found in \$$PATH"; exit 1; fi - -build: WHAT ?= ./cmd/... -build: require-jq require-go require-git verify-go-versions ## Build the project - GOOS=$(OS) GOARCH=$(ARCH) go build $(BUILDFLAGS) -ldflags="$(LDFLAGS)" -o bin/ $(WHAT) -.PHONY: build - -.PHONY: build-all -build-all: - GOOS=$(OS) GOARCH=$(ARCH) $(MAKE) build WHAT=./cmd/... - -install: WHAT ?= ./cmd/... -install: ## install binaries to GOBIN - GOOS=$(OS) GOARCH=$(ARCH) go install -ldflags="$(LDFLAGS)" $(WHAT) -.PHONY: install - -$(GOLANGCI_LINT): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/golangci/golangci-lint/cmd/golangci-lint $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER) - -$(STATICCHECK): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) honnef.co/go/tools/cmd/staticcheck $(STATICCHECK_BIN) $(STATICCHECK_VER) - -$(LOGCHECK): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) sigs.k8s.io/logtools/logcheck $(LOGCHECK_BIN) $(LOGCHECK_VER) - -lint: $(GOLANGCI_LINT) $(STATICCHECK) $(LOGCHECK) ## Run linters - $(GOLANGCI_LINT) run --timeout=10m --skip-dirs pkg/client ./... - $(STATICCHECK) -checks ST1019,ST1005 ./... -.PHONY: lint +### +### These variables should not need tweaking. +### -vendor: ## Vendor the dependencies - go mod tidy - go mod vendor -.PHONY: vendor +SRC_PKGS := apis client cmd contrib deploy docs examples guides hack pkg test # directories which hold app source excluding tests (not vendored) +SRC_DIRS := $(SRC_PKGS) # directories which hold app source (not vendored) -tools: $(GOLANGCI_LINT) $(CONTROLLER_GEN) $(YAML_PATCH) $(GOTESTSUM) $(OPENSHIFT_GOIMPORTS) -.PHONY: tools +DOCKER_PLATFORMS := linux/amd64 linux/arm64 +BIN_PLATFORMS := $(DOCKER_PLATFORMS) -$(CONTROLLER_GEN): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) sigs.k8s.io/controller-tools/cmd/controller-gen $(CONTROLLER_GEN_BIN) $(CONTROLLER_GEN_VER) +# Used internally. Users should pass GOOS and/or GOARCH. +OS := $(if $(GOOS),$(GOOS),$(shell go env GOOS)) +ARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH)) -$(YAML_PATCH): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/pivotal-cf/yaml-patch/cmd/yaml-patch $(YAML_PATCH_BIN) $(YAML_PATCH_VER) +# BASEIMAGE_PROD ?= gcr.io/distroless/static-debian12 +BASEIMAGE_PROD ?= alpine +BASEIMAGE_DBG ?= debian:bookworm -$(GOTESTSUM): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) gotest.tools/gotestsum $(GOTESTSUM_BIN) $(GOTESTSUM_VER) +IMAGE := $(REGISTRY)/$(BIN) +VERSION_PROD := $(VERSION) +VERSION_DBG := $(VERSION)-dbg +TAG := $(VERSION)_$(OS)_$(ARCH) +TAG_PROD := $(TAG) +TAG_DBG := $(VERSION)-dbg_$(OS)_$(ARCH) -codegen: $(CONTROLLER_GEN) $(YAML_PATCH) ## Run the codegenerators - go mod download - ./hack/update-codegen.sh - $(MAKE) imports -.PHONY: codegen +GO_VERSION ?= 1.21 +BUILD_IMAGE ?= ghcr.io/appscode/golang-dev:$(GO_VERSION) +CHART_TEST_IMAGE ?= quay.io/helmpack/chart-testing:v3.5.1 -# Note, running this locally if you have any modified files, even those that are not generated, -# will result in an error. This target is mostly for CI jobs. -.PHONY: verify-codegen -verify-codegen: - if [[ -n "${GITHUB_WORKSPACE}" ]]; then \ - mkdir -p $$(go env GOPATH)/src/github.com/kube-bind; \ - ln -s ${GITHUB_WORKSPACE} $$(go env GOPATH)/src/go.bytebuilders.dev/kube-bind; \ - fi +OUTBIN = bin/$(BIN)-$(OS)-$(ARCH) +ifeq ($(OS),windows) + OUTBIN := bin/$(BIN)-$(OS)-$(ARCH).exe + BIN := $(BIN).exe +endif - $(MAKE) codegen +# Directories that we need created to build/test. +BUILD_DIRS := bin/$(OS)_$(ARCH) \ + .go/bin/$(OS)_$(ARCH) \ + .go/cache \ + hack/config \ + $(HOME)/.credentials \ + $(HOME)/.kube + +DOCKERFILE_PROD = Dockerfile.in +DOCKERFILE_DBG = Dockerfile.dbg + +DOCKER_REPO_ROOT := /go/src/$(GO_PKG)/$(REPO) + +# If you want to build all binaries, see the 'all-build' rule. +# If you want to build all containers, see the 'all-container' rule. +# If you want to build AND push all containers, see the 'all-push' rule. +all: fmt build + +# For the following OS/ARCH expansions, we transform OS/ARCH into OS_ARCH +# because make pattern rules don't match with embedded '/' characters. + +build-%: + @$(MAKE) build \ + --no-print-directory \ + GOOS=$(firstword $(subst _, ,$*)) \ + GOARCH=$(lastword $(subst _, ,$*)) + +container-%: + @$(MAKE) container \ + --no-print-directory \ + GOOS=$(firstword $(subst _, ,$*)) \ + GOARCH=$(lastword $(subst _, ,$*)) + +push-%: + @$(MAKE) push \ + --no-print-directory \ + GOOS=$(firstword $(subst _, ,$*)) \ + GOARCH=$(lastword $(subst _, ,$*)) + +all-build: $(addprefix build-, $(subst /,_, $(BIN_PLATFORMS))) +ifeq ($(COMPRESS),yes) + @cd bin; \ + sha256sum $(patsubst $(BIN)-windows-%.tar.gz,$(BIN)-windows-%.zip, $(addsuffix .tar.gz, $(addprefix $(BIN)-, $(subst /,-, $(BIN_PLATFORMS))))) > $(BIN)-checksums.txt +endif - if ! git diff --quiet HEAD; then \ - git diff; \ - echo "You need to run 'make codegen' to update generated files and commit them"; \ - exit 1; \ +all-container: $(addprefix container-, $(subst /,_, $(DOCKER_PLATFORMS))) + +all-push: $(addprefix push-, $(subst /,_, $(DOCKER_PLATFORMS))) + +version: + @echo version=$(VERSION) + @echo version_strategy=$(version_strategy) + @echo git_tag=$(git_tag) + @echo git_branch=$(git_branch) + @echo commit_hash=$(commit_hash) + @echo commit_timestamp=$(commit_timestamp) + +# Generate code for Kubernetes types +.PHONY: clientset +clientset: + @docker run --rm \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(CODE_GENERATOR_IMAGE) \ + /go/src/k8s.io/code-generator/generate-groups.sh \ + "client,deepcopy,informer,lister" \ + $(GO_PKG)/$(REPO)/client \ + $(GO_PKG)/$(REPO)/apis \ + "$(API_GROUPS)" \ + --go-header-file "./hack/license/go.txt" + +# Generate openapi schema +.PHONY: openapi +openapi: $(addprefix openapi-, $(subst :,_, $(API_GROUPS))) +openapi-%: + @echo "Generating openapi schema for $(subst _,/,$*)" + @mkdir -p .config/api-rules + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(CODE_GENERATOR_IMAGE) \ + openapi-gen \ + --v 1 --logtostderr \ + --go-header-file "./hack/license/go.txt" \ + --input-dirs "$(GO_PKG)/$(REPO)/apis/$(subst _,/,$*),k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/api/resource,k8s.io/apimachinery/pkg/runtime,k8s.io/apimachinery/pkg/util/intstr,k8s.io/apimachinery/pkg/version,k8s.io/api/core/v1,k8s.io/api/apps/v1,k8s.io/api/rbac/v1,kmodules.xyz/client-go/api/v1" \ + --output-package "$(GO_PKG)/$(REPO)/apis/$(subst _,/,$*)" \ + --report-filename .config/api-rules/violation_exceptions.list + +# Generate CRD manifests +.PHONY: gen-crds +gen-crds: + @echo "Generating CRD manifests" + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(CODE_GENERATOR_IMAGE) \ + controller-gen \ + $(CRD_OPTIONS) \ + paths="./apis/..." \ + output:crd:artifacts:config=crds + +.PHONY: manifests +manifests: gen-crds + +.PHONY: gen +gen: clientset manifests # openapi + +fmt: $(BUILD_DIRS) + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + /bin/bash -c " \ + REPO_PKG=$(GO_PKG) \ + ./hack/fmt.sh $(SRC_DIRS) \ + " + +build: $(OUTBIN) + +# The following structure defeats Go's (intentional) behavior to always touch +# result files, even if they have not changed. This will still run `go` but +# will not trigger further work if nothing has actually changed. + +$(OUTBIN): .go/$(OUTBIN).stamp + @true + +# This will build the binary under ./.go and update the real binary iff needed. +.PHONY: .go/$(OUTBIN).stamp +.go/$(OUTBIN).stamp: $(BUILD_DIRS) + @echo "making $(OUTBIN)" + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + /bin/bash -c " \ + PRODUCT_OWNER_NAME=$(PRODUCT_OWNER_NAME) \ + PRODUCT_NAME=$(PRODUCT_NAME) \ + ENFORCE_LICENSE=$(ENFORCE_LICENSE) \ + ARCH=$(ARCH) \ + OS=$(OS) \ + VERSION=$(VERSION) \ + version_strategy=$(version_strategy) \ + git_branch=$(git_branch) \ + git_tag=$(git_tag) \ + commit_hash=$(commit_hash) \ + commit_timestamp=$(commit_timestamp) \ + ./hack/build.sh \ + " + @if ! cmp -s .go/bin/$(OS)_$(ARCH)/$(BIN) $(OUTBIN); then \ + mv .go/bin/$(OS)_$(ARCH)/$(BIN) $(OUTBIN); \ + date >$@; \ fi +ifeq ($(COMPRESS),yes) +ifeq ($(OS),windows) + @echo "compressing $(OUTBIN)"; \ + cd bin; \ + zip -j $(subst .exe,,$(BIN))-$(OS)-$(ARCH).zip $(subst .exe,,$(BIN))-$(OS)-$(ARCH).exe ../LICENSE.md +else + @echo "compressing $(OUTBIN)"; \ + cd bin; \ + tar -czvf $(BIN)-$(OS)-$(ARCH).tar.gz $(BIN)-$(OS)-$(ARCH) ../LICENSE.md +endif +endif + @echo + +# Used to track state in hidden files. +DOTFILE_IMAGE = $(subst /,_,$(IMAGE))-$(TAG) + +container: bin/.container-$(DOTFILE_IMAGE)-PROD bin/.container-$(DOTFILE_IMAGE)-DBG +ifeq (,$(SRC_REG)) +bin/.container-$(DOTFILE_IMAGE)-%: bin/$(BIN)-$(OS)-$(ARCH) $(DOCKERFILE_%) + @echo "container: $(IMAGE):$(TAG_$*)" + @sed \ + -e 's|{ARG_BIN}|$(BIN)|g' \ + -e 's|{ARG_ARCH}|$(ARCH)|g' \ + -e 's|{ARG_OS}|$(OS)|g' \ + -e 's|{ARG_FROM}|$(BASEIMAGE_$*)|g' \ + $(DOCKERFILE_$*) > bin/.dockerfile-$*-$(OS)_$(ARCH) + @docker buildx build --platform $(OS)/$(ARCH) --load --pull -t $(IMAGE):$(TAG_$*) -f bin/.dockerfile-$*-$(OS)_$(ARCH) . + @docker images -q $(IMAGE):$(TAG_$*) > $@ + @echo +else +bin/.container-$(DOTFILE_IMAGE)-%: + @echo "container: $(IMAGE):$(TAG_$*)" + @docker tag $(SRC_REG)/$(BIN):$(TAG_$*) $(IMAGE):$(TAG_$*) + @echo +endif -$(OPENSHIFT_GOIMPORTS): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/openshift-eng/openshift-goimports $(OPENSHIFT_GOIMPORTS_BIN) $(OPENSHIFT_GOIMPORTS_VER) - -.PHONY: imports -imports: $(OPENSHIFT_GOIMPORTS) - $(OPENSHIFT_GOIMPORTS) -m go.bytebuilders.dev/kube-bind - -$(TOOLS_DIR)/verify_boilerplate.py: - mkdir -p $(TOOLS_DIR) - curl --fail --retry 3 -L -o $(TOOLS_DIR)/verify_boilerplate.py https://raw.githubusercontent.com/kubernetes/repo-infra/master/hack/verify_boilerplate.py - chmod +x $(TOOLS_DIR)/verify_boilerplate.py +push: bin/.push-$(DOTFILE_IMAGE)-PROD bin/.push-$(DOTFILE_IMAGE)-DBG +bin/.push-$(DOTFILE_IMAGE)-%: bin/.container-$(DOTFILE_IMAGE)-% + @docker push $(IMAGE):$(TAG_$*) + @echo "pushed: $(IMAGE):$(TAG_$*)" + @echo -.PHONY: verify-boilerplate -verify-boilerplate: $(TOOLS_DIR)/verify_boilerplate.py - $(TOOLS_DIR)/verify_boilerplate.py --boilerplate-dir=hack/boilerplate --skip dex +.PHONY: docker-manifest +docker-manifest: docker-manifest-PROD docker-manifest-DBG +docker-manifest-%: + docker manifest create -a $(IMAGE):$(VERSION_$*) $(foreach PLATFORM,$(DOCKER_PLATFORMS),$(IMAGE):$(VERSION_$*)_$(subst /,_,$(PLATFORM))) + docker manifest push $(IMAGE):$(VERSION_$*) -ifdef ARTIFACT_DIR -GOTESTSUM_ARGS += --junitfile=$(ARTIFACT_DIR)/junit.xml -endif +.PHONY: test +test: unit-tests e2e-tests + +unit-tests: $(BUILD_DIRS) + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + /bin/bash -c " \ + ARCH=$(ARCH) \ + OS=$(OS) \ + VERSION=$(VERSION) \ + ./hack/test.sh $(SRC_PKGS) \ + " + +# - e2e-tests can hold both ginkgo args (as GINKGO_ARGS) and program/test args (as TEST_ARGS). +# make e2e-tests TEST_ARGS="--selfhosted-operator=false --storageclass=standard" GINKGO_ARGS="--flakeAttempts=2" +# +# - Minimalist: +# make e2e-tests +# +# NB: -t is used to catch ctrl-c interrupt from keyboard and -t will be problematic for CI. + +GINKGO_ARGS ?= +TEST_ARGS ?= + +.PHONY: e2e-tests +e2e-tests: $(BUILD_DIRS) + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + --net=host \ + -v $(HOME)/.kube:/.kube \ + -v $(HOME)/.minikube:$(HOME)/.minikube \ + -v $(HOME)/.credentials:$(HOME)/.credentials \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + --env KUBECONFIG=$(KUBECONFIG) \ + --env-file=$$(pwd)/hack/config/.env \ + $(BUILD_IMAGE) \ + /bin/bash -c " \ + ARCH=$(ARCH) \ + OS=$(OS) \ + VERSION=$(VERSION) \ + DOCKER_REGISTRY=$(REGISTRY) \ + TAG=$(TAG) \ + KUBECONFIG=$${KUBECONFIG#$(HOME)} \ + GINKGO_ARGS='$(GINKGO_ARGS)' \ + TEST_ARGS='$(TEST_ARGS)' \ + ./hack/e2e.sh \ + " + +.PHONY: e2e-parallel +e2e-parallel: + @$(MAKE) e2e-tests GINKGO_ARGS="-p -stream --flakeAttempts=2" --no-print-directory + +ADDTL_LINTERS := gofmt,goimports,unparam -GO_TEST = go test -ifdef USE_GOTESTSUM -GO_TEST = $(GOTESTSUM) $(GOTESTSUM_ARGS) -- +.PHONY: lint +lint: $(BUILD_DIRS) + @echo "running linter" + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + --env GOFLAGS="-mod=vendor" \ + $(BUILD_IMAGE) \ + golangci-lint run --enable $(ADDTL_LINTERS) --max-same-issues=100 --timeout=10m --skip-files="generated.*\.go$\" --skip-dirs-use-default --skip-dirs=client,vendor + +$(BUILD_DIRS): + @mkdir -p $@ + +KUBE_NAMESPACE ?= kubeops +REGISTRY_SECRET ?= +IMAGE_PULL_POLICY ?= IfNotPresent + +ifeq ($(strip $(REGISTRY_SECRET)),) + IMAGE_PULL_SECRETS = +else + IMAGE_PULL_SECRETS = --set imagePullSecrets[0].name=$(REGISTRY_SECRET) endif -COUNT ?= 1 -E2E_PARALLELISM ?= 1 - -dex: - git clone https://github.com/dexidp/dex.git -dex/bin/dex: dex - cd dex - make - -$(DEX): - mkdir -p $(TOOLS_DIR) - git clone --branch $(DEX_VER) --depth 1 https://github.com/dexidp/dex $(TOOLS_DIR)/dex-clone-$(DEX_VER) - cd $(TOOLS_DIR)/dex-clone-$(DEX_VER) && make build - cp -a $(TOOLS_DIR)/dex-clone-$(DEX_VER)/bin/dex $(DEX) - -$(KCP): - mkdir -p $(TOOLS_DIR) - curl --fail --retry 3 -L "https://github.com/kcp-dev/kcp/releases/download/$(KCP_VER)/kcp_$(KCP_VER:v%=%)_$(OS)_$(ARCH).tar.gz" | \ - tar xz -C "$(TOOLS_DIR)" --strip-components="1" bin/kcp - mv $(TOOLS_DIR)/kcp $(KCP) - -.PHONY: test-e2e -ifdef USE_GOTESTSUM -test-e2e: $(GOTESTSUM) -endif -test-e2e: TEST_ARGS ?= -test-e2e: WORK_DIR ?= . -test-e2e: WHAT ?= ./test/e2e... -test-e2e: $(KCP) $(DEX) build-all - mkdir .kcp - $(DEX) serve hack/dex-config-dev.yaml 2>&1 & DEX_PID=$$!; \ - $(KCP) start &>.kcp/kcp.log & KCP_PID=$$!; \ - trap 'kill -TERM $$DEX_PID $$KCP_PID; rm -rf .kcp' TERM INT EXIT && \ - echo "Waiting for kcp to be ready (check .kcp/kcp.log)." && while ! KUBECONFIG=.kcp/admin.kubeconfig kubectl get --raw /readyz &>/dev/null; do sleep 1; echo -n "."; done && echo && \ - KUBECONFIG=$$PWD/.kcp/admin.kubeconfig GOOS=$(OS) GOARCH=$(ARCH) $(GO_TEST) -race -count $(COUNT) -p $(E2E_PARALLELISM) -parallel $(E2E_PARALLELISM) $(WHAT) $(TEST_ARGS) +.PHONY: dev +dev: gen fmt push -.PHONY: test -ifdef USE_GOTESTSUM -test: $(GOTESTSUM) -endif -test: WHAT ?= ./... -# We will need to move into the sub package, of pkg/apis to run those tests. -test: ## run unit tests - $(GO_TEST) -race -count $(COUNT) -coverprofile=coverage.txt -covermode=atomic $(TEST_ARGS) $$(go list "$(WHAT)" | grep -v ./test/e2e/) - cd pkg/apis && $(GO_TEST) -race -count $(COUNT) -coverprofile=coverage.txt -covermode=atomic $(TEST_ARGS) $(WHAT) - -.PHONY: verify-imports -verify-imports: - hack/verify-imports.sh - -.PHONY: verify-go-versions -verify-go-versions: - hack/verify-go-versions.sh - -.PHONY: modules -modules: ## Run go mod tidy to ensure modules are up to date - go mod tidy - cd pkg/apis; go mod tidy +.PHONY: verify +verify: verify-gen verify-modules .PHONY: verify-modules -verify-modules: modules # Verify go modules are up to date - @if !(git diff --quiet HEAD -- go.sum go.mod pkg/apis/go.mod pkg/apis/go.sum); then \ - git diff; \ +verify-modules: + go mod tidy + go mod vendor + @if !(git diff --exit-code HEAD); then \ echo "go module files are out of date"; exit 1; \ fi -.PHONY: verify -verify: verify-modules verify-go-versions verify-imports verify-codegen verify-boilerplate ## verify formal properties of the code +.PHONY: verify-gen +verify-gen: gen fmt + @if !(git diff --exit-code HEAD); then \ + echo "generated files are out of date, run make gen fmt"; exit 1; \ + fi + +.PHONY: add-license +add-license: + @echo "Adding license header" + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + ltag -t "./hack/license" --excludes "vendor bin" -v + +.PHONY: check-license +check-license: + @echo "Checking files have proper license header" + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + ltag -t "./hack/license" --excludes "vendor bin" --check -v + +.PHONY: ci +ci: verify check-license lint build unit-tests #cover + +.PHONY: qa +qa: + @if [ "$$APPSCODE_ENV" = "prod" ]; then \ + echo "Nothing to do in prod env. Are you trying to 'release' binaries to prod?"; \ + exit 1; \ + fi + @if [ "$(version_strategy)" = "tag" ]; then \ + echo "Are you trying to 'release' binaries to prod?"; \ + exit 1; \ + fi + @$(MAKE) clean all-build all-push docker-manifest --no-print-directory -.PHONY: help -help: ## Show this help. - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' +.PHONY: release +release: + @if [ "$$APPSCODE_ENV" != "prod" ]; then \ + echo "'release' only works in PROD env."; \ + exit 1; \ + fi + @if [ "$(version_strategy)" != "tag" ]; then \ + echo "apply tag to release binaries and/or docker images."; \ + exit 1; \ + fi + @$(MAKE) clean all-build all-push docker-manifest --no-print-directory + +.PHONY: clean +clean: + rm -rf .go bin + +.PHONY: push-to-kind +push-to-kind: container + @echo "Loading docker image into kind cluster...." + @kind load docker-image $(IMAGE):$(TAG_PROD) + @echo "Image has been pushed successfully into kind cluster." + +.PHONY: gen-krew-manifest +gen-krew-manifest: + @if [ "$(version_strategy)" != "tag" ]; then \ + echo "apply tag to generate krew manifest."; \ + exit 1; \ + fi + @sed \ + -e 's|{VERSION}|$(VERSION)|g' \ + -e 's|{SHA256SUM_DARWIN_AMD64}|$(shell sha256sum bin/$(BIN)-darwin-amd64.tar.gz | cut -d' ' -f1)|g' \ + -e 's|{SHA256SUM_DARWIN_ARM64}|$(shell sha256sum bin/$(BIN)-darwin-arm64.tar.gz | cut -d' ' -f1)|g' \ + -e 's|{SHA256SUM_LINUX_AMD64}|$(shell sha256sum bin/$(BIN)-linux-amd64.tar.gz | cut -d' ' -f1)|g' \ + -e 's|{SHA256SUM_LINUX_ARM}|$(shell sha256sum bin/$(BIN)-linux-arm.tar.gz | cut -d' ' -f1)|g' \ + -e 's|{SHA256SUM_LINUX_ARM64}|$(shell sha256sum bin/$(BIN)-linux-arm64.tar.gz | cut -d' ' -f1)|g' \ + -e 's|{SHA256SUM_WINDOWS_AMD64}|$(shell sha256sum bin/$(BIN)-windows-amd64.zip | cut -d' ' -f1)|g' \ + hack/krew/plugin.yaml diff --git a/OWNERS b/OWNERS deleted file mode 100644 index 8c2bcd2b..00000000 --- a/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -approvers: -- moadqassem -- pkbhowmick -- s-urbaniak -- sttts -- lhaendler diff --git a/README.md b/README.md index 1e71fbc9..95fb8a3f 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,24 @@ # kube-bind -### Disclaimer: work in progress and not ready for production use. - -You are invited to [contribute](#contributing)! - ## What is it? -kube-bind is a prototype project that aims to provide better support for service providers and consumers that reside in distinct Kubernetes clusters. +kube-bind is a project that aims to provide better support for service providers and consumers that reside in distinct Kubernetes clusters. The code in this repo has been forked from the [kube-bind](https://github.com/kube-bind/kube-bind) project. - A service provider defines its API in terms of CRDs and associated permission claims/limitations, and exports it for use from other clusters. - Service consumers identify the services they want to consume. - The service CRDs get installed in the service consumer clusters, with objects of the defined kinds written and read by the service consumers. - The service provider indirectly reads and writes those objects as the interface to the service that it provides. - The service provider does not inject controllers/operators into the service consumer's cluster. -- A single vendor-neutral, OpenSource agent per consumer cluster connects it with the requested services. ## Try it out This is the 3 line pitch: ```shell -$ kubectl krew index add bind https://github.com/kube-bind/krew-index.git -$ kubectl krew install bind/bind -$ kubectl bind https://mangodb/exports +$ kubectl krew index add bind https://github.com/appscode/krew-index.git +$ kubectl krew install appscode/connect +$ kubectl connect https://mangodb/exports Redirect to the brower to authenticate via OIDC. BOOM – the MangoDB API is available in the local cluster, without anything MangoDB-specific running. @@ -40,18 +35,6 @@ The kube-bind prototype is following this manifesto from the linked talk: ![kube-bind manifesto](docs/images/manifesto.png) -## Contributing - -We ❤️ our contributors! If you're interested in helping us out, please check out -[Contributing to kube-bind](./CONTRIBUTING.md) and [kube-bind Project Governance](./GOVERNANCE.md). - -## Getting in touch - -There are several ways to communicate with us: - -- The [`#kube-bind` channel](https://kubernetes.slack.com/archives/C046PRXNJ4W) in the [Kubernetes Slack workspace](https://slack.k8s.io) -- Our mailing list [kube-bind-dev](https://groups.google.com/g/kube-bind-dev) for development discussions. - ## Technical Overview overview @@ -111,3 +94,8 @@ The `--cookie-signing-key` option is required and supports 32 and 64 byte length The `--cookie-encryption-key` option is optional and supports byte lengths of 16, 24, 32 for AES-128, AES-192, or AES-256. * with a KUBECONFIG against another cluster (a consumer cluster) bind a service: `kubectl bind http://127.0.0.1:8080/export`. + +## Copyright + +Copyright 2022-2023 The Kube Bind Authors. +Copyright 2024 AppsCode Inc. and Contributors. diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 81fd55bc..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,3 +0,0 @@ -# Security Process for kube-bind - -TBD diff --git a/pkg/apis/kubebind/v1alpha1/apiservicebinding_types.go b/apis/kubebind/v1alpha1/apiservicebinding_types.go similarity index 93% rename from pkg/apis/kubebind/v1alpha1/apiservicebinding_types.go rename to apis/kubebind/v1alpha1/apiservicebinding_types.go index 299a4601..41c53a45 100644 --- a/pkg/apis/kubebind/v1alpha1/apiservicebinding_types.go +++ b/apis/kubebind/v1alpha1/apiservicebinding_types.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,9 +17,14 @@ limitations under the License. package v1alpha1 import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" conditionsapi "kmodules.xyz/client-go/api/v1" +) - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +const ( + ResourceKindAPIServiceBinding = "APIServiceBinding" + ResourceAPIServiceBinding = "apiservicebinding" + ResourceAPIServiceBindings = "apiservicebindings" ) const ( diff --git a/pkg/apis/kubebind/v1alpha1/apiserviceexport_types.go b/apis/kubebind/v1alpha1/apiserviceexport_types.go similarity index 96% rename from pkg/apis/kubebind/v1alpha1/apiserviceexport_types.go rename to apis/kubebind/v1alpha1/apiserviceexport_types.go index 5fe7cf01..7f4cbe0d 100644 --- a/pkg/apis/kubebind/v1alpha1/apiserviceexport_types.go +++ b/apis/kubebind/v1alpha1/apiserviceexport_types.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,11 +17,16 @@ limitations under the License. package v1alpha1 import ( - conditionsapi "kmodules.xyz/client-go/api/v1" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + conditionsapi "kmodules.xyz/client-go/api/v1" +) + +const ( + ResourceKindAPIServiceExport = "APIServiceExport" + ResourceAPIServiceExport = "apiserviceexport" + ResourceAPIServiceExports = "apiserviceexports" ) const ( diff --git a/pkg/apis/kubebind/v1alpha1/apiserviceexportrequest_types.go b/apis/kubebind/v1alpha1/apiserviceexportrequest_types.go similarity index 94% rename from pkg/apis/kubebind/v1alpha1/apiserviceexportrequest_types.go rename to apis/kubebind/v1alpha1/apiserviceexportrequest_types.go index 3668b488..c78d8eb0 100644 --- a/pkg/apis/kubebind/v1alpha1/apiserviceexportrequest_types.go +++ b/apis/kubebind/v1alpha1/apiserviceexportrequest_types.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,10 +17,15 @@ limitations under the License. package v1alpha1 import ( - conditionsapi "kmodules.xyz/client-go/api/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + conditionsapi "kmodules.xyz/client-go/api/v1" +) + +const ( + ResourceKindAPIServiceExportRequest = "APIServiceExportRequest" + ResourceAPIServiceExportRequest = "apiserviceexportrequest" + ResourceAPIServiceExportRequests = "apiserviceexportrequests" ) const ( diff --git a/pkg/apis/kubebind/v1alpha1/apiservicenamespace_types.go b/apis/kubebind/v1alpha1/apiservicenamespace_types.go similarity index 83% rename from pkg/apis/kubebind/v1alpha1/apiservicenamespace_types.go rename to apis/kubebind/v1alpha1/apiservicenamespace_types.go index 7b973f10..04def079 100644 --- a/pkg/apis/kubebind/v1alpha1/apiservicenamespace_types.go +++ b/apis/kubebind/v1alpha1/apiservicenamespace_types.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,6 +20,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +const ( + ResourceKindAPIServiceNamespace = "APIServiceNamespace" + ResourceAPIServiceNamespace = "apiservicenamespace" + ResourceAPIServiceNamespaces = "apiservicenamespaces" +) + const ( APIServiceNamespaceAnnotationKey = "kube-bind.appscode.com/api-service-namespace" ) @@ -49,8 +55,7 @@ type APIServiceNamespace struct { Status APIServiceNamespaceStatus `json:"status,omitempty"` } -type APIServiceNamespaceSpec struct { -} +type APIServiceNamespaceSpec struct{} type APIServiceNamespaceStatus struct { // namespace is the service provider namespace name that will be bound to the diff --git a/pkg/apis/kubebind/v1alpha1/bindingprovider_types.go b/apis/kubebind/v1alpha1/bindingprovider_types.go similarity index 93% rename from pkg/apis/kubebind/v1alpha1/bindingprovider_types.go rename to apis/kubebind/v1alpha1/bindingprovider_types.go index f2ef5352..7dbc41f2 100644 --- a/pkg/apis/kubebind/v1alpha1/bindingprovider_types.go +++ b/apis/kubebind/v1alpha1/bindingprovider_types.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/apis/kubebind/v1alpha1/bindingresponse_types.go b/apis/kubebind/v1alpha1/bindingresponse_types.go similarity index 93% rename from pkg/apis/kubebind/v1alpha1/bindingresponse_types.go rename to apis/kubebind/v1alpha1/bindingresponse_types.go index ac04bcbc..3c98794f 100644 --- a/pkg/apis/kubebind/v1alpha1/bindingresponse_types.go +++ b/apis/kubebind/v1alpha1/bindingresponse_types.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/apis/kubebind/v1alpha1/clusterbinding_types.go b/apis/kubebind/v1alpha1/clusterbinding_types.go similarity index 94% rename from pkg/apis/kubebind/v1alpha1/clusterbinding_types.go rename to apis/kubebind/v1alpha1/clusterbinding_types.go index 13fb47db..ae8b30f0 100644 --- a/pkg/apis/kubebind/v1alpha1/clusterbinding_types.go +++ b/apis/kubebind/v1alpha1/clusterbinding_types.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,10 +17,15 @@ limitations under the License. package v1alpha1 import ( - conditionsapi "kmodules.xyz/client-go/api/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + conditionsapi "kmodules.xyz/client-go/api/v1" +) + +const ( + ResourceKindClusterBinding = "ClusterBinding" + ResourceClusterBinding = "clusterbinding" + ResourceClusterBindings = "clusterbindings" ) const ( diff --git a/apis/kubebind/v1alpha1/crds.go b/apis/kubebind/v1alpha1/crds.go new file mode 100644 index 00000000..a9aa03b2 --- /dev/null +++ b/apis/kubebind/v1alpha1/crds.go @@ -0,0 +1,43 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the AppsCode Community License 1.0.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md + +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. +*/ + +package v1alpha1 + +import ( + "go.bytebuilders.dev/kube-bind/crds" + + "kmodules.xyz/client-go/apiextensions" +) + +func (_ APIServiceExport) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { + return crds.MustCustomResourceDefinition(SchemeGroupVersion.WithResource(ResourceAPIServiceExports)) +} + +func (_ APIServiceBinding) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { + return crds.MustCustomResourceDefinition(SchemeGroupVersion.WithResource(ResourceAPIServiceBindings)) +} + +func (_ APIServiceExportRequest) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { + return crds.MustCustomResourceDefinition(SchemeGroupVersion.WithResource(ResourceAPIServiceExportRequests)) +} + +func (_ APIServiceNamespace) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { + return crds.MustCustomResourceDefinition(SchemeGroupVersion.WithResource(ResourceAPIServiceNamespaces)) +} + +func (_ ClusterBinding) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { + return crds.MustCustomResourceDefinition(SchemeGroupVersion.WithResource(ResourceClusterBindings)) +} diff --git a/pkg/apis/kubebind/v1alpha1/doc.go b/apis/kubebind/v1alpha1/doc.go similarity index 77% rename from pkg/apis/kubebind/v1alpha1/doc.go rename to apis/kubebind/v1alpha1/doc.go index c786acfa..691fb847 100644 --- a/pkg/apis/kubebind/v1alpha1/doc.go +++ b/apis/kubebind/v1alpha1/doc.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/apis/kubebind/v1alpha1/helpers/crd.go b/apis/kubebind/v1alpha1/helpers/crd.go similarity index 75% rename from pkg/apis/kubebind/v1alpha1/helpers/crd.go rename to apis/kubebind/v1alpha1/helpers/crd.go index f52e2119..8a9c7e5f 100644 --- a/pkg/apis/kubebind/v1alpha1/helpers/crd.go +++ b/apis/kubebind/v1alpha1/helpers/crd.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,10 +19,10 @@ package helpers import ( "strings" - "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ) func IsOwnedByBinding(name string, uid types.UID, refs []v1.OwnerReference) bool { diff --git a/pkg/apis/kubebind/v1alpha1/helpers/serviceexport.go b/apis/kubebind/v1alpha1/helpers/serviceexport.go similarity index 94% rename from pkg/apis/kubebind/v1alpha1/helpers/serviceexport.go rename to apis/kubebind/v1alpha1/helpers/serviceexport.go index 532b442a..063ceb71 100644 --- a/pkg/apis/kubebind/v1alpha1/helpers/serviceexport.go +++ b/apis/kubebind/v1alpha1/helpers/serviceexport.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,12 +22,12 @@ import ( "fmt" "math/big" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime2 "k8s.io/apimachinery/pkg/util/runtime" "sigs.k8s.io/yaml" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // ServiceExportToCRD converts a APIServiceExport to a CRD. diff --git a/pkg/apis/kubebind/v1alpha1/helpers/serviceexport_test.go b/apis/kubebind/v1alpha1/helpers/serviceexport_test.go similarity index 86% rename from pkg/apis/kubebind/v1alpha1/helpers/serviceexport_test.go rename to apis/kubebind/v1alpha1/helpers/serviceexport_test.go index 734c8edb..e17c154e 100644 --- a/pkg/apis/kubebind/v1alpha1/helpers/serviceexport_test.go +++ b/apis/kubebind/v1alpha1/helpers/serviceexport_test.go @@ -1,11 +1,11 @@ /* -Copyright 2023 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,7 +20,6 @@ import ( "testing" "github.com/stretchr/testify/require" - v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/utils/ptr" ) @@ -45,7 +44,8 @@ func TestWebhookCRDStorageVersion(t *testing.T) { Webhook: &v1.WebhookConversion{ ClientConfig: &v1.WebhookClientConfig{ URL: ptr.To("https://example.com/webhook"), - CABundle: []byte("1234")}, + CABundle: []byte("1234"), + }, }, }, }, diff --git a/pkg/apis/kubebind/v1alpha1/register.go b/apis/kubebind/v1alpha1/register.go similarity index 90% rename from pkg/apis/kubebind/v1alpha1/register.go rename to apis/kubebind/v1alpha1/register.go index 12804513..022c5804 100644 --- a/pkg/apis/kubebind/v1alpha1/register.go +++ b/apis/kubebind/v1alpha1/register.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -46,18 +46,18 @@ func Resource(resource string) schema.GroupResource { // Adds the list of known types to api.Scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &APIServiceExport{}, - &APIServiceExportList{}, &APIServiceBinding{}, &APIServiceBindingList{}, + &APIServiceExport{}, + &APIServiceExportList{}, &APIServiceExportRequest{}, &APIServiceExportRequestList{}, &APIServiceNamespace{}, &APIServiceNamespaceList{}, - &ClusterBinding{}, - &ClusterBindingList{}, &BindingProvider{}, &BindingResponse{}, + &ClusterBinding{}, + &ClusterBindingList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/pkg/apis/kubebind/v1alpha1/zz_generated.deepcopy.go b/apis/kubebind/v1alpha1/zz_generated.deepcopy.go similarity index 99% rename from pkg/apis/kubebind/v1alpha1/zz_generated.deepcopy.go rename to apis/kubebind/v1alpha1/zz_generated.deepcopy.go index a3147be2..a3aca6a9 100644 --- a/pkg/apis/kubebind/v1alpha1/zz_generated.deepcopy.go +++ b/apis/kubebind/v1alpha1/zz_generated.deepcopy.go @@ -2,13 +2,13 @@ // +build !ignore_autogenerated /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,10 +22,9 @@ limitations under the License. package v1alpha1 import ( - v1 "kmodules.xyz/client-go/api/v1" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" runtime "k8s.io/apimachinery/pkg/runtime" + v1 "kmodules.xyz/client-go/api/v1" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. diff --git a/pkg/client/clientset/versioned/clientset.go b/client/clientset/versioned/clientset.go similarity index 92% rename from pkg/client/clientset/versioned/clientset.go rename to client/clientset/versioned/clientset.go index 5e78d681..42398b71 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/client/clientset/versioned/clientset.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,11 +22,11 @@ import ( "fmt" "net/http" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/client/clientset/versioned/typed/kubebind/v1alpha1" + discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/typed/kubebind/v1alpha1" ) type Interface interface { diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/client/clientset/versioned/fake/clientset_generated.go similarity index 83% rename from pkg/client/clientset/versioned/fake/clientset_generated.go rename to client/clientset/versioned/fake/clientset_generated.go index 733f1e91..8f738510 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/client/clientset/versioned/fake/clientset_generated.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,15 +19,15 @@ limitations under the License. package fake import ( + clientset "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/client/clientset/versioned/typed/kubebind/v1alpha1" + fakekubebindv1alpha1 "go.bytebuilders.dev/kube-bind/client/clientset/versioned/typed/kubebind/v1alpha1/fake" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" fakediscovery "k8s.io/client-go/discovery/fake" "k8s.io/client-go/testing" - - clientset "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/typed/kubebind/v1alpha1" - fakekubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake" ) // NewSimpleClientset returns a clientset that will respond with the provided objects. diff --git a/client/clientset/versioned/fake/doc.go b/client/clientset/versioned/fake/doc.go new file mode 100644 index 00000000..79b18da7 --- /dev/null +++ b/client/clientset/versioned/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the AppsCode Community License 1.0.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/pkg/client/clientset/versioned/fake/register.go b/client/clientset/versioned/fake/register.go similarity index 86% rename from pkg/client/clientset/versioned/fake/register.go rename to client/clientset/versioned/fake/register.go index 90ad36fb..e55662ce 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/client/clientset/versioned/fake/register.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,13 +19,13 @@ limitations under the License. package fake import ( + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) var scheme = runtime.NewScheme() diff --git a/pkg/client/clientset/versioned/scheme/doc.go b/client/clientset/versioned/scheme/doc.go similarity index 74% rename from pkg/client/clientset/versioned/scheme/doc.go rename to client/clientset/versioned/scheme/doc.go index b5ec927c..b741aed1 100644 --- a/pkg/client/clientset/versioned/scheme/doc.go +++ b/client/clientset/versioned/scheme/doc.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/client/clientset/versioned/scheme/register.go b/client/clientset/versioned/scheme/register.go similarity index 86% rename from pkg/client/clientset/versioned/scheme/register.go rename to client/clientset/versioned/scheme/register.go index afde65bc..241f9af3 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/client/clientset/versioned/scheme/register.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,13 +19,13 @@ limitations under the License. package scheme import ( + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) var Scheme = runtime.NewScheme() diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicebinding.go b/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicebinding.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicebinding.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/apiservicebinding.go index cfc47b90..983b621e 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicebinding.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicebinding.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,13 +22,13 @@ import ( "context" "time" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + scheme "go.bytebuilders.dev/kube-bind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - scheme "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/scheme" ) // APIServiceBindingsGetter has a method to return a APIServiceBindingInterface. diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexport.go b/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexport.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexport.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexport.go index 152681ae..97e87109 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexport.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexport.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,13 +22,13 @@ import ( "context" "time" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + scheme "go.bytebuilders.dev/kube-bind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - scheme "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/scheme" ) // APIServiceExportsGetter has a method to return a APIServiceExportInterface. diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexportrequest.go b/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexportrequest.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexportrequest.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexportrequest.go index 35804998..eaeda2f6 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexportrequest.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/apiserviceexportrequest.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,13 +22,13 @@ import ( "context" "time" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + scheme "go.bytebuilders.dev/kube-bind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - scheme "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/scheme" ) // APIServiceExportRequestsGetter has a method to return a APIServiceExportRequestInterface. diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicenamespace.go b/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicenamespace.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicenamespace.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/apiservicenamespace.go index ba54abef..8e0a14cb 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicenamespace.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/apiservicenamespace.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,13 +22,13 @@ import ( "context" "time" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + scheme "go.bytebuilders.dev/kube-bind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - scheme "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/scheme" ) // APIServiceNamespacesGetter has a method to return a APIServiceNamespaceInterface. diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/clusterbinding.go b/client/clientset/versioned/typed/kubebind/v1alpha1/clusterbinding.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/clusterbinding.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/clusterbinding.go index b38ee878..08a2d16b 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/clusterbinding.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/clusterbinding.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,13 +22,13 @@ import ( "context" "time" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + scheme "go.bytebuilders.dev/kube-bind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - scheme "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/scheme" ) // ClusterBindingsGetter has a method to return a ClusterBindingInterface. diff --git a/client/clientset/versioned/typed/kubebind/v1alpha1/doc.go b/client/clientset/versioned/typed/kubebind/v1alpha1/doc.go new file mode 100644 index 00000000..bfb6bb78 --- /dev/null +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the AppsCode Community License 1.0.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/client/clientset/versioned/typed/kubebind/v1alpha1/fake/doc.go b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/doc.go new file mode 100644 index 00000000..c4c35e4c --- /dev/null +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the AppsCode Community License 1.0.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicebinding.go b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicebinding.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicebinding.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicebinding.go index cae398bd..8c194366 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicebinding.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicebinding.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,13 +21,13 @@ package fake import ( "context" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // FakeAPIServiceBindings implements APIServiceBindingInterface diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexport.go b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexport.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexport.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexport.go index 7bede6a5..77bca648 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexport.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexport.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,13 +21,13 @@ package fake import ( "context" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // FakeAPIServiceExports implements APIServiceExportInterface diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexportrequest.go b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexportrequest.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexportrequest.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexportrequest.go index c240dbd6..402d992a 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexportrequest.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiserviceexportrequest.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,13 +21,13 @@ package fake import ( "context" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // FakeAPIServiceExportRequests implements APIServiceExportRequestInterface diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicenamespace.go b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicenamespace.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicenamespace.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicenamespace.go index 469546c2..55f5a3e1 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicenamespace.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_apiservicenamespace.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,13 +21,13 @@ package fake import ( "context" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // FakeAPIServiceNamespaces implements APIServiceNamespaceInterface diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_clusterbinding.go b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_clusterbinding.go similarity index 95% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_clusterbinding.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_clusterbinding.go index ee0a92f9..908644bf 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_clusterbinding.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_clusterbinding.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,13 +21,13 @@ package fake import ( "context" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/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" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // FakeClusterBindings implements ClusterBindingInterface diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_kubebind_client.go b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_kubebind_client.go similarity index 84% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_kubebind_client.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_kubebind_client.go index 61ee81a1..02aa9b5b 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_kubebind_client.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/fake/fake_kubebind_client.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,10 +19,10 @@ limitations under the License. package fake import ( + v1alpha1 "go.bytebuilders.dev/kube-bind/client/clientset/versioned/typed/kubebind/v1alpha1" + rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/typed/kubebind/v1alpha1" ) type FakeKubeBindV1alpha1 struct { diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/generated_expansion.go b/client/clientset/versioned/typed/kubebind/v1alpha1/generated_expansion.go similarity index 79% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/generated_expansion.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/generated_expansion.go index 3b60d85b..a9de782f 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/generated_expansion.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/generated_expansion.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/kubebind_client.go b/client/clientset/versioned/typed/kubebind/v1alpha1/kubebind_client.go similarity index 91% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/kubebind_client.go rename to client/clientset/versioned/typed/kubebind/v1alpha1/kubebind_client.go index 62c684c2..da279d73 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/kubebind_client.go +++ b/client/clientset/versioned/typed/kubebind/v1alpha1/kubebind_client.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,10 +21,10 @@ package v1alpha1 import ( "net/http" - rest "k8s.io/client-go/rest" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/client/clientset/versioned/scheme" - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" ) type KubeBindV1alpha1Interface interface { diff --git a/pkg/client/informers/externalversions/factory.go b/client/informers/externalversions/factory.go similarity index 95% rename from pkg/client/informers/externalversions/factory.go rename to client/informers/externalversions/factory.go index a90705be..e2900ed4 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/client/informers/externalversions/factory.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,14 +23,14 @@ import ( sync "sync" time "time" + versioned "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + internalinterfaces "go.bytebuilders.dev/kube-bind/client/informers/externalversions/internalinterfaces" + kubebind "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" - - versioned "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - internalinterfaces "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/internalinterfaces" - kubebind "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind" ) // SharedInformerOption defines the functional option type for SharedInformerFactory. diff --git a/pkg/client/informers/externalversions/generic.go b/client/informers/externalversions/generic.go similarity index 91% rename from pkg/client/informers/externalversions/generic.go rename to client/informers/externalversions/generic.go index a625541a..9cd6b085 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/client/informers/externalversions/generic.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,10 +21,10 @@ package externalversions import ( "fmt" + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // GenericInformer is type of SharedIndexInformer which will locate and delegate to other diff --git a/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/client/informers/externalversions/internalinterfaces/factory_interfaces.go similarity index 82% rename from pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go rename to client/informers/externalversions/internalinterfaces/factory_interfaces.go index 0ac5395a..e2a8c919 100644 --- a/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/client/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,11 +21,11 @@ package internalinterfaces import ( time "time" + versioned "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" cache "k8s.io/client-go/tools/cache" - - versioned "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" ) // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. diff --git a/pkg/client/informers/externalversions/kubebind/interface.go b/client/informers/externalversions/kubebind/interface.go similarity index 76% rename from pkg/client/informers/externalversions/kubebind/interface.go rename to client/informers/externalversions/kubebind/interface.go index 42012b0d..e343d352 100644 --- a/pkg/client/informers/externalversions/kubebind/interface.go +++ b/client/informers/externalversions/kubebind/interface.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,8 +19,8 @@ limitations under the License. package kubebind import ( - internalinterfaces "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind/v1alpha1" + internalinterfaces "go.bytebuilders.dev/kube-bind/client/informers/externalversions/internalinterfaces" + v1alpha1 "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind/v1alpha1" ) // Interface provides access to each of this group's versions. diff --git a/pkg/client/informers/externalversions/kubebind/v1alpha1/apiservicebinding.go b/client/informers/externalversions/kubebind/v1alpha1/apiservicebinding.go similarity index 86% rename from pkg/client/informers/externalversions/kubebind/v1alpha1/apiservicebinding.go rename to client/informers/externalversions/kubebind/v1alpha1/apiservicebinding.go index 335fe8eb..e6aef4aa 100644 --- a/pkg/client/informers/externalversions/kubebind/v1alpha1/apiservicebinding.go +++ b/client/informers/externalversions/kubebind/v1alpha1/apiservicebinding.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,15 +22,15 @@ import ( "context" time "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + versioned "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + internalinterfaces "go.bytebuilders.dev/kube-bind/client/informers/externalversions/internalinterfaces" + v1alpha1 "go.bytebuilders.dev/kube-bind/client/listers/kubebind/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" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - versioned "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - internalinterfaces "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" ) // APIServiceBindingInformer provides access to a shared informer and lister for diff --git a/pkg/client/informers/externalversions/kubebind/v1alpha1/apiserviceexport.go b/client/informers/externalversions/kubebind/v1alpha1/apiserviceexport.go similarity index 86% rename from pkg/client/informers/externalversions/kubebind/v1alpha1/apiserviceexport.go rename to client/informers/externalversions/kubebind/v1alpha1/apiserviceexport.go index 6b1077b2..bffa7049 100644 --- a/pkg/client/informers/externalversions/kubebind/v1alpha1/apiserviceexport.go +++ b/client/informers/externalversions/kubebind/v1alpha1/apiserviceexport.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,15 +22,15 @@ import ( "context" time "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + versioned "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + internalinterfaces "go.bytebuilders.dev/kube-bind/client/informers/externalversions/internalinterfaces" + v1alpha1 "go.bytebuilders.dev/kube-bind/client/listers/kubebind/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" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - versioned "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - internalinterfaces "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" ) // APIServiceExportInformer provides access to a shared informer and lister for diff --git a/pkg/client/informers/externalversions/kubebind/v1alpha1/apiserviceexportrequest.go b/client/informers/externalversions/kubebind/v1alpha1/apiserviceexportrequest.go similarity index 87% rename from pkg/client/informers/externalversions/kubebind/v1alpha1/apiserviceexportrequest.go rename to client/informers/externalversions/kubebind/v1alpha1/apiserviceexportrequest.go index ab47ecdb..2bdc3066 100644 --- a/pkg/client/informers/externalversions/kubebind/v1alpha1/apiserviceexportrequest.go +++ b/client/informers/externalversions/kubebind/v1alpha1/apiserviceexportrequest.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,15 +22,15 @@ import ( "context" time "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + versioned "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + internalinterfaces "go.bytebuilders.dev/kube-bind/client/informers/externalversions/internalinterfaces" + v1alpha1 "go.bytebuilders.dev/kube-bind/client/listers/kubebind/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" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - versioned "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - internalinterfaces "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" ) // APIServiceExportRequestInformer provides access to a shared informer and lister for diff --git a/pkg/client/informers/externalversions/kubebind/v1alpha1/apiservicenamespace.go b/client/informers/externalversions/kubebind/v1alpha1/apiservicenamespace.go similarity index 86% rename from pkg/client/informers/externalversions/kubebind/v1alpha1/apiservicenamespace.go rename to client/informers/externalversions/kubebind/v1alpha1/apiservicenamespace.go index fa59ba04..10e85464 100644 --- a/pkg/client/informers/externalversions/kubebind/v1alpha1/apiservicenamespace.go +++ b/client/informers/externalversions/kubebind/v1alpha1/apiservicenamespace.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,15 +22,15 @@ import ( "context" time "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + versioned "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + internalinterfaces "go.bytebuilders.dev/kube-bind/client/informers/externalversions/internalinterfaces" + v1alpha1 "go.bytebuilders.dev/kube-bind/client/listers/kubebind/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" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - versioned "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - internalinterfaces "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" ) // APIServiceNamespaceInformer provides access to a shared informer and lister for diff --git a/pkg/client/informers/externalversions/kubebind/v1alpha1/clusterbinding.go b/client/informers/externalversions/kubebind/v1alpha1/clusterbinding.go similarity index 86% rename from pkg/client/informers/externalversions/kubebind/v1alpha1/clusterbinding.go rename to client/informers/externalversions/kubebind/v1alpha1/clusterbinding.go index 370f5771..3d860f5c 100644 --- a/pkg/client/informers/externalversions/kubebind/v1alpha1/clusterbinding.go +++ b/client/informers/externalversions/kubebind/v1alpha1/clusterbinding.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,15 +22,15 @@ import ( "context" time "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + versioned "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + internalinterfaces "go.bytebuilders.dev/kube-bind/client/informers/externalversions/internalinterfaces" + v1alpha1 "go.bytebuilders.dev/kube-bind/client/listers/kubebind/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" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - versioned "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - internalinterfaces "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" ) // ClusterBindingInformer provides access to a shared informer and lister for diff --git a/pkg/client/informers/externalversions/kubebind/v1alpha1/interface.go b/client/informers/externalversions/kubebind/v1alpha1/interface.go similarity index 90% rename from pkg/client/informers/externalversions/kubebind/v1alpha1/interface.go rename to client/informers/externalversions/kubebind/v1alpha1/interface.go index 73051f24..fa59b46a 100644 --- a/pkg/client/informers/externalversions/kubebind/v1alpha1/interface.go +++ b/client/informers/externalversions/kubebind/v1alpha1/interface.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,7 +19,7 @@ limitations under the License. package v1alpha1 import ( - internalinterfaces "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/internalinterfaces" + internalinterfaces "go.bytebuilders.dev/kube-bind/client/informers/externalversions/internalinterfaces" ) // Interface provides access to all the informers in this group version. diff --git a/pkg/client/listers/kubebind/v1alpha1/apiservicebinding.go b/client/listers/kubebind/v1alpha1/apiservicebinding.go similarity index 89% rename from pkg/client/listers/kubebind/v1alpha1/apiservicebinding.go rename to client/listers/kubebind/v1alpha1/apiservicebinding.go index d4614ab7..e1a48125 100644 --- a/pkg/client/listers/kubebind/v1alpha1/apiservicebinding.go +++ b/client/listers/kubebind/v1alpha1/apiservicebinding.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,11 +19,11 @@ limitations under the License. package v1alpha1 import ( + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // APIServiceBindingLister helps list APIServiceBindings. diff --git a/pkg/client/listers/kubebind/v1alpha1/apiserviceexport.go b/client/listers/kubebind/v1alpha1/apiserviceexport.go similarity index 93% rename from pkg/client/listers/kubebind/v1alpha1/apiserviceexport.go rename to client/listers/kubebind/v1alpha1/apiserviceexport.go index dcd12acd..18547a54 100644 --- a/pkg/client/listers/kubebind/v1alpha1/apiserviceexport.go +++ b/client/listers/kubebind/v1alpha1/apiserviceexport.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,11 +19,11 @@ limitations under the License. package v1alpha1 import ( + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // APIServiceExportLister helps list APIServiceExports. diff --git a/pkg/client/listers/kubebind/v1alpha1/apiserviceexportrequest.go b/client/listers/kubebind/v1alpha1/apiserviceexportrequest.go similarity index 94% rename from pkg/client/listers/kubebind/v1alpha1/apiserviceexportrequest.go rename to client/listers/kubebind/v1alpha1/apiserviceexportrequest.go index 5f3285d4..df065c91 100644 --- a/pkg/client/listers/kubebind/v1alpha1/apiserviceexportrequest.go +++ b/client/listers/kubebind/v1alpha1/apiserviceexportrequest.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,11 +19,11 @@ limitations under the License. package v1alpha1 import ( + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // APIServiceExportRequestLister helps list APIServiceExportRequests. diff --git a/pkg/client/listers/kubebind/v1alpha1/apiservicenamespace.go b/client/listers/kubebind/v1alpha1/apiservicenamespace.go similarity index 93% rename from pkg/client/listers/kubebind/v1alpha1/apiservicenamespace.go rename to client/listers/kubebind/v1alpha1/apiservicenamespace.go index 1e61b68d..54e85592 100644 --- a/pkg/client/listers/kubebind/v1alpha1/apiservicenamespace.go +++ b/client/listers/kubebind/v1alpha1/apiservicenamespace.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,11 +19,11 @@ limitations under the License. package v1alpha1 import ( + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // APIServiceNamespaceLister helps list APIServiceNamespaces. diff --git a/pkg/client/listers/kubebind/v1alpha1/clusterbinding.go b/client/listers/kubebind/v1alpha1/clusterbinding.go similarity index 93% rename from pkg/client/listers/kubebind/v1alpha1/clusterbinding.go rename to client/listers/kubebind/v1alpha1/clusterbinding.go index 2905ddce..40572766 100644 --- a/pkg/client/listers/kubebind/v1alpha1/clusterbinding.go +++ b/client/listers/kubebind/v1alpha1/clusterbinding.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,11 +19,11 @@ limitations under the License. package v1alpha1 import ( + v1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" - - v1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) // ClusterBindingLister helps list ClusterBindings. diff --git a/pkg/client/listers/kubebind/v1alpha1/expansion_generated.go b/client/listers/kubebind/v1alpha1/expansion_generated.go similarity index 91% rename from pkg/client/listers/kubebind/v1alpha1/expansion_generated.go rename to client/listers/kubebind/v1alpha1/expansion_generated.go index 3cdf7aed..d07f10a8 100644 --- a/pkg/client/listers/kubebind/v1alpha1/expansion_generated.go +++ b/client/listers/kubebind/v1alpha1/expansion_generated.go @@ -1,11 +1,11 @@ /* -Copyright The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/cmd/example-backend/main.go b/cmd/example-backend/main.go index 49f1a25a..ed123943 100644 --- a/cmd/example-backend/main.go +++ b/cmd/example-backend/main.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,15 +21,14 @@ import ( "os" "strings" - "github.com/spf13/pflag" + backend "go.bytebuilders.dev/kube-bind/contrib/example-backend" + "go.bytebuilders.dev/kube-bind/contrib/example-backend/options" + "github.com/spf13/pflag" genericapiserver "k8s.io/apiserver/pkg/server" logsv1 "k8s.io/component-base/logs/api/v1" "k8s.io/component-base/version" "k8s.io/klog/v2" - - backend "go.bytebuilders.dev/kube-bind/contrib/example-backend" - "go.bytebuilders.dev/kube-bind/contrib/example-backend/options" ) func main() { diff --git a/cmd/konnector/cmd/konnector.go b/cmd/konnector/cmd/konnector.go index 5206e1b8..4e0a7fdd 100644 --- a/cmd/konnector/cmd/konnector.go +++ b/cmd/konnector/cmd/konnector.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,16 +21,15 @@ import ( "fmt" "os" - "github.com/spf13/cobra" + "go.bytebuilders.dev/kube-bind/pkg/konnector" + konnectoroptions "go.bytebuilders.dev/kube-bind/pkg/konnector/options" + bindversion "go.bytebuilders.dev/kube-bind/pkg/version" + "github.com/spf13/cobra" logsv1 "k8s.io/component-base/logs/api/v1" _ "k8s.io/component-base/logs/json/register" componentbaseversion "k8s.io/component-base/version" "k8s.io/klog/v2" - - "go.bytebuilders.dev/kube-bind/pkg/konnector" - konnectoroptions "go.bytebuilders.dev/kube-bind/pkg/konnector/options" - bindversion "go.bytebuilders.dev/kube-bind/pkg/version" ) func New(ctx context.Context) *cobra.Command { diff --git a/cmd/konnector/cmd/leaderelection.go b/cmd/konnector/cmd/leaderelection.go index cad03564..72b6d424 100644 --- a/cmd/konnector/cmd/leaderelection.go +++ b/cmd/konnector/cmd/leaderelection.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/cmd/konnector/main.go b/cmd/konnector/main.go index d6b6303c..56b12e8a 100644 --- a/cmd/konnector/main.go +++ b/cmd/konnector/main.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,10 +19,10 @@ package main import ( "os" + "go.bytebuilders.dev/kube-bind/cmd/konnector/cmd" + genericapiserver "k8s.io/apiserver/pkg/server" "k8s.io/component-base/cli" - - "go.bytebuilders.dev/kube-bind/cmd/konnector/cmd" ) func main() { diff --git a/cmd/kubectl-connect/main.go b/cmd/kubectl-connect/main.go index 0d83c0bf..82ef2b53 100644 --- a/cmd/kubectl-connect/main.go +++ b/cmd/kubectl-connect/main.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,25 +20,24 @@ import ( "fmt" "os" - "github.com/spf13/pflag" - - "k8s.io/cli-runtime/pkg/genericclioptions" - apiservicecmd "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind-apiservice/cmd" bindcmd "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind/cmd" + + "github.com/spf13/pflag" + "k8s.io/cli-runtime/pkg/genericiooptions" ) func main() { - flags := pflag.NewFlagSet("kubectl-bind", pflag.ExitOnError) + flags := pflag.NewFlagSet("kubectl-connect", pflag.ExitOnError) pflag.CommandLine = flags - bindCmd, err := bindcmd.New(genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}) + bindCmd, err := bindcmd.New(genericiooptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}) if err != nil { fmt.Fprintf(os.Stderr, "error: %v", err) os.Exit(1) } - apiserviceCmd, err := apiservicecmd.New(genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}) + apiserviceCmd, err := apiservicecmd.New(genericiooptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}) if err != nil { fmt.Fprintf(os.Stderr, "error: %v", err) os.Exit(1) diff --git a/code-of-conduct.md b/code-of-conduct.md deleted file mode 100644 index a027bf69..00000000 --- a/code-of-conduct.md +++ /dev/null @@ -1,75 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of -experience, education, socio-economic status, nationality, personal appearance, -race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Gracefully accepting constructive criticism -- Focusing on what is best for the community -- Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -- The use of sexualized language or imagery and unwelcome sexual attention or - advances -- Trolling, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic - address, without explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, or to ban temporarily or permanently any -contributor for other behaviors that they deem inappropriate, threatening, -offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at -kube-bind-code-of-conduct@googlegroups.com. All complaints will be reviewed and -investigated and will result in a response that is deemed necessary and -appropriate to the circumstances. The project team is obligated to maintain -confidentiality with regard to the reporter of an incident. Further details of -specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 1.4, available at -https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org diff --git a/contrib/example-backend/config.go b/contrib/example-backend/config.go index e9f67d36..7b358e71 100644 --- a/contrib/example-backend/config.go +++ b/contrib/example-backend/config.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,16 +19,16 @@ package backend import ( "time" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions" + "go.bytebuilders.dev/kube-bind/contrib/example-backend/options" + apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions" kubeinformers "k8s.io/client-go/informers" kubernetesclient "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - - "go.bytebuilders.dev/kube-bind/contrib/example-backend/options" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions" ) type Config struct { diff --git a/contrib/example-backend/controllers/clusterbinding/clusterbinding_controller.go b/contrib/example-backend/controllers/clusterbinding/clusterbinding_controller.go index 43c58a7d..b464d604 100644 --- a/contrib/example-backend/controllers/clusterbinding/clusterbinding_controller.go +++ b/contrib/example-backend/controllers/clusterbinding/clusterbinding_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,12 @@ import ( "fmt" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind/v1alpha1" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -38,12 +44,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind/v1alpha1" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" ) const ( @@ -53,7 +53,7 @@ const ( // NewController returns a new controller to reconcile ClusterBindings. func NewController( config *rest.Config, - scope kubebindv1alpha1.Scope, + scope v1alpha1.Scope, clusterBindingInformer bindinformers.ClusterBindingInformer, serviceExportInformer bindinformers.APIServiceExportInformer, clusterRoleInformer rbacinformers.ClusterRoleInformer, @@ -99,7 +99,7 @@ func NewController( reconciler: reconciler{ scope: scope, - listServiceExports: func(ns string) ([]*kubebindv1alpha1.APIServiceExport, error) { + listServiceExports: func(ns string) ([]*v1alpha1.APIServiceExport, error) { return serviceExportInformer.Lister().APIServiceExports(ns).List(labels.Everything()) }, getClusterRole: func(name string) (*rbacv1.ClusterRole, error) { @@ -137,8 +137,8 @@ func NewController( }, }, - commit: committer.NewCommitter[*kubebindv1alpha1.ClusterBinding, *kubebindv1alpha1.ClusterBindingSpec, *kubebindv1alpha1.ClusterBindingStatus]( - func(ns string) committer.Patcher[*kubebindv1alpha1.ClusterBinding] { + commit: committer.NewCommitter[*v1alpha1.ClusterBinding, *v1alpha1.ClusterBindingSpec, *v1alpha1.ClusterBindingStatus]( + func(ns string) committer.Patcher[*v1alpha1.ClusterBinding] { return bindClient.KubeBindV1alpha1().ClusterBindings(ns) }, ), @@ -177,8 +177,10 @@ func NewController( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.ClusterBindingSpec, *kubebindv1alpha1.ClusterBindingStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*v1alpha1.ClusterBindingSpec, *v1alpha1.ClusterBindingStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) // Controller reconciles ClusterBinding conditions. type Controller struct { diff --git a/contrib/example-backend/controllers/clusterbinding/clusterbinding_reconcile.go b/contrib/example-backend/controllers/clusterbinding/clusterbinding_reconcile.go index 7317dd60..d5aa547d 100644 --- a/contrib/example-backend/controllers/clusterbinding/clusterbinding_reconcile.go +++ b/contrib/example-backend/controllers/clusterbinding/clusterbinding_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,8 +22,8 @@ import ( "reflect" "time" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + kuberesources "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -32,15 +32,14 @@ import ( utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/klog/v2" "k8s.io/utils/ptr" - - kuberesources "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) type reconciler struct { - scope kubebindv1alpha1.Scope + scope v1alpha1.Scope - listServiceExports func(ns string) ([]*kubebindv1alpha1.APIServiceExport, error) + listServiceExports func(ns string) ([]*v1alpha1.APIServiceExport, error) getClusterRole func(name string) (*rbacv1.ClusterRole, error) createClusterRole func(ctx context.Context, binding *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) @@ -58,7 +57,7 @@ type reconciler struct { getNamespace func(name string) (*corev1.Namespace, error) } -func (r *reconciler) reconcile(ctx context.Context, clusterBinding *kubebindv1alpha1.ClusterBinding) error { +func (r *reconciler) reconcile(ctx context.Context, clusterBinding *v1alpha1.ClusterBinding) error { var errs []error if err := r.ensureKubeSystemNSAccess(ctx, clusterBinding); err != nil { @@ -80,24 +79,24 @@ func (r *reconciler) reconcile(ctx context.Context, clusterBinding *kubebindv1al return utilerrors.NewAggregate(errs) } -func (r *reconciler) ensureClusterBindingConditions(clusterBinding *kubebindv1alpha1.ClusterBinding) { +func (r *reconciler) ensureClusterBindingConditions(clusterBinding *v1alpha1.ClusterBinding) { if clusterBinding.Status.LastHeartbeatTime.IsZero() { conditions.MarkFalse(clusterBinding, - kubebindv1alpha1.ClusterBindingConditionHealthy, + v1alpha1.ClusterBindingConditionHealthy, "FirstHeartbeatPending", conditionsapi.ConditionSeverityInfo, "Waiting for first heartbeat", ) } else if clusterBinding.Status.HeartbeatInterval.Duration == 0 { conditions.MarkFalse(clusterBinding, - kubebindv1alpha1.ClusterBindingConditionHealthy, + v1alpha1.ClusterBindingConditionHealthy, "HeartbeatIntervalMissing", conditionsapi.ConditionSeverityInfo, "Waiting for consumer cluster reporting its heartbeat interval", ) } else if ago := time.Since(clusterBinding.Status.LastHeartbeatTime.Time); ago > clusterBinding.Status.HeartbeatInterval.Duration*2 { conditions.MarkFalse(clusterBinding, - kubebindv1alpha1.ClusterBindingConditionHealthy, + v1alpha1.ClusterBindingConditionHealthy, "HeartbeatTimeout", conditionsapi.ConditionSeverityError, "Heartbeat timeout: expected heartbeat within %s, but last one has been at %s", @@ -106,19 +105,19 @@ func (r *reconciler) ensureClusterBindingConditions(clusterBinding *kubebindv1al ) } else if ago < time.Second*10 { conditions.MarkFalse(clusterBinding, - kubebindv1alpha1.ClusterBindingConditionHealthy, + v1alpha1.ClusterBindingConditionHealthy, "HeartbeatTimeDrift", conditionsapi.ConditionSeverityWarning, "Clocks of consumer cluster and service account cluster seem to be off by more than 10s", ) } else { conditions.MarkTrue(clusterBinding, - kubebindv1alpha1.ClusterBindingConditionHealthy, + v1alpha1.ClusterBindingConditionHealthy, ) } } -func (r *reconciler) ensureKubeSystemNSAccess(ctx context.Context, clusterBinding *kubebindv1alpha1.ClusterBinding) error { +func (r *reconciler) ensureKubeSystemNSAccess(ctx context.Context, clusterBinding *v1alpha1.ClusterBinding) error { roleName := "kube-binder-namespace" clusterRole, err := r.getClusterRole(roleName) if err != nil && !errors.IsNotFound(err) { @@ -194,7 +193,7 @@ func (r *reconciler) ensureKubeSystemNSAccess(ctx context.Context, clusterBindin return nil } -func (r *reconciler) ensureRBACClusterRole(ctx context.Context, clusterBinding *kubebindv1alpha1.ClusterBinding) error { +func (r *reconciler) ensureRBACClusterRole(ctx context.Context, clusterBinding *v1alpha1.ClusterBinding) error { name := "kube-binder-" + clusterBinding.Namespace role, err := r.getClusterRole(name) if err != nil && !errors.IsNotFound(err) { @@ -247,14 +246,14 @@ func (r *reconciler) ensureRBACClusterRole(ctx context.Context, clusterBinding * return nil } -func (r *reconciler) ensureRBACClusterRoleBinding(ctx context.Context, clusterBinding *kubebindv1alpha1.ClusterBinding) error { +func (r *reconciler) ensureRBACClusterRoleBinding(ctx context.Context, clusterBinding *v1alpha1.ClusterBinding) error { name := "kube-binder-" + clusterBinding.Namespace binding, err := r.getClusterRoleBinding(name) if err != nil && !errors.IsNotFound(err) { return fmt.Errorf("failed to get ClusterRoleBinding %s: %w", name, err) } - if r.scope != kubebindv1alpha1.ClusterScope { + if r.scope != v1alpha1.ClusterScope { if err := r.deleteClusterRoleBinding(ctx, name); err != nil && !errors.IsNotFound(err) { return fmt.Errorf("failed to delete ClusterRoleBinding %s: %w", name, err) } @@ -308,7 +307,7 @@ func (r *reconciler) ensureRBACClusterRoleBinding(ctx context.Context, clusterBi return nil } -func (r *reconciler) ensureRBACRoleBinding(ctx context.Context, clusterBinding *kubebindv1alpha1.ClusterBinding) error { +func (r *reconciler) ensureRBACRoleBinding(ctx context.Context, clusterBinding *v1alpha1.ClusterBinding) error { binding, err := r.getRoleBinding(clusterBinding.Namespace, "kube-binder") if err != nil && !errors.IsNotFound(err) { return fmt.Errorf("failed to get RoleBinding \"kube-binder\": %w", err) diff --git a/contrib/example-backend/controllers/serviceexport/serviceexport_controller.go b/contrib/example-backend/controllers/serviceexport/serviceexport_controller.go index ded2fbcc..1ca8f7ae 100644 --- a/contrib/example-backend/controllers/serviceexport/serviceexport_controller.go +++ b/contrib/example-backend/controllers/serviceexport/serviceexport_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,13 @@ import ( "fmt" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind/v1alpha1" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1" apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" @@ -33,13 +40,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind/v1alpha1" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" - "go.bytebuilders.dev/kube-bind/pkg/indexers" ) const ( @@ -138,8 +138,10 @@ func NewController( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.APIServiceExportSpec, *kubebindv1alpha1.APIServiceExportStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*kubebindv1alpha1.APIServiceExportSpec, *kubebindv1alpha1.APIServiceExportStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) // Controller reconciles ServiceNamespaces by creating a Namespace for each, and deleting it if // the APIServiceNamespace is deleted. diff --git a/contrib/example-backend/controllers/serviceexport/serviceexport_reconcile.go b/contrib/example-backend/controllers/serviceexport/serviceexport_reconcile.go index 177099d7..3f29846c 100644 --- a/contrib/example-backend/controllers/serviceexport/serviceexport_reconcile.go +++ b/contrib/example-backend/controllers/serviceexport/serviceexport_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,16 +19,15 @@ package serviceexport import ( "context" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + kubebindhelpers "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1/helpers" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - kubebindhelpers "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1/helpers" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) type reconciler struct { @@ -75,7 +74,7 @@ func (r *reconciler) ensureSchema(ctx context.Context, export *kubebindv1alpha1. "CustomResourceDefinition %s cannot be converted into a APIServiceExport: %s", export.Name, err, ) - return false, nil //nothing we can do + return false, nil // nothing we can do } if hash := kubebindhelpers.APIServiceExportCRDSpecHash(expected); export.Annotations[kubebindv1alpha1.SourceSpecHashAnnotationKey] != hash { diff --git a/contrib/example-backend/controllers/serviceexportrequest/serviceexportrequest_controller.go b/contrib/example-backend/controllers/serviceexportrequest/serviceexportrequest_controller.go index 8d7665a7..27966dd7 100644 --- a/contrib/example-backend/controllers/serviceexportrequest/serviceexportrequest_controller.go +++ b/contrib/example-backend/controllers/serviceexportrequest/serviceexportrequest_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,13 @@ import ( "fmt" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind/v1alpha1" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1" apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" @@ -34,13 +41,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind/v1alpha1" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" - "go.bytebuilders.dev/kube-bind/pkg/indexers" ) const ( @@ -51,8 +51,8 @@ const ( // creating corresponding APIServiceExports. func NewController( config *rest.Config, - scope kubebindv1alpha1.Scope, - isolation kubebindv1alpha1.Isolation, + scope v1alpha1.Scope, + isolation v1alpha1.Isolation, serviceExportRequestInformer bindinformers.APIServiceExportRequestInformer, serviceExportInformer bindinformers.APIServiceExportInformer, crdInformer apiextensionsinformers.CustomResourceDefinitionInformer, @@ -96,10 +96,10 @@ func NewController( getCRD: func(name string) (*apiextensionsv1.CustomResourceDefinition, error) { return crdInformer.Lister().Get(name) }, - getServiceExport: func(ns, name string) (*kubebindv1alpha1.APIServiceExport, error) { + getServiceExport: func(ns, name string) (*v1alpha1.APIServiceExport, error) { return serviceExportInformer.Lister().APIServiceExports(ns).Get(name) }, - createServiceExport: func(ctx context.Context, resource *kubebindv1alpha1.APIServiceExport) (*kubebindv1alpha1.APIServiceExport, error) { + createServiceExport: func(ctx context.Context, resource *v1alpha1.APIServiceExport) (*v1alpha1.APIServiceExport, error) { return bindClient.KubeBindV1alpha1().APIServiceExports(resource.Namespace).Create(ctx, resource, metav1.CreateOptions{}) }, deleteServiceExportRequest: func(ctx context.Context, ns, name string) error { @@ -107,8 +107,8 @@ func NewController( }, }, - commit: committer.NewCommitter[*kubebindv1alpha1.APIServiceExportRequest, *kubebindv1alpha1.APIServiceExportRequestSpec, *kubebindv1alpha1.APIServiceExportRequestStatus]( - func(ns string) committer.Patcher[*kubebindv1alpha1.APIServiceExportRequest] { + commit: committer.NewCommitter[*v1alpha1.APIServiceExportRequest, *v1alpha1.APIServiceExportRequestSpec, *v1alpha1.APIServiceExportRequestStatus]( + func(ns string) committer.Patcher[*v1alpha1.APIServiceExportRequest] { return bindClient.KubeBindV1alpha1().APIServiceExportRequests(ns) }, ), @@ -169,8 +169,10 @@ func NewController( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.APIServiceExportRequestSpec, *kubebindv1alpha1.APIServiceExportRequestStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*v1alpha1.APIServiceExportRequestSpec, *v1alpha1.APIServiceExportRequestStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) // Controller to reconcile APIServiceExportRequests by creating corresponding APIServiceExports. type Controller struct { diff --git a/contrib/example-backend/controllers/serviceexportrequest/serviceexportrequest_reconcile.go b/contrib/example-backend/controllers/serviceexportrequest/serviceexportrequest_reconcile.go index f1e24e26..d01d4897 100644 --- a/contrib/example-backend/controllers/serviceexportrequest/serviceexportrequest_reconcile.go +++ b/contrib/example-backend/controllers/serviceexportrequest/serviceexportrequest_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,31 +20,30 @@ import ( "context" "time" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1/helpers" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1/helpers" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) type reconciler struct { - informerScope kubebindv1alpha1.Scope - clusterScopedIsolation kubebindv1alpha1.Isolation + informerScope v1alpha1.Scope + clusterScopedIsolation v1alpha1.Isolation getCRD func(name string) (*apiextensionsv1.CustomResourceDefinition, error) - getServiceExport func(ns, name string) (*kubebindv1alpha1.APIServiceExport, error) - createServiceExport func(ctx context.Context, resource *kubebindv1alpha1.APIServiceExport) (*kubebindv1alpha1.APIServiceExport, error) + getServiceExport func(ns, name string) (*v1alpha1.APIServiceExport, error) + createServiceExport func(ctx context.Context, resource *v1alpha1.APIServiceExport) (*v1alpha1.APIServiceExport, error) deleteServiceExportRequest func(ctx context.Context, namespace, name string) error } -func (r *reconciler) reconcile(ctx context.Context, req *kubebindv1alpha1.APIServiceExportRequest) error { +func (r *reconciler) reconcile(ctx context.Context, req *v1alpha1.APIServiceExportRequest) error { var errs []error if err := r.ensureExports(ctx, req); err != nil { @@ -56,10 +55,10 @@ func (r *reconciler) reconcile(ctx context.Context, req *kubebindv1alpha1.APISer return utilerrors.NewAggregate(errs) } -func (r *reconciler) ensureExports(ctx context.Context, req *kubebindv1alpha1.APIServiceExportRequest) error { +func (r *reconciler) ensureExports(ctx context.Context, req *v1alpha1.APIServiceExportRequest) error { logger := klog.FromContext(ctx) - if req.Status.Phase == kubebindv1alpha1.APIServiceExportRequestPhasePending { + if req.Status.Phase == v1alpha1.APIServiceExportRequestPhasePending { failure := false for _, res := range req.Spec.Resources { name := res.Resource + "." + res.Group @@ -70,7 +69,7 @@ func (r *reconciler) ensureExports(ctx context.Context, req *kubebindv1alpha1.AP if apierrors.IsNotFound(err) { conditions.MarkFalse( req, - kubebindv1alpha1.APIServiceExportRequestConditionExportsReady, + v1alpha1.APIServiceExportRequestConditionExportsReady, "CRDNotFound", conditionsapi.ConditionSeverityError, "CustomResourceDefinition %s in the service provider cluster not found", @@ -90,7 +89,7 @@ func (r *reconciler) ensureExports(ctx context.Context, req *kubebindv1alpha1.AP if err != nil { conditions.MarkFalse( req, - kubebindv1alpha1.APIServiceExportRequestConditionExportsReady, + v1alpha1.APIServiceExportRequestConditionExportsReady, "CRDInvalid", conditionsapi.ConditionSeverityError, "CustomResourceDefinition %s cannot be converted to a APIServiceExport: %v", @@ -101,15 +100,15 @@ func (r *reconciler) ensureExports(ctx context.Context, req *kubebindv1alpha1.AP break } hash := helpers.APIServiceExportCRDSpecHash(exportSpec) - export := &kubebindv1alpha1.APIServiceExport{ + export := &v1alpha1.APIServiceExport{ ObjectMeta: metav1.ObjectMeta{ Name: crd.Name, Namespace: req.Namespace, Annotations: map[string]string{ - kubebindv1alpha1.SourceSpecHashAnnotationKey: hash, + v1alpha1.SourceSpecHashAnnotationKey: hash, }, }, - Spec: kubebindv1alpha1.APIServiceExportSpec{ + Spec: v1alpha1.APIServiceExportSpec{ APIServiceExportCRDSpec: *exportSpec, InformerScope: r.informerScope, }, @@ -125,14 +124,14 @@ func (r *reconciler) ensureExports(ctx context.Context, req *kubebindv1alpha1.AP } if !failure { - conditions.MarkTrue(req, kubebindv1alpha1.APIServiceExportRequestConditionExportsReady) - req.Status.Phase = kubebindv1alpha1.APIServiceExportRequestPhaseSucceeded + conditions.MarkTrue(req, v1alpha1.APIServiceExportRequestConditionExportsReady) + req.Status.Phase = v1alpha1.APIServiceExportRequestPhaseSucceeded return nil } if time.Since(req.CreationTimestamp.Time) > time.Minute { - req.Status.Phase = kubebindv1alpha1.APIServiceExportRequestPhaseFailed - req.Status.TerminalMessage = conditions.GetMessage(req, kubebindv1alpha1.APIServiceExportRequestConditionExportsReady) + req.Status.Phase = v1alpha1.APIServiceExportRequestPhaseFailed + req.Status.TerminalMessage = conditions.GetMessage(req, v1alpha1.APIServiceExportRequestConditionExportsReady) } return nil diff --git a/contrib/example-backend/controllers/servicenamespace/servicenamespace_controller.go b/contrib/example-backend/controllers/servicenamespace/servicenamespace_controller.go index 8228a6ab..f797f2b3 100644 --- a/contrib/example-backend/controllers/servicenamespace/servicenamespace_controller.go +++ b/contrib/example-backend/controllers/servicenamespace/servicenamespace_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,6 +22,13 @@ import ( "reflect" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind/v1alpha1" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -38,13 +45,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind/v1alpha1" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" - "go.bytebuilders.dev/kube-bind/pkg/indexers" ) const ( @@ -54,7 +54,7 @@ const ( // NewController returns a new controller for ServiceNamespaces. func NewController( config *rest.Config, - scope kubebindv1alpha1.Scope, + scope v1alpha1.Scope, serviceNamespaceInformer bindinformers.APIServiceNamespaceInformer, clusterBindingInformer bindinformers.ClusterBindingInformer, serviceExportInformer bindinformers.APIServiceExportInformer, @@ -126,8 +126,8 @@ func NewController( }, }, - commit: committer.NewCommitter[*kubebindv1alpha1.APIServiceNamespace, *kubebindv1alpha1.APIServiceNamespaceSpec, *kubebindv1alpha1.APIServiceNamespaceStatus]( - func(ns string) committer.Patcher[*kubebindv1alpha1.APIServiceNamespace] { + commit: committer.NewCommitter[*v1alpha1.APIServiceNamespace, *v1alpha1.APIServiceNamespaceSpec, *v1alpha1.APIServiceNamespaceStatus]( + func(ns string) committer.Patcher[*v1alpha1.APIServiceNamespace] { return bindClient.KubeBindV1alpha1().APIServiceNamespaces(ns) }, ), @@ -181,11 +181,11 @@ func NewController( c.enqueueServiceExport(logger, obj) }, UpdateFunc: func(old, newObj interface{}) { - oldExport, ok := old.(*kubebindv1alpha1.APIServiceExport) + oldExport, ok := old.(*v1alpha1.APIServiceExport) if !ok { return } - newExport, ok := old.(*kubebindv1alpha1.APIServiceExport) + newExport, ok := old.(*v1alpha1.APIServiceExport) if !ok { return } @@ -205,8 +205,10 @@ func NewController( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.APIServiceNamespaceSpec, *kubebindv1alpha1.APIServiceNamespaceStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*v1alpha1.APIServiceNamespaceSpec, *v1alpha1.APIServiceNamespaceStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) // Controller reconciles ServiceNamespaces by creating a Namespace for each, and deleting it if // the APIServiceNamespace is deleted. diff --git a/contrib/example-backend/controllers/servicenamespace/servicenamespace_reconcile.go b/contrib/example-backend/controllers/servicenamespace/servicenamespace_reconcile.go index 6fc650de..c7080228 100644 --- a/contrib/example-backend/controllers/servicenamespace/servicenamespace_reconcile.go +++ b/contrib/example-backend/controllers/servicenamespace/servicenamespace_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,17 +21,17 @@ import ( "fmt" "reflect" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + kuberesources "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" + corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - kuberesources "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) type reconciler struct { - scope kubebindv1alpha1.Scope + scope v1alpha1.Scope getNamespace func(name string) (*corev1.Namespace, error) createNamespace func(ctx context.Context, ns *corev1.Namespace) (*corev1.Namespace, error) @@ -42,7 +42,7 @@ type reconciler struct { updateRoleBinding func(ctx context.Context, cr *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) } -func (c *reconciler) reconcile(ctx context.Context, sns *kubebindv1alpha1.APIServiceNamespace) error { +func (c *reconciler) reconcile(ctx context.Context, sns *v1alpha1.APIServiceNamespace) error { var ns *corev1.Namespace nsName := sns.Namespace + "-" + sns.Name if sns.Status.Namespace != "" { @@ -54,7 +54,7 @@ func (c *reconciler) reconcile(ctx context.Context, sns *kubebindv1alpha1.APISer ObjectMeta: metav1.ObjectMeta{ Name: nsName, Annotations: map[string]string{ - kubebindv1alpha1.APIServiceNamespaceAnnotationKey: sns.Namespace + "/" + sns.Name, + v1alpha1.APIServiceNamespaceAnnotationKey: sns.Namespace + "/" + sns.Name, }, }, } @@ -63,7 +63,7 @@ func (c *reconciler) reconcile(ctx context.Context, sns *kubebindv1alpha1.APISer } } - if c.scope == kubebindv1alpha1.NamespacedScope { + if c.scope == v1alpha1.NamespacedScope { if err := c.ensureRBACRoleBinding(ctx, nsName, sns); err != nil { return fmt.Errorf("failed to ensure RBAC: %w", err) } @@ -76,7 +76,7 @@ func (c *reconciler) reconcile(ctx context.Context, sns *kubebindv1alpha1.APISer return nil } -func (c *reconciler) ensureRBACRoleBinding(ctx context.Context, ns string, sns *kubebindv1alpha1.APIServiceNamespace) error { +func (c *reconciler) ensureRBACRoleBinding(ctx context.Context, ns string, sns *v1alpha1.APIServiceNamespace) error { objName := "kube-binder" binding, err := c.getRoleBinding(ns, objName) if err != nil && !errors.IsNotFound(err) { diff --git a/contrib/example-backend/cookie/cookie.go b/contrib/example-backend/cookie/cookie.go index ebcee017..3b382eff 100644 --- a/contrib/example-backend/cookie/cookie.go +++ b/contrib/example-backend/cookie/cookie.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/cookie/session.go b/contrib/example-backend/cookie/session.go index 6ac1a549..feb8c9a4 100644 --- a/contrib/example-backend/cookie/session.go +++ b/contrib/example-backend/cookie/session.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/deploy/bootstrap.go b/contrib/example-backend/deploy/bootstrap.go index 390c10d8..3e03bd26 100644 --- a/contrib/example-backend/deploy/bootstrap.go +++ b/contrib/example-backend/deploy/bootstrap.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,11 +20,11 @@ import ( "context" "embed" + "go.bytebuilders.dev/kube-bind/pkg/bootstrap" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" - - "go.bytebuilders.dev/kube-bind/pkg/bootstrap" ) //go:embed *.yaml diff --git a/contrib/example-backend/http/handler.go b/contrib/example-backend/http/handler.go index aa00dabf..ad4c485d 100644 --- a/contrib/example-backend/http/handler.go +++ b/contrib/example-backend/http/handler.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -29,9 +29,15 @@ import ( "strings" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/contrib/example-backend/cookie" + "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes" + "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" + "go.bytebuilders.dev/kube-bind/contrib/example-backend/template" + bindversion "go.bytebuilders.dev/kube-bind/pkg/version" + "github.com/gorilla/mux" "github.com/gorilla/securecookie" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -39,18 +45,9 @@ import ( "k8s.io/apimachinery/pkg/runtime" componentbaseversion "k8s.io/component-base/version" "k8s.io/klog/v2" - - "go.bytebuilders.dev/kube-bind/contrib/example-backend/cookie" - "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes" - "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" - "go.bytebuilders.dev/kube-bind/contrib/example-backend/template" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindversion "go.bytebuilders.dev/kube-bind/pkg/version" ) -var ( - resourcesTemplate = htmltemplate.Must(htmltemplate.New("resource").Parse(mustRead(template.Files.ReadFile, "resources.gohtml"))) -) +var resourcesTemplate = htmltemplate.Must(htmltemplate.New("resource").Parse(mustRead(template.Files.ReadFile, "resources.gohtml"))) // See https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=en var noCacheHeaders = map[string]string{ @@ -62,7 +59,7 @@ var noCacheHeaders = map[string]string{ type handler struct { oidc *OIDCServiceProvider - scope kubebindv1alpha1.Scope + scope v1alpha1.Scope oidcAuthorizeURL string backendCallbackURL string providerPrettyName string @@ -80,7 +77,7 @@ func NewHandler( provider *OIDCServiceProvider, oidcAuthorizeURL, backendCallbackURL, providerPrettyName, testingAutoSelect string, cookieSigningKey, cookieEncryptionKey []byte, - scope kubebindv1alpha1.Scope, + scope v1alpha1.Scope, mgr *kubernetes.Manager, apiextensionsLister apiextensionslisters.CustomResourceDefinitionLister, ) (*handler, error) { @@ -121,17 +118,17 @@ func (h *handler) handleServiceExport(w http.ResponseWriter, r *http.Request) { ver = "v0.0.0" } - provider := &kubebindv1alpha1.BindingProvider{ + provider := &v1alpha1.BindingProvider{ TypeMeta: metav1.TypeMeta{ - APIVersion: kubebindv1alpha1.GroupVersion, + APIVersion: v1alpha1.GroupVersion, Kind: "BindingProvider", }, Version: ver, ProviderPrettyName: "example-backend", - AuthenticationMethods: []kubebindv1alpha1.AuthenticationMethod{ + AuthenticationMethods: []v1alpha1.AuthenticationMethod{ { Method: "OAuth2CodeGrant", - OAuth2CodeGrant: &kubebindv1alpha1.OAuth2CodeGrant{ + OAuth2CodeGrant: &v1alpha1.OAuth2CodeGrant{ AuthenticatedURL: oidcAuthorizeURL, }, }, @@ -306,7 +303,7 @@ func (h *handler) handleResources(w http.ResponseWriter, r *http.Request) { }) rightScopedCRDs := []*apiextensionsv1.CustomResourceDefinition{} for _, crd := range crds { - if h.scope == kubebindv1alpha1.ClusterScope || crd.Spec.Scope == apiextensionsv1.NamespaceScoped { + if h.scope == v1alpha1.ClusterScope || crd.Spec.Scope == apiextensionsv1.NamespaceScoped { rightScopedCRDs = append(rightScopedCRDs, crd) } } @@ -368,20 +365,20 @@ func (h *handler) handleBind(w http.ResponseWriter, r *http.Request) { return } - request := kubebindv1alpha1.APIServiceExportRequestResponse{ + request := v1alpha1.APIServiceExportRequestResponse{ TypeMeta: metav1.TypeMeta{ - APIVersion: kubebindv1alpha1.SchemeGroupVersion.String(), + APIVersion: v1alpha1.SchemeGroupVersion.String(), Kind: "APIServiceExportRequest", }, - ObjectMeta: kubebindv1alpha1.NameObjectMeta{ + ObjectMeta: v1alpha1.NameObjectMeta{ // this is good for one resource. If there are more (in the future), // we need a better name heuristic. Note: it does not have to be unique. // But pretty is better. Name: resource + "." + group, }, - Spec: kubebindv1alpha1.APIServiceExportRequestSpec{ - Resources: []kubebindv1alpha1.APIServiceExportRequestResource{ - {GroupResource: kubebindv1alpha1.GroupResource{Group: group, Resource: resource}}, + Spec: v1alpha1.APIServiceExportRequestSpec{ + Resources: []v1alpha1.APIServiceExportRequestResource{ + {GroupResource: v1alpha1.GroupResource{Group: group, Resource: resource}}, }, }, } @@ -393,13 +390,13 @@ func (h *handler) handleBind(w http.ResponseWriter, r *http.Request) { http.Error(w, "internal error", http.StatusInternalServerError) return } - response := kubebindv1alpha1.BindingResponse{ + response := v1alpha1.BindingResponse{ TypeMeta: metav1.TypeMeta{ - APIVersion: kubebindv1alpha1.SchemeGroupVersion.String(), + APIVersion: v1alpha1.SchemeGroupVersion.String(), Kind: "BindingResponse", }, - Authentication: kubebindv1alpha1.BindingResponseAuthentication{ - OAuth2CodeGrant: &kubebindv1alpha1.BindingResponseAuthenticationOAuth2CodeGrant{ + Authentication: v1alpha1.BindingResponseAuthentication{ + OAuth2CodeGrant: &v1alpha1.BindingResponseAuthenticationOAuth2CodeGrant{ SessionID: state.SessionID, ID: idToken.Issuer + "/" + idToken.Subject, }, diff --git a/contrib/example-backend/http/oidc.go b/contrib/example-backend/http/oidc.go index 11cf4d17..31ab4d1b 100644 --- a/contrib/example-backend/http/oidc.go +++ b/contrib/example-backend/http/oidc.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/http/server.go b/contrib/example-backend/http/server.go index b1e825c2..6584ffef 100644 --- a/contrib/example-backend/http/server.go +++ b/contrib/example-backend/http/server.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,9 +22,9 @@ import ( "net/http" "strconv" - "github.com/gorilla/mux" - "go.bytebuilders.dev/kube-bind/contrib/example-backend/options" + + "github.com/gorilla/mux" ) type Server struct { diff --git a/contrib/example-backend/kubernetes/indexers.go b/contrib/example-backend/kubernetes/indexers.go index b441edf4..13208a0b 100644 --- a/contrib/example-backend/kubernetes/indexers.go +++ b/contrib/example-backend/kubernetes/indexers.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,9 +17,9 @@ limitations under the License. package kubernetes import ( - corev1 "k8s.io/api/core/v1" - "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" + + corev1 "k8s.io/api/core/v1" ) const ( diff --git a/contrib/example-backend/kubernetes/manager.go b/contrib/example-backend/kubernetes/manager.go index 22e6f222..613dfc1b 100644 --- a/contrib/example-backend/kubernetes/manager.go +++ b/contrib/example-backend/kubernetes/manager.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,6 +20,12 @@ import ( "context" "fmt" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind/v1alpha1" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + kuberesources "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -29,12 +35,6 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" - - kuberesources "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes/resources" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind/v1alpha1" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/indexers" ) type Manager struct { diff --git a/contrib/example-backend/kubernetes/resources/cluster_binding.go b/contrib/example-backend/kubernetes/resources/cluster_binding.go index ba298af7..b8771f99 100644 --- a/contrib/example-backend/kubernetes/resources/cluster_binding.go +++ b/contrib/example-backend/kubernetes/resources/cluster_binding.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,24 +19,24 @@ package resources import ( "context" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" ) func CreateClusterBinding(ctx context.Context, client bindclient.Interface, ns, secretName, providerPrettyName string) error { logger := klog.FromContext(ctx) - clusterBinding := &kubebindv1alpha1.ClusterBinding{ + clusterBinding := &v1alpha1.ClusterBinding{ ObjectMeta: metav1.ObjectMeta{ Name: ClusterBindingName, Namespace: ns, }, - Spec: kubebindv1alpha1.ClusterBindingSpec{ + Spec: v1alpha1.ClusterBindingSpec{ ProviderPrettyName: providerPrettyName, - KubeconfigSecretRef: kubebindv1alpha1.LocalSecretKeyRef{ + KubeconfigSecretRef: v1alpha1.LocalSecretKeyRef{ Name: secretName, Key: "kubeconfig", }, diff --git a/contrib/example-backend/kubernetes/resources/kubeconfig.go b/contrib/example-backend/kubernetes/resources/kubeconfig.go index 5306e0fa..d87dd20f 100644 --- a/contrib/example-backend/kubernetes/resources/kubeconfig.go +++ b/contrib/example-backend/kubernetes/resources/kubeconfig.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,7 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" diff --git a/contrib/example-backend/kubernetes/resources/namespace.go b/contrib/example-backend/kubernetes/resources/namespace.go index 0618595c..7ac5665a 100644 --- a/contrib/example-backend/kubernetes/resources/namespace.go +++ b/contrib/example-backend/kubernetes/resources/namespace.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/kubernetes/resources/rbac.go b/contrib/example-backend/kubernetes/resources/rbac.go index 57d8c10d..612b2d69 100644 --- a/contrib/example-backend/kubernetes/resources/rbac.go +++ b/contrib/example-backend/kubernetes/resources/rbac.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/kubernetes/resources/resources.go b/contrib/example-backend/kubernetes/resources/resources.go index 415d5ae7..f34a7974 100644 --- a/contrib/example-backend/kubernetes/resources/resources.go +++ b/contrib/example-backend/kubernetes/resources/resources.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,6 +23,6 @@ const ( KubeconfigSecretName = "kubeconfig" ClusterBindingName = "cluster" - //TODO(MQ): maybe think of a better label name. + // TODO(MQ): maybe think of a better label name. ExportedCRDsLabel = "kube-bind.appscode.com/exported" ) diff --git a/contrib/example-backend/kubernetes/resources/secret.go b/contrib/example-backend/kubernetes/resources/secret.go index c605ddde..53a789aa 100644 --- a/contrib/example-backend/kubernetes/resources/secret.go +++ b/contrib/example-backend/kubernetes/resources/secret.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/options/cookie.go b/contrib/example-backend/options/cookie.go index 874621f7..c32cbd1f 100644 --- a/contrib/example-backend/options/cookie.go +++ b/contrib/example-backend/options/cookie.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/options/oidc.go b/contrib/example-backend/options/oidc.go index d6daecc8..e69f14bc 100644 --- a/contrib/example-backend/options/oidc.go +++ b/contrib/example-backend/options/oidc.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/options/options.go b/contrib/example-backend/options/options.go index c8f4311d..9c31e78d 100644 --- a/contrib/example-backend/options/options.go +++ b/contrib/example-backend/options/options.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,12 +22,11 @@ import ( "os" "strings" - "github.com/spf13/pflag" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "github.com/spf13/pflag" "k8s.io/component-base/logs" logsv1 "k8s.io/component-base/logs/api/v1" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) type Options struct { @@ -80,8 +79,8 @@ func NewOptions() *Options { ExtraOptions: ExtraOptions{ NamespacePrefix: "cluster", PrettyName: "Example Backend", - ConsumerScope: string(kubebindv1alpha1.NamespacedScope), - ClusterScopedIsolation: string(kubebindv1alpha1.IsolationPrefixed), + ConsumerScope: string(v1alpha1.NamespacedScope), + ClusterScopedIsolation: string(v1alpha1.IsolationPrefixed), }, } } @@ -118,18 +117,18 @@ func (options *Options) Complete() (*CompletedOptions, error) { // normalize the scope and the isolation if strings.ToLower(options.ConsumerScope) == "namespaced" { - options.ConsumerScope = string(kubebindv1alpha1.NamespacedScope) + options.ConsumerScope = string(v1alpha1.NamespacedScope) } if strings.ToLower(options.ConsumerScope) == "cluster" { - options.ConsumerScope = string(kubebindv1alpha1.ClusterScope) + options.ConsumerScope = string(v1alpha1.ClusterScope) } switch strings.ToLower(options.ClusterScopedIsolation) { case "prefixed": - options.ClusterScopedIsolation = string(kubebindv1alpha1.IsolationPrefixed) + options.ClusterScopedIsolation = string(v1alpha1.IsolationPrefixed) case "namespaced": - options.ClusterScopedIsolation = string(kubebindv1alpha1.IsolationNamespaced) + options.ClusterScopedIsolation = string(v1alpha1.IsolationNamespaced) case "none": - options.ClusterScopedIsolation = string(kubebindv1alpha1.IsolationNone) + options.ClusterScopedIsolation = string(v1alpha1.IsolationNone) } if options.ExternalCAFile != "" && options.ExternalCA != nil { @@ -168,8 +167,8 @@ func (options *CompletedOptions) Validate() error { if err := options.Cookie.Validate(); err != nil { return err } - if options.ConsumerScope != string(kubebindv1alpha1.NamespacedScope) && options.ConsumerScope != string(kubebindv1alpha1.ClusterScope) { - return fmt.Errorf("consumer scope must be either %q or %q", kubebindv1alpha1.NamespacedScope, kubebindv1alpha1.ClusterScope) + if options.ConsumerScope != string(v1alpha1.NamespacedScope) && options.ConsumerScope != string(v1alpha1.ClusterScope) { + return fmt.Errorf("consumer scope must be either %q or %q", v1alpha1.NamespacedScope, v1alpha1.ClusterScope) } if options.ExternalAddress != "" { diff --git a/contrib/example-backend/options/serve.go b/contrib/example-backend/options/serve.go index d15addb7..d4586244 100644 --- a/contrib/example-backend/options/serve.go +++ b/contrib/example-backend/options/serve.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/contrib/example-backend/server.go b/contrib/example-backend/server.go index 7dc5e397..b52b8e2c 100644 --- a/contrib/example-backend/server.go +++ b/contrib/example-backend/server.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,10 +22,7 @@ import ( "fmt" "net" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/dynamic" - "k8s.io/klog/v2" - + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" "go.bytebuilders.dev/kube-bind/contrib/example-backend/controllers/clusterbinding" "go.bytebuilders.dev/kube-bind/contrib/example-backend/controllers/serviceexport" "go.bytebuilders.dev/kube-bind/contrib/example-backend/controllers/serviceexportrequest" @@ -33,7 +30,10 @@ import ( "go.bytebuilders.dev/kube-bind/contrib/example-backend/deploy" examplehttp "go.bytebuilders.dev/kube-bind/contrib/example-backend/http" examplekube "go.bytebuilders.dev/kube-bind/contrib/example-backend/kubernetes" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/client-go/dynamic" + "k8s.io/klog/v2" ) type Server struct { @@ -114,7 +114,7 @@ func NewServer(config *Config) (*Server, error) { config.Options.TestingAutoSelect, signingKey, encryptionKey, - kubebindv1alpha1.Scope(config.Options.ConsumerScope), + v1alpha1.Scope(config.Options.ConsumerScope), s.Kubernetes, config.ApiextensionsInformers.Apiextensions().V1().CustomResourceDefinitions().Lister(), ) @@ -126,7 +126,7 @@ func NewServer(config *Config) (*Server, error) { // construct controllers s.ClusterBinding, err = clusterbinding.NewController( config.ClientConfig, - kubebindv1alpha1.Scope(config.Options.ConsumerScope), + v1alpha1.Scope(config.Options.ConsumerScope), config.BindInformers.KubeBind().V1alpha1().ClusterBindings(), config.BindInformers.KubeBind().V1alpha1().APIServiceExports(), config.KubeInformers.Rbac().V1().ClusterRoles(), @@ -139,7 +139,7 @@ func NewServer(config *Config) (*Server, error) { } s.ServiceNamespace, err = servicenamespace.NewController( config.ClientConfig, - kubebindv1alpha1.Scope(config.Options.ConsumerScope), + v1alpha1.Scope(config.Options.ConsumerScope), config.BindInformers.KubeBind().V1alpha1().APIServiceNamespaces(), config.BindInformers.KubeBind().V1alpha1().ClusterBindings(), config.BindInformers.KubeBind().V1alpha1().APIServiceExports(), @@ -160,8 +160,8 @@ func NewServer(config *Config) (*Server, error) { } s.ServiceExportRequest, err = serviceexportrequest.NewController( config.ClientConfig, - kubebindv1alpha1.Scope(config.Options.ConsumerScope), - kubebindv1alpha1.Isolation(config.Options.ClusterScopedIsolation), + v1alpha1.Scope(config.Options.ConsumerScope), + v1alpha1.Isolation(config.Options.ClusterScopedIsolation), config.BindInformers.KubeBind().V1alpha1().APIServiceExportRequests(), config.BindInformers.KubeBind().V1alpha1().APIServiceExports(), config.ApiextensionsInformers.Apiextensions().V1().CustomResourceDefinitions(), diff --git a/contrib/example-backend/template/files.go b/contrib/example-backend/template/files.go index 96179b5d..8bc9c803 100644 --- a/contrib/example-backend/template/files.go +++ b/contrib/example-backend/template/files.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/deploy/crd/kube-bind.appscode.com_apiservicebindings.yaml b/crds/kube-bind.appscode.com_apiservicebindings.yaml similarity index 99% rename from deploy/crd/kube-bind.appscode.com_apiservicebindings.yaml rename to crds/kube-bind.appscode.com_apiservicebindings.yaml index b2f9a95e..9524491d 100644 --- a/deploy/crd/kube-bind.appscode.com_apiservicebindings.yaml +++ b/crds/kube-bind.appscode.com_apiservicebindings.yaml @@ -1,9 +1,8 @@ + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 creationTimestamp: null name: apiservicebindings.kube-bind.appscode.com spec: diff --git a/deploy/crd/kube-bind.appscode.com_apiserviceexportrequests.yaml b/crds/kube-bind.appscode.com_apiserviceexportrequests.yaml similarity index 99% rename from deploy/crd/kube-bind.appscode.com_apiserviceexportrequests.yaml rename to crds/kube-bind.appscode.com_apiserviceexportrequests.yaml index bab2c929..3c160941 100644 --- a/deploy/crd/kube-bind.appscode.com_apiserviceexportrequests.yaml +++ b/crds/kube-bind.appscode.com_apiserviceexportrequests.yaml @@ -1,8 +1,8 @@ + +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 creationTimestamp: null name: apiserviceexportrequests.kube-bind.appscode.com spec: diff --git a/deploy/crd/kube-bind.appscode.com_apiserviceexports.yaml b/crds/kube-bind.appscode.com_apiserviceexports.yaml similarity index 99% rename from deploy/crd/kube-bind.appscode.com_apiserviceexports.yaml rename to crds/kube-bind.appscode.com_apiserviceexports.yaml index 608530d9..92c04b78 100644 --- a/deploy/crd/kube-bind.appscode.com_apiserviceexports.yaml +++ b/crds/kube-bind.appscode.com_apiserviceexports.yaml @@ -1,9 +1,8 @@ + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 creationTimestamp: null name: apiserviceexports.kube-bind.appscode.com spec: diff --git a/deploy/crd/kube-bind.appscode.com_apiservicenamespaces.yaml b/crds/kube-bind.appscode.com_apiservicenamespaces.yaml similarity index 97% rename from deploy/crd/kube-bind.appscode.com_apiservicenamespaces.yaml rename to crds/kube-bind.appscode.com_apiservicenamespaces.yaml index 1dedbc65..0c9c630f 100644 --- a/deploy/crd/kube-bind.appscode.com_apiservicenamespaces.yaml +++ b/crds/kube-bind.appscode.com_apiservicenamespaces.yaml @@ -1,9 +1,8 @@ + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 creationTimestamp: null name: apiservicenamespaces.kube-bind.appscode.com spec: diff --git a/deploy/crd/kube-bind.appscode.com_clusterbindings.yaml b/crds/kube-bind.appscode.com_clusterbindings.yaml similarity index 99% rename from deploy/crd/kube-bind.appscode.com_clusterbindings.yaml rename to crds/kube-bind.appscode.com_clusterbindings.yaml index 7c3ece28..d2d0563e 100644 --- a/deploy/crd/kube-bind.appscode.com_clusterbindings.yaml +++ b/crds/kube-bind.appscode.com_clusterbindings.yaml @@ -1,9 +1,8 @@ + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 creationTimestamp: null name: clusterbindings.kube-bind.appscode.com spec: diff --git a/crds/lib.go b/crds/lib.go new file mode 100644 index 00000000..852aec78 --- /dev/null +++ b/crds/lib.go @@ -0,0 +1,60 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the AppsCode Community License 1.0.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md + +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. +*/ + +package crds + +import ( + "embed" + "fmt" + + "k8s.io/apimachinery/pkg/runtime/schema" + "kmodules.xyz/client-go/apiextensions" + "sigs.k8s.io/yaml" +) + +//go:embed *.yaml +var fs embed.FS + +func load(filename string, o interface{}) error { + data, err := fs.ReadFile(filename) + if err != nil { + return err + } + return yaml.Unmarshal(data, o) +} + +func CustomResourceDefinition(gvr schema.GroupVersionResource) (*apiextensions.CustomResourceDefinition, error) { + var out apiextensions.CustomResourceDefinition + + v1file := fmt.Sprintf("%s_%s.yaml", gvr.Group, gvr.Resource) + if err := load(v1file, &out.V1); err != nil { + return nil, err + } + + if out.V1 == nil { + return nil, fmt.Errorf("missing crd yamls for gvr: %s", gvr) + } + + return &out, nil +} + +func MustCustomResourceDefinition(gvr schema.GroupVersionResource) *apiextensions.CustomResourceDefinition { + out, err := CustomResourceDefinition(gvr) + if err != nil { + panic(err) + } + return out +} \ No newline at end of file diff --git a/deploy/crd/bootstrap.go b/deploy/crd/bootstrap.go deleted file mode 100644 index 8872b270..00000000 --- a/deploy/crd/bootstrap.go +++ /dev/null @@ -1,181 +0,0 @@ -/* -Copyright 2021 The Kube Bind Authors. - -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. -*/ - -package crd - -import ( - "context" - "embed" - "fmt" - "sync" - "time" - - crdhelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - extensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver" - apiextensionsv1client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1" - "k8s.io/apimachinery/pkg/api/equality" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - kerrors "k8s.io/apimachinery/pkg/util/errors" - utilnet "k8s.io/apimachinery/pkg/util/net" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/util/retry" - "k8s.io/klog/v2" -) - -//go:embed *.yaml -var raw embed.FS - -// CreateFromFS creates the given CRDs using the target client from the -// provided filesystem and waits for it to become established. This call is blocking. -func CreateFromFS(ctx context.Context, client apiextensionsv1client.CustomResourceDefinitionInterface, fs embed.FS, grs ...metav1.GroupResource) error { - wg := sync.WaitGroup{} - bootstrapErrChan := make(chan error, len(grs)) - for _, gk := range grs { - wg.Add(1) - go func(gr metav1.GroupResource) { - defer wg.Done() - err := retryRetryableErrors(func() error { - return createSingleFromFS(ctx, client, gr, fs) - }) - // wait.Poll functions return ErrWaitTimeout instead the context cancellation error, for backward compatibility reasons, see: - // https://github.com/kubernetes/kubernetes/blob/b5f8cca701575678819b5e9e6372df989ab6799f/staging/src/k8s.io/apimachinery/pkg/util/wait/wait.go - // however, retryOnError swallows that error and replaces it for the last one, that is nil if it is still retrying, see: - // https://github.com/kubernetes/kubernetes/blob/ee81e5ebfad1b3f3c1112e7b83b0a5113286a3d3/pkg/client/unversioned/util.go - // if the context is cancelled, we have to inform the upper layers about that, so context error takes precedence. - if ctx.Err() != nil { - err = ctx.Err() - } - bootstrapErrChan <- err - }(gk) - } - wg.Wait() - close(bootstrapErrChan) - var bootstrapErrors []error - for err := range bootstrapErrChan { - bootstrapErrors = append(bootstrapErrors, err) - } - if err := kerrors.NewAggregate(bootstrapErrors); err != nil { - return fmt.Errorf("could not bootstrap CRDs: %w", err) - } - return nil -} - -// Create creates the given CRDs using the target client and waits -// for all of them to become established in parallel. This call is blocking. -func Create(ctx context.Context, client apiextensionsv1client.CustomResourceDefinitionInterface, grs ...metav1.GroupResource) error { - return CreateFromFS(ctx, client, raw, grs...) -} - -// CreateFromFS creates the given CRD using the target client from the -// provided filesystem and waits for it to become established. This call is blocking. -func createSingleFromFS(ctx context.Context, client apiextensionsv1client.CustomResourceDefinitionInterface, gr metav1.GroupResource, fs embed.FS) error { - crd, err := CRD(fs, gr) - if err != nil { - return err - } - - return CreateSingle(ctx, client, crd) -} - -// CRD returns an *apiextensionsv1.CustomResourceDefinition for the GroupResource specified by gr from fs. The embedded -// file's name must have the format _.yaml. -func CRD(fs embed.FS, gr metav1.GroupResource) (*apiextensionsv1.CustomResourceDefinition, error) { - raw, err := fs.ReadFile(fmt.Sprintf("%s_%s.yaml", gr.Group, gr.Resource)) - if err != nil { - return nil, fmt.Errorf("could not read CRD %s: %w", gr.String(), err) - } - - expectedGvk := &schema.GroupVersionKind{Group: apiextensionsv1.GroupName, Version: "v1", Kind: "CustomResourceDefinition"} - - obj, gvk, err := extensionsapiserver.Codecs.UniversalDeserializer().Decode(raw, expectedGvk, &apiextensionsv1.CustomResourceDefinition{}) - if err != nil { - return nil, fmt.Errorf("could not decode raw CRD %s: %w", gr.String(), err) - } - - if !equality.Semantic.DeepEqual(gvk, expectedGvk) { - return nil, fmt.Errorf("decoded CRD %s into incorrect GroupVersionKind, got %#v, wanted %#v", gr.String(), gvk, expectedGvk) - } - - crd, ok := obj.(*apiextensionsv1.CustomResourceDefinition) - if !ok { - return nil, fmt.Errorf("decoded CRD %s into incorrect type, got %T, wanted %T", gr.String(), obj, &apiextensionsv1.CustomResourceDefinition{}) - } - - return crd, nil -} - -func CreateSingle(ctx context.Context, client apiextensionsv1client.CustomResourceDefinitionInterface, rawCRD *apiextensionsv1.CustomResourceDefinition) error { - start := time.Now() - klog.V(4).Infof("Bootstrapping %v", rawCRD.Name) - - updateNeeded := false - crd, err := client.Get(ctx, rawCRD.Name, metav1.GetOptions{}) - if err != nil { - if apierrors.IsNotFound(err) { - crd, err = client.Create(ctx, rawCRD, metav1.CreateOptions{}) - if err != nil { - // If multiple post-start hooks specify the same CRD, they could race with each other, so we need to - // handle the scenario where another hook created this CRD after our Get() call returned not found. - if apierrors.IsAlreadyExists(err) { - // Re-get so we have the correct resourceVersion - crd, err = client.Get(ctx, rawCRD.Name, metav1.GetOptions{}) - if err != nil { - return fmt.Errorf("error getting CRD %s: %w", rawCRD.Name, err) - } - updateNeeded = true - } else { - return fmt.Errorf("error creating CRD %s: %w", rawCRD.Name, err) - } - } else { - klog.Infof("Bootstrapped CRD %v after %s", crd.Name, time.Since(start).String()) - } - } else { - return fmt.Errorf("error fetching CRD %s: %w", rawCRD.Name, err) - } - } else { - updateNeeded = true - } - - if updateNeeded { - rawCRD.ResourceVersion = crd.ResourceVersion - _, err := client.Update(ctx, rawCRD, metav1.UpdateOptions{}) - if err != nil { - return err - } - klog.Infof("Updated CRD %v after %s", rawCRD.Name, time.Since(start).String()) - } - - return wait.PollUntilContextCancel(ctx, 100*time.Millisecond, true, func(ctx context.Context) (bool, error) { - crd, err := client.Get(ctx, rawCRD.Name, metav1.GetOptions{}) - if err != nil { - if apierrors.IsNotFound(err) { - return false, fmt.Errorf("CRD %s was deleted before being established", rawCRD.Name) - } - return false, fmt.Errorf("error fetching CRD %s: %w", rawCRD.Name, err) - } - - return crdhelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established), nil - }) -} - -func retryRetryableErrors(f func() error) error { - return retry.OnError(retry.DefaultBackoff, func(err error) bool { - return utilnet.IsConnectionRefused(err) || apierrors.IsTooManyRequests(err) || apierrors.IsConflict(err) - }, f) -} diff --git a/deploy/examples/crd-mangodb.yaml b/deploy/examples/crd-mangodb.yaml deleted file mode 100644 index fe408b65..00000000 --- a/deploy/examples/crd-mangodb.yaml +++ /dev/null @@ -1,41 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: mangodbs.mangodb.com - labels: - kube-bind.appscode.com/exported: "true" -spec: - group: mangodb.com - names: - kind: MangoDB - listKind: MangoDBList - plural: mangodbs - singular: mangodb - scope: Namespaced - versions: - - name: v1alpha1 - served: true - storage: true - schema: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - tier: - type: string - enum: - - Dedicated - - Shared - default: Shared - status: - type: object - properties: - phase: - type: string - required: - - spec - subresources: - status: {} - diff --git a/deploy/examples/crd-tangodb.yaml b/deploy/examples/crd-tangodb.yaml deleted file mode 100644 index 1ac0339a..00000000 --- a/deploy/examples/crd-tangodb.yaml +++ /dev/null @@ -1,41 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: tangodbs.tangodb.com - labels: - kube-bind.appscode.com/exported: "true" -spec: - group: tangodb.com - names: - kind: TangoDB - listKind: TangoDBList - plural: tangodbs - singular: tangodb - scope: Namespaced - versions: - - name: v1alpha1 - served: true - storage: true - schema: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - tier: - type: string - enum: - - Dedicated - - Shared - default: Shared - status: - type: object - properties: - phase: - type: string - required: - - spec - subresources: - status: {} - diff --git a/deploy/examples/servicenamespace-example.yaml b/deploy/examples/servicenamespace-example.yaml deleted file mode 100644 index 31f2db2d..00000000 --- a/deploy/examples/servicenamespace-example.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kube-bind.appscode.com/v1alpha1 -kind: APIServiceNamespace -metadata: - name: example -spec: {} \ No newline at end of file diff --git a/deploy/konnector/bootstrap.go b/deploy/konnector/bootstrap.go index b99d1cf9..1719e8c3 100644 --- a/deploy/konnector/bootstrap.go +++ b/deploy/konnector/bootstrap.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,11 +20,11 @@ import ( "context" "embed" + "go.bytebuilders.dev/kube-bind/pkg/bootstrap" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" - - "go.bytebuilders.dev/kube-bind/pkg/bootstrap" ) //go:embed *.yaml diff --git a/deploy/patches/kube-bind.appscode.com_apiserviceexportrequests.yaml-patch b/deploy/patches/kube-bind.appscode.com_apiserviceexportrequests.yaml-patch deleted file mode 100644 index 4aa3602b..00000000 --- a/deploy/patches/kube-bind.appscode.com_apiserviceexportrequests.yaml-patch +++ /dev/null @@ -1,3 +0,0 @@ -- op: add - path: /spec/versions/name=v1alpha1/schema/openAPIV3Schema/properties/status/default - value: {} diff --git a/go.mod b/go.mod index 7d043359..2894b648 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/evanphx/json-patch v5.7.0+incompatible github.com/fatih/color v1.12.0 github.com/google/go-cmp v0.6.0 - github.com/gorilla/mux v1.8.0 + github.com/gorilla/mux v1.8.1 github.com/gorilla/securecookie v1.1.1 github.com/headzoo/surf v1.0.1 github.com/kcp-dev/kcp/pkg/apis v0.11.0 @@ -21,7 +21,7 @@ require ( github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace github.com/stretchr/testify v1.8.4 - github.com/vmihailenco/msgpack/v4 v4.3.12 + github.com/vmihailenco/msgpack/v4 v4.3.13 golang.org/x/oauth2 v0.12.0 google.golang.org/grpc v1.59.0 gopkg.in/headzoo/surf.v1 v1.0.1 @@ -31,13 +31,11 @@ require ( k8s.io/apiserver v0.29.0 k8s.io/cli-runtime v0.29.0 k8s.io/client-go v0.29.0 - k8s.io/code-generator v0.29.0 k8s.io/component-base v0.29.0 k8s.io/klog/v2 v2.110.1 k8s.io/utils v0.0.0-20230726121419-3b25d923346b kmodules.xyz/client-go v0.29.9 sigs.k8s.io/controller-runtime v0.17.0 - sigs.k8s.io/controller-tools v0.10.0 sigs.k8s.io/yaml v1.4.0 ) @@ -58,7 +56,7 @@ require ( github.com/evanphx/json-patch/v5 v5.8.0 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/frankban/quicktest v1.14.3 // indirect + github.com/frankban/quicktest v1.14.6 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.4.1 // indirect @@ -67,7 +65,6 @@ require ( github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect - github.com/gobuffalo/flect v0.2.5 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -99,6 +96,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nxadm/tail v1.4.8 // indirect github.com/onsi/gomega v1.30.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect @@ -133,14 +131,12 @@ require ( go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 // indirect - golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.16.1 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/mergo v0.3.13 // indirect gomodules.xyz/pointer v0.1.0 // indirect @@ -153,7 +149,6 @@ require ( gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect rsc.io/qr v0.2.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 // indirect diff --git a/go.sum b/go.sum index 89b7c5af..6bb55743 100644 --- a/go.sum +++ b/go.sum @@ -65,13 +65,13 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= @@ -88,8 +88,6 @@ github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gobuffalo/flect v0.2.5 h1:H6vvsv2an0lalEaCDRThvtBfmg44W/QHXBCYUXf/6S4= -github.com/gobuffalo/flect v0.2.5/go.mod h1:1ZyCLIbg0YD7sDkzvFdPoOydPtD8y9JQnrOROolUcM8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -127,14 +125,12 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ= github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= @@ -143,8 +139,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= @@ -182,9 +178,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -237,6 +231,7 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -252,7 +247,7 @@ github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lne github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -285,8 +280,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= -github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/msgpack/v4 v4.3.13 h1:A2wsiTbvp63ilDaWmsk2wjx6xZdxQOvpiNlKBGKKXKI= +github.com/vmihailenco/msgpack/v4 v4.3.13/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= @@ -360,8 +355,6 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -389,6 +382,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -419,7 +413,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= @@ -470,7 +463,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/headzoo/surf.v1 v1.0.1 h1:oDBy9b5NlTb2Hvl3hF8NN+Qy7ypC9/g5YDP85pPh13k= gopkg.in/headzoo/surf.v1 v1.0.1/go.mod h1:T0BH8276y+OPL0E4tisxCFjBVIAKGbwdYU7AS7/EpQQ= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -505,13 +497,8 @@ k8s.io/cli-runtime v0.29.0 h1:q2kC3cex4rOBLfPOnMSzV2BIrrQlx97gxHJs21KxKS4= k8s.io/cli-runtime v0.29.0/go.mod h1:VKudXp3X7wR45L+nER85YUzOQIru28HQpXr0mTdeCrk= k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/code-generator v0.29.0 h1:2LQfayGDhaIlaamXjIjEQlCMy4JNCH9lrzas4DNW1GQ= -k8s.io/code-generator v0.29.0/go.mod h1:5bqIZoCxs2zTRKMWNYqyQWW/bajc+ah4rh0tMY8zdGA= k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= -k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= -k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kms v0.29.0 h1:KJ1zaZt74CgvgV3NR7tnURJ/mJOKC5X3nwon/WdwgxI= @@ -528,8 +515,6 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2S sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y= sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s= sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= -sigs.k8s.io/controller-tools v0.10.0 h1:0L5DTDTFB67jm9DkfrONgTGmfc/zYow0ZaHyppizU2U= -sigs.k8s.io/controller-tools v0.10.0/go.mod h1:uvr0EW6IsprfB0jpQq6evtKy+hHyHCXNfdWI5ONPx94= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= @@ -538,6 +523,5 @@ sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/hack/boilerplate/boilerplate.Dockerfile.txt b/hack/boilerplate/boilerplate.Dockerfile.txt deleted file mode 100644 index 3b4ee55a..00000000 --- a/hack/boilerplate/boilerplate.Dockerfile.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright YEAR The Kube Bind Authors. -# -# 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. - diff --git a/hack/boilerplate/boilerplate.Makefile.txt b/hack/boilerplate/boilerplate.Makefile.txt deleted file mode 100644 index 3b4ee55a..00000000 --- a/hack/boilerplate/boilerplate.Makefile.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright YEAR The Kube Bind Authors. -# -# 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. - diff --git a/hack/boilerplate/boilerplate.py.txt b/hack/boilerplate/boilerplate.py.txt deleted file mode 100644 index 3b4ee55a..00000000 --- a/hack/boilerplate/boilerplate.py.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright YEAR The Kube Bind Authors. -# -# 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. - diff --git a/hack/build.sh b/hack/build.sh new file mode 100755 index 00000000..6541be34 --- /dev/null +++ b/hack/build.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +# Copyright AppsCode Inc. and Contributors +# +# Licensed under the AppsCode Community License 1.0.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md +# +# 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. + +# Copyright AppsCode Inc. and Contributors. +# +# 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. + +set -eou pipefail + +if [ -z "${OS:-}" ]; then + echo "OS must be set" + exit 1 +fi +if [ -z "${ARCH:-}" ]; then + echo "ARCH must be set" + exit 1 +fi +if [ -z "${VERSION:-}" ]; then + echo "VERSION must be set" + exit 1 +fi + +export CGO_ENABLED=0 +export GOARCH="${ARCH}" +export GOOS="${OS}" +export GO111MODULE=on +export GOFLAGS="-mod=vendor" + +ENFORCE_LICENSE=${ENFORCE_LICENSE:-} +if [ ! -z "${git_tag:-}" ]; then + ENFORCE_LICENSE=true +fi +if [ "$ENFORCE_LICENSE" != "true" ]; then + ENFORCE_LICENSE=false +fi + +# ref: https://medium.com/golangspec/blocks-in-go-2f68768868f6 +# ref: https://dave.cheney.net/2020/05/02/mid-stack-inlining-in-go +# -gcflags="all=-N -l" \ +go install \ + -installsuffix "static" \ + -ldflags " \ + -X main.Version=${VERSION} \ + -X main.VersionStrategy=${version_strategy:-} \ + -X main.GitTag=${git_tag:-} \ + -X main.GitBranch=${git_branch:-} \ + -X main.CommitHash=${commit_hash:-} \ + -X main.CommitTimestamp=${commit_timestamp:-} \ + -X main.GoVersion=$(go version | cut -d " " -f 3) \ + -X main.Compiler=$(go env CC) \ + -X main.Platform=${OS}/${ARCH} \ + -X 'go.bytebuilders.dev/license-verifier/info.EnforceLicense=${ENFORCE_LICENSE}' \ + -X 'go.bytebuilders.dev/license-verifier/info.LicenseCA=$(curl -fsSL https://licenses.appscode.com/certificates/ca.crt)' \ + -X 'go.bytebuilders.dev/license-verifier/info.ProductOwnerName=${PRODUCT_OWNER_NAME}' \ + -X 'go.bytebuilders.dev/license-verifier/info.ProductName=${PRODUCT_NAME}' \ + " \ + ./... diff --git a/hack/dex-config-dev.yaml b/hack/dex-config-dev.yaml deleted file mode 100644 index 9e2bdbe9..00000000 --- a/hack/dex-config-dev.yaml +++ /dev/null @@ -1,149 +0,0 @@ -# DEPRECATED: use config.yaml.dist and config.dev.yaml examples in the repository root. -# TODO: keep this until all references are updated. - -# The base path of dex and the external name of the OpenID Connect service. -# This is the canonical URL that all clients MUST use to refer to dex. If a -# path is provided, dex's HTTP service will listen at a non-root URL. -issuer: http://127.0.0.1:5556/dex - -# The storage configuration determines where dex stores its state. Supported -# options include SQL flavors and Kubernetes third party resources. -# -# See the documentation (https://dexidp.io/docs/storage/) for further information. -storage: - type: memory - config: - file: examples/dex.db - - # type: mysql - # config: - # host: localhost - # port: 3306 - # database: dex - # user: mysql - # password: mysql - # ssl: - # mode: "false" - - # type: postgres - # config: - # host: localhost - # port: 5432 - # database: dex - # user: postgres - # password: postgres - # ssl: - # mode: disable - - # type: etcd - # config: - # endpoints: - # - http://localhost:2379 - # namespace: dex/ - - # type: kubernetes - # config: - # kubeConfigFile: $HOME/.kube/config - -# Configuration for the HTTP endpoints. -web: - http: 0.0.0.0:5556 - # Uncomment for HTTPS options. - # https: 127.0.0.1:5554 - # tlsCert: /etc/dex/tls.crt - # tlsKey: /etc/dex/tls.key - -# Configuration for dex appearance -# frontend: -# issuer: dex -# logoURL: theme/logo.png -# dir: web/ -# theme: light - -# Configuration for telemetry -telemetry: - http: 0.0.0.0:5558 - # enableProfiling: true - -# Uncomment this block to enable the gRPC API. This values MUST be different -# from the HTTP endpoints. -grpc: - addr: 127.0.0.1:5557 -# tlsCert: examples/grpc-client/server.crt -# tlsKey: examples/grpc-client/server.key -# tlsClientCA: examples/grpc-client/ca.crt - -# Uncomment this block to enable configuration for the expiration time durations. -# Is possible to specify units using only s, m and h suffixes. -# expiry: -# deviceRequests: "5m" -# signingKeys: "6h" -# idTokens: "24h" -# refreshTokens: -# reuseInterval: "3s" -# validIfNotUsedFor: "2160h" # 90 days -# absoluteLifetime: "3960h" # 165 days - -# Options for controlling the logger. -# logger: -# level: "debug" -# format: "text" # can also be "json" - -# Default values shown below -oauth2: - # use ["code", "token", "id_token"] to enable implicit flow for web-only clients -# responseTypes: [ "code" ] # also allowed are "token" and "id_token" - # By default, Dex will ask for approval to share data with application - # (approval for sharing data from connected IdP to Dex is separate process on IdP) - skipApprovalScreen: true - # If only one authentication method is enabled, the default behavior is to - # go directly to it. For connected IdPs, this redirects the browser away - # from application to upstream provider such as the Google login page -# alwaysShowLoginScreen: false - # Uncomment the passwordConnector to use a specific connector for password grants -# passwordConnector: local - -# Instead of reading from an external storage, use this list of clients. -# -# If this option isn't chosen clients may be added through the gRPC API. -staticClients: -- id: kube-bind - redirectURIs: - - 'http://127.0.0.1:8080/callback' - name: 'Kube Bind' - secret: ZXhhbXBsZS1hcHAtc2VjcmV0 - -# - id: example-device-client -# redirectURIs: -# - /device/callback -# name: 'Static Client for Device Flow' -# public: true -connectors: -- type: mockCallback - id: mock - name: Example -# - type: google -# id: google -# name: Google -# config: -# issuer: https://accounts.google.com -# # Connector config values starting with a "$" will read from the environment. -# clientID: $GOOGLE_CLIENT_ID -# clientSecret: $GOOGLE_CLIENT_SECRET -# redirectURI: http://127.0.0.1:5556/dex/callback -# hostedDomains: -# - $GOOGLE_HOSTED_DOMAIN - -# Let dex keep a list of passwords which can be used to login to dex. -# enablePasswordDB: true - -# A static list of passwords to login the end user. By identifying here, dex -# won't look in its underlying storage for passwords. -# -# If this option isn't chosen users may be added through the gRPC API. -# staticPasswords: -# - email: "admin@example.com" -# # bcrypt hash of the string "password": $(echo password | htpasswd -BinC 10 admin | cut -d: -f2) -# hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" -# username: "admin" -# userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" diff --git a/hack/e2e.sh b/hack/e2e.sh new file mode 100755 index 00000000..24e4f7b4 --- /dev/null +++ b/hack/e2e.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Copyright AppsCode Inc. and Contributors +# +# Licensed under the AppsCode Community License 1.0.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md +# +# 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. + +# Copyright AppsCode Inc. and Contributors. +# +# 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. + +set -eou pipefail + +export CGO_ENABLED=1 +export GO111MODULE=on +export GOFLAGS="-mod=vendor" + +GINKGO_ARGS=${GINKGO_ARGS:-} +TEST_ARGS=${TEST_ARGS:-} +DOCKER_REGISTRY=${DOCKER_REGISTRY:-} + +echo "Running e2e tests:" +cmd="ginkgo -r --v -race --progress --trace --noisyPendings=false ${GINKGO_ARGS} test -- --docker-registry=${DOCKER_REGISTRY} ${TEST_ARGS}" +echo $cmd +$cmd diff --git a/hack/fmt.sh b/hack/fmt.sh new file mode 100755 index 00000000..69ce2e47 --- /dev/null +++ b/hack/fmt.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Copyright AppsCode Inc. and Contributors +# +# Licensed under the AppsCode Community License 1.0.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md +# +# 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. + +# Copyright AppsCode Inc. and Contributors. +# +# 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. + +set -eou pipefail + +export CGO_ENABLED=0 +export GO111MODULE=on +export GOFLAGS="-mod=vendor" + +TARGETS="$@" + +if [ -n "$TARGETS" ]; then + echo "Running reimport.py" + cmd="reimport3.py ${REPO_PKG} ${TARGETS}" + $cmd + echo + + echo "Running goimports:" + cmd="goimports -w ${TARGETS}" + echo "$cmd" + $cmd + echo + + echo "Running gofmt:" + cmd="gofmt -s -w ${TARGETS}" + echo "$cmd" + $cmd + echo +fi + +echo "Running shfmt:" +cmd="find . -path ./vendor -prune -o -name '*.sh' -exec shfmt -l -w -ci -i 4 {} \;" +echo "$cmd" +eval "$cmd" # xref: https://stackoverflow.com/a/5615748/244009 +echo diff --git a/hack/go-install.sh b/hack/go-install.sh deleted file mode 100755 index baa7dbc0..00000000 --- a/hack/go-install.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2021 The Kube Bind Authors. -# -# 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. - -# Originally copied from -# https://github.com/kubernetes-sigs/cluster-api-provider-gcp/blob/c26a68b23e9317323d5d37660fe9d29b3d2ff40c/scripts/go_install.sh - -set -o errexit -set -o nounset -set -o pipefail - -if [[ -z "${1:-}" ]]; then - echo "must provide module as first parameter" - exit 1 -fi - -if [[ -z "${2:-}" ]]; then - echo "must provide binary name as second parameter" - exit 1 -fi - -if [[ -z "${3:-}" ]]; then - echo "must provide version as third parameter" - exit 1 -fi - -if [[ -z "${GOBIN:-}" ]]; then - echo "GOBIN is not set. Must set GOBIN to install the bin in a specified directory." - exit 1 -fi - -mkdir -p "${GOBIN}" - -tmp_dir=$(mktemp -d -t goinstall_XXXXXXXXXX) -function clean { - rm -rf "${tmp_dir}" -} -trap clean EXIT - -rm "${GOBIN}/${2}"* > /dev/null 2>&1 || true - -cd "${tmp_dir}" - -# create a new module in the tmp directory -go mod init fake/mod - -# install the golang module specified as the first argument -go install -tags tools "${1}@${3}" -mv "${GOBIN}/${2}" "${GOBIN}/${2}-${3}" -ln -sf "${GOBIN}/${2}-${3}" "${GOBIN}/${2}" \ No newline at end of file diff --git a/hack/import_hacks.go b/hack/import_hacks.go new file mode 100644 index 00000000..0eee7e62 --- /dev/null +++ b/hack/import_hacks.go @@ -0,0 +1,25 @@ +/* +Copyright AppsCode Inc. and Contributors. + +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. +*/ + +package hack + +import ( + _ "k8s.io/apimachinery/pkg/api/resource" + _ "k8s.io/apimachinery/pkg/apis/meta/v1" + _ "k8s.io/apimachinery/pkg/runtime" + _ "k8s.io/apimachinery/pkg/runtime/schema" + _ "k8s.io/apimachinery/pkg/util/intstr" +) diff --git a/hack/krew/plugin.yaml b/hack/krew/plugin.yaml new file mode 100644 index 00000000..9f7c6ce8 --- /dev/null +++ b/hack/krew/plugin.yaml @@ -0,0 +1,71 @@ +apiVersion: krew.googlecontainertools.github.com/v1alpha2 +kind: Plugin +metadata: + name: dba +spec: + version: {VERSION} + homepage: https://kubedb.com + shortDescription: kubectl plugin for KubeDB by AppsCode + description: | + This plugin provides a list of commands to interact with KubeDB custom resources. + platforms: + - selector: + matchLabels: + os: darwin + arch: amd64 + uri: https://github.com/bytebuilders/kube-bind/releases/download/{VERSION}/kubectl-connect-darwin-amd64.tar.gz + sha256: {SHA256SUM_DARWIN_AMD64} + files: + - from: "*" + to: "." + bin: kubectl-connect-darwin-amd64 + - selector: + matchLabels: + os: darwin + arch: arm64 + uri: https://github.com/bytebuilders/kube-bind/releases/download/{VERSION}/kubectl-connect-darwin-arm64.tar.gz + sha256: {SHA256SUM_DARWIN_ARM64} + files: + - from: "*" + to: "." + bin: kubectl-connect-darwin-arm64 + - selector: + matchLabels: + os: linux + arch: amd64 + uri: https://github.com/bytebuilders/kube-bind/releases/download/{VERSION}/kubectl-connect-linux-amd64.tar.gz + sha256: {SHA256SUM_LINUX_AMD64} + files: + - from: "*" + to: "." + bin: kubectl-connect-linux-amd64 + - selector: + matchLabels: + os: linux + arch: arm + uri: https://github.com/bytebuilders/kube-bind/releases/download/{VERSION}/kubectl-connect-linux-arm.tar.gz + sha256: {SHA256SUM_LINUX_ARM} + files: + - from: "*" + to: "." + bin: kubectl-connect-linux-arm + - selector: + matchLabels: + os: linux + arch: arm64 + uri: https://github.com/bytebuilders/kube-bind/releases/download/{VERSION}/kubectl-connect-linux-arm64.tar.gz + sha256: {SHA256SUM_LINUX_ARM64} + files: + - from: "*" + to: "." + bin: kubectl-connect-linux-arm64 + - selector: + matchLabels: + os: windows + arch: amd64 + uri: https://github.com/bytebuilders/kube-bind/releases/download/{VERSION}/kubectl-connect-windows-amd64.zip + sha256: {SHA256SUM_WINDOWS_AMD64} + files: + - from: "*" + to: "." + bin: kubectl-connect-windows-amd64.exe diff --git a/hack/lib.sh b/hack/lib.sh deleted file mode 100755 index 47b7b551..00000000 --- a/hack/lib.sh +++ /dev/null @@ -1,434 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2022 The Kube Bind Authors. -# -# 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. - - -### Contains commonly used functions for the other scripts. - -# Required for signal propagation to work so -# the cleanup trap gets executed when a script -# receives a SIGINT -set -o monitor - -# Get the operating system -# Possible values are: -# * linux for linux -# * darwin for macOS -# -# usage: -# if [ "${OS}" == "darwin" ]; then -# # do macos stuff -# fi -OS="$(echo $(uname) | tr '[:upper:]' '[:lower:]')" - -worker_name() { - echo "${KUBERMATIC_WORKERNAME:-$(uname -n)}" | tr -cd '[:alnum:]' | tr '[:upper:]' '[:lower:]' -} - -retry() { - # Works only with bash but doesn't fail on other shells - start_time=$(date +%s) - set +e - actual_retry $@ - rc=$? - set -e - elapsed_time=$(($(date +%s) - $start_time)) - write_junit "$rc" "$elapsed_time" - return $rc -} - -# We use an extra wrapping to write junit and have a timer -actual_retry() { - retries=$1 - shift - - count=0 - delay=1 - until "$@"; do - rc=$? - count=$((count + 1)) - if [ $count -lt "$retries" ]; then - echo "Retry $count/$retries exited $rc, retrying in $delay seconds..." > /dev/stderr - sleep $delay - else - echo "Retry $count/$retries exited $rc, no more retries left." > /dev/stderr - return $rc - fi - delay=$((delay * 2)) - done - return 0 -} - -echodate() { - # do not use -Is to keep this compatible with macOS - echo "[$(date +%Y-%m-%dT%H:%M:%S%:z)]" "$@" -} - -write_junit() { - # Doesn't make any sense if we don't know a testname - if [ -z "${TEST_NAME:-}" ]; then return; fi - # Only run in CI - if [ -z "${ARTIFACTS:-}" ]; then return; fi - - rc=$1 - duration=${2:-0} - errors=0 - failure="" - if [ "$rc" -ne 0 ]; then - errors=1 - failure='Step failed' - fi - TEST_CLASS="${TEST_CLASS:-Kubermatic}" - cat << EOF > ${ARTIFACTS}/junit.$(echo $TEST_NAME | sed 's/ /_/g' | tr '[:upper:]' '[:lower:]').xml - - - - - $failure - - - -EOF -} - -containerize() { - local cmd="$1" - local image="${CONTAINERIZE_IMAGE:-quay.io/kubermatic/util:2.0.0}" - local gocache="${CONTAINERIZE_GOCACHE:-/tmp/.gocache}" - local gomodcache="${CONTAINERIZE_GOMODCACHE:-/tmp/.gomodcache}" - local skip="${NO_CONTAINERIZE:-}" - - # short-circuit containerize when in some cases it needs to be avoided - [ -n "$skip" ] && return - - if ! [ -f /.dockerenv ]; then - echodate "Running $cmd in a Docker container using $image..." - mkdir -p "$gocache" - mkdir -p "$gomodcache" - - exec docker run \ - -v "$PWD":/go/src/k8c.io/kubermatic \ - -v "$gocache":"$gocache" \ - -v "$gomodcache":"$gomodcache" \ - -w /go/src/k8c.io/kubermatic \ - -e "GOCACHE=$gocache" \ - -e "GOMODCACHE=$gomodcache" \ - -u "$(id -u):$(id -g)" \ - --entrypoint="$cmd" \ - --rm \ - -it \ - $image $@ - - exit $? - fi -} - -ensure_github_host_pubkey() { - # check whether we already have a known_hosts entry for Github - if ssh-keygen -F github.com > /dev/null 2>&1; then - echo " [*] Github's SSH host key already present" > /dev/stderr - else - local github_rsa_key - # https://help.github.com/en/github/authenticating-to-github/githubs-ssh-key-fingerprints - github_rsa_key="github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" - - echo " [*] Adding Github's SSH host key to known hosts" > /dev/stderr - mkdir -p "$HOME/.ssh" - chmod 700 "$HOME/.ssh" - echo "$github_rsa_key" >> "$HOME/.ssh/known_hosts" - chmod 600 "$HOME/.ssh/known_hosts" - fi -} - -vault_ci_login() { - # already logged in - if [ -n "${VAULT_TOKEN:-}" ]; then - return 0 - fi - - # check environment variables - if [ -z "${VAULT_ROLE_ID:-}" ] || [ -z "${VAULT_SECRET_ID:-}" ]; then - echo "VAULT_ROLE_ID and VAULT_SECRET_ID must be set to programmatically authenticate against Vault." - return 1 - fi - - local token - token=$(vault write --format=json auth/approle/login "role_id=$VAULT_ROLE_ID" "secret_id=$VAULT_SECRET_ID" | jq -r '.auth.client_token') - - export VAULT_TOKEN="$token" -} - -get_latest_dashboard_hash() { - local FOR_BRANCH="$1" - - ensure_github_host_pubkey - git config --global core.sshCommand 'ssh -o CheckHostIP=no -i /ssh/id_rsa' - local DASHBOARD_URL="git@github.com:kubermatic/dashboard.git" - - # `local` always sets the rc to 0, so declare as local _before_ doing the substitution - # which may fail - local HASH - HASH="$(retry 5 git ls-remote "$DASHBOARD_URL" "refs/heads/$FOR_BRANCH" | awk '{print $1}')" - echodate "The latest dashboard hash for $FOR_BRANCH is $HASH" > /dev/stderr - echo "$HASH" -} - -# This should only be used for release branches, as it only fetches the last 25 commits -# for checking for tags. -get_latest_dashboard_tag() { - local FOR_BRANCH="$1" - local DEPTH="${2:-25}" - - ensure_github_host_pubkey - git config --global core.sshCommand 'ssh -o CheckHostIP=no -i /ssh/id_rsa' - local DASHBOARD_URL="git@github.com:kubermatic/dashboard.git" - - local TMPDIR - TMPDIR=$(mktemp -d dashboard.XXXXX) - - # git ls-remote cannot list tags in a meaningful way, so we have to clone the repo - echodate "Cloning dashboard repository to find tags in $FOR_BRANCH branch..." > /dev/stderr - git clone -b "$FOR_BRANCH" --single-branch --depth $DEPTH "$DASHBOARD_URL" "$TMPDIR" - - local TAG - TAG="$(git --git-dir $TMPDIR/.git describe --abbrev=0 --tags --first-parent)" - - echodate "The latest dashboard tag in $FOR_BRANCH is $TAG" > /dev/stderr - echo "$TAG" -} - -check_dashboard_tag() { - local TAG="$1" - - ensure_github_host_pubkey - git config --global core.sshCommand 'ssh -o CheckHostIP=no -i /ssh/id_rsa' - local DASHBOARD_URL="git@github.com:kubermatic/dashboard.git" - - retry 5 git ls-remote "$DASHBOARD_URL" "refs/tags/$TAG" -} - -format_dashboard() { - local filename="$1" - local tmpfile="$filename.tmp" - - cat "$filename" | - jq '(.templating.list[] | select(.type=="query") | .options) = []' | - jq '(.templating.list[] | select(.type=="query") | .refresh) = 2' | - jq '(.templating.list[] | select(.type=="query") | .current) = {}' | - jq '(.templating.list[] | select(.type=="datasource") | .current) = {}' | - jq '(.templating.list[] | select(.type=="interval") | .current) = {}' | - jq '(.panels[] | select(.scopedVars!=null) | .scopedVars) = {}' | - jq '(.annotations.list) = []' | - jq '(.links) = []' | - jq '(.refresh) = "30s"' | - jq '(.time.from) = "now-6h"' | - jq '(.editable) = true' | - jq '(.panels[] | select(.type!="row") | .editable) = true' | - jq '(.panels[] | select(.type!="row") | .transparent) = true' | - jq '(.panels[] | select(.type!="row") | .timeRegions) = []' | - jq '(.hideControls) = false' | - jq '(.time.to) = "now"' | - jq '(.timezone) = ""' | - jq '(.graphTooltip) = 1' | - jq 'del(.panels[] | select(.repeatPanelId!=null))' | - jq 'del(.id)' | - jq 'del(.iteration)' | - jq --sort-keys '.' > "$tmpfile" - - mv "$tmpfile" "$filename" -} - -# appendTrap appends to existing traps, if any. It is needed because Bash replaces existing handlers -# rather than appending: https://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal -# Needing this func is a strong indicator that Bash is not the right language anymore. Also, this -# basically needs unit tests. -appendTrap() { - command="$1" - signal="$2" - - # Have existing traps, must append - if [[ "$(trap -p | grep $signal)" ]]; then - existingHandlerName="$(trap -p | grep $signal | awk '{print $3}' | tr -d "'")" - - newHandlerName="${command}_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13)" - # Need eval to get a random func name - eval "$newHandlerName() { $command; $existingHandlerName; }" - echodate "Appending $command as trap for $signal, existing command $existingHandlerName" - trap $newHandlerName $signal - # First trap - else - echodate "Using $command as trap for $signal" - trap $command $signal - fi -} - -# returns the current time as a number of milliseconds -nowms() { - echo $(($(date +%s%N) / 1000000)) -} - -# returns the number of milliseconds elapsed since the given time -elapsed() { - echo $(($(nowms) - $1)) -} - -# pushes a Prometheus metric to a pushgateway -pushMetric() { - local metric="$1" - local value="$2" - local labels="${3:-}" - local kind="${4:-gauge}" - local help="${5:-}" - local pushgateway="${PUSHGATEWAY_URL:-}" - local job="ci" - local instance="${PROW_JOB_ID:-}" - local prowjob="${JOB_NAME:-}" - - if [ -z "$pushgateway" ]; then - return - fi - - local payload="# TYPE $metric $kind" - - if [ -n "$help" ]; then - payload="$payload\n# HELP $metric $help" - fi - - if [ -n "$labels" ]; then - labels=",$labels" - fi - - payload="$payload\n$metric{prowjob=\"$prowjob\"$labels} $value\n" - - echo -e "$payload" | curl --data-binary @- -s "$pushgateway/metrics/job/$job/instance/$instance" -} - -pushElapsed() { - pushMetric "$1" $(elapsed $2) "${3:-}" "${4:-}" "${5:-}" -} - -# err print an error log to stderr -err() { - echo "$(date) E: $*" >> /dev/stderr -} - -# fatal can be used to print logs to stderr -fatal() { - echo "$(date) F: $*" >> /dev/stderr - exit 1 -} - -check_all_deployments_ready() { - local namespace="$1" - - # check that Deployments have been created - local deployments - deployments=$(kubectl -n $namespace get deployments -o json) - - if [ $(echo "$deployments" | jq '.items | length') -eq 0 ]; then - echodate "No Deployments created yet." - return 1 - fi - - # check that all Deployments are ready - local unready - unready=$(echo "$deployments" | jq -r '[.items[] | select(.spec.replicas > 0) | select (.status.availableReplicas < .spec.replicas) | .metadata.name] | @tsv') - if [ -n "$unready" ]; then - echodate "Not all Deployments have finished rolling out, namely: $unready" - return 1 - fi - - return 0 -} - -cleanup_kubermatic_clusters_in_kind() { - # Tolerate errors and just continue - set +e - # Clean up clusters - echodate "Cleaning up clusters..." - kubectl delete cluster --all --ignore-not-found=true - echodate "Done cleaning up clusters" - - # Kill all descendant processes - pkill -P $$ - set -e -} - -docker_logs() { - if [[ $? -ne 0 ]]; then - echodate "Printing Docker logs" - cat /tmp/docker.log - echodate "Done printing Docker logs" - fi -} - -start_docker_daemon_ci() { - # DOCKER_REGISTRY_MIRROR_ADDR is injected via Prow preset; - # start-docker.sh is part of the build image. - DOCKER_REGISTRY_MIRROR="${DOCKER_REGISTRY_MIRROR_ADDR:-}" DOCKER_MTU=1400 start-docker.sh -} - -start_docker_daemon() { - if docker stats --no-stream > /dev/null 2>&1; then - echodate "Not starting Docker again, it's already running." - return - fi - - # Start Docker daemon - echodate "Starting Docker" - dockerd > /tmp/docker.log 2>&1 & - - echodate "Started Docker successfully" - appendTrap docker_logs EXIT - - # Wait for Docker to start - echodate "Waiting for Docker" - retry 5 docker stats --no-stream - echodate "Docker became ready" -} - -repeat() { - local end=$1 - local str="${2:-=}" - - for i in $(seq 1 $end); do - echo -n "${str}" - done -} - -heading() { - local title="$@" - echo "$title" - repeat ${#title} "=" - echo -} - -# This is used during releases to set the correct version on all Helm charts. -set_helm_charts_version() { - local version="$1" - local dockerTag="${2:-$version}" - - echodate "Setting Helm chart version to $version..." - -# while IFS= read -r -d '' chartFile; do -# chart="$(basename $(dirname "$chartFile"))" -# -# yq write --inplace "$chartFile" version "$version" -# if [ "$chart" = "kubermatic-operator" ]; then -# yq write --inplace "$chartFile" appVersion "$version" -# yq write --inplace "$(dirname "$chartFile")/values.yaml" kubermaticOperator.image.tag "$dockerTag" -# fi -# done < <(find charts -name 'Chart.yaml' -print0 | sort --zero-terminated) -} \ No newline at end of file diff --git a/hack/boilerplate/boilerplate.sh.txt b/hack/license/bash.txt similarity index 68% rename from hack/boilerplate/boilerplate.sh.txt rename to hack/license/bash.txt index 3b4ee55a..4328d2a3 100644 --- a/hack/boilerplate/boilerplate.sh.txt +++ b/hack/license/bash.txt @@ -1,14 +1,13 @@ -# Copyright YEAR The Kube Bind Authors. +# Copyright AppsCode Inc. and Contributors # -# Licensed under the Apache License, Version 2.0 (the "License"); +# Licensed under the AppsCode Community License 1.0.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 +# https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md # # 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. - diff --git a/hack/license/dockerfile.txt b/hack/license/dockerfile.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/hack/license/dockerfile.txt @@ -0,0 +1 @@ + diff --git a/vendor/k8s.io/gengo/examples/set-gen/sets/doc.go b/hack/license/go.txt similarity index 62% rename from vendor/k8s.io/gengo/examples/set-gen/sets/doc.go rename to hack/license/go.txt index b152a0bf..82f480ab 100644 --- a/vendor/k8s.io/gengo/examples/set-gen/sets/doc.go +++ b/hack/license/go.txt @@ -1,11 +1,11 @@ /* -Copyright The Kubernetes Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,3 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. - -// Package sets has auto-generated set types. -package sets diff --git a/hack/license/makefile.txt b/hack/license/makefile.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/hack/license/makefile.txt @@ -0,0 +1 @@ + diff --git a/hack/scripts/update-release-tracker.sh b/hack/scripts/update-release-tracker.sh new file mode 100755 index 00000000..e03826d2 --- /dev/null +++ b/hack/scripts/update-release-tracker.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Copyright AppsCode Inc. and Contributors +# +# Licensed under the AppsCode Community License 1.0.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md +# +# 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. + +# Copyright AppsCode Inc. and Contributors. +# +# 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. + +set -eou pipefail + +# ref: https://gist.github.com/joshisa/297b0bc1ec0dcdda0d1625029711fa24 +parse_url() { + proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')" + # remove the protocol + url="$(echo ${1/$proto/})" + + IFS='/' # / is set as delimiter + read -ra PARTS <<<"$url" # str is read into an array as tokens separated by IFS + if [ ${PARTS[0]} != 'github.com' ] || [ ${#PARTS[@]} -ne 5 ]; then + echo "failed to parse relase-tracker: $url" + exit 1 + fi + export RELEASE_TRACKER_OWNER=${PARTS[1]} + export RELEASE_TRACKER_REPO=${PARTS[2]} + export RELEASE_TRACKER_PR=${PARTS[4]} +} + +RELEASE_TRACKER=${RELEASE_TRACKER:-} +GITHUB_BASE_REF=${GITHUB_BASE_REF:-} + +while IFS=$': \r\t' read -r -u9 marker v; do + case $marker in + Release-tracker) + export RELEASE_TRACKER=$(echo $v | tr -d '\r\t') + ;; + Release) + export RELEASE=$(echo $v | tr -d '\r\t') + ;; + esac +done 9< <(git show -s --format=%b) + +[ ! -z "$RELEASE_TRACKER" ] || { + echo "Release-tracker url not found." + exit 0 +} + +[ ! -z "$GITHUB_BASE_REF" ] || { + echo "GitHub base ref not found." + exit 0 +} + +parse_url $RELEASE_TRACKER +api_url="repos/${RELEASE_TRACKER_OWNER}/${RELEASE_TRACKER_REPO}/issues/${RELEASE_TRACKER_PR}/comments" + +case $GITHUB_BASE_REF in + master) + msg="/ready-to-tag github.com/${GITHUB_REPOSITORY} ${GITHUB_SHA}" + ;; + *) + msg="/cherry-picked github.com/${GITHUB_REPOSITORY} ${GITHUB_BASE_REF} ${GITHUB_SHA}" + ;; +esac + +hub api "$api_url" -f body="$msg" diff --git a/hack/test.sh b/hack/test.sh new file mode 100755 index 00000000..318c7d1f --- /dev/null +++ b/hack/test.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# Copyright AppsCode Inc. and Contributors +# +# Licensed under the AppsCode Community License 1.0.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md +# +# 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. + +# Copyright AppsCode Inc. and Contributors. +# +# 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. + +set -eou pipefail + +export CGO_ENABLED=1 +export GO111MODULE=on +export GOFLAGS="-mod=vendor" + +TARGETS=$(for d in "$@"; do echo ./$d/...; done) + +echo "Running tests:" +go test -race -installsuffix "static" ${TARGETS} +echo diff --git a/hack/update-codegen-clients.sh b/hack/update-codegen-clients.sh deleted file mode 100755 index 376d3252..00000000 --- a/hack/update-codegen-clients.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2021 The Kube Bind Authors. -# -# 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. - -set -o errexit -set -o nounset -set -o pipefail -set -o xtrace - -chmod +x ./vendor/k8s.io/code-generator/generate-groups.sh -chmod +x ./vendor/k8s.io/code-generator/generate-internal-groups.sh - -export GOPATH=$(go env GOPATH) - -SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. -CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; go list -f '{{.Dir}}' -m k8s.io/code-generator)} - -bash ./vendor/k8s.io/code-generator/generate-groups.sh "deepcopy,client,informer,lister" \ - go.bytebuilders.dev/kube-bind/pkg/client go.bytebuilders.dev/kube-bind/pkg/apis \ - "kubebind:v1alpha1" \ - --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate/boilerplate.generatego.txt \ - --output-base "${SCRIPT_ROOT}" \ - --trim-path-prefix go.bytebuilders.dev/kube-bind diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh deleted file mode 100755 index cb47dd8d..00000000 --- a/hack/update-codegen.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2021 The Kube Bind Authors. -# -# 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. - -set -o errexit -set -o nounset -set -o pipefail -set -o xtrace - -if [[ -z "${MAKELEVEL:-}" ]]; then - echo 'You must invoke this script via make' - exit 1 -fi - -"$(dirname "${BASH_SOURCE[0]}")/update-codegen-clients.sh" - -# Update generated CRD YAML -cd pkg/apis -../../${CONTROLLER_GEN} \ - crd \ - rbac:roleName=manager-role \ - webhook \ - paths="./..." \ - output:crd:artifacts:config=../../deploy/crd -cd - - -cd deploy/crd -for CRD in *.yaml; do - if [ -f "../patches/${CRD}-patch" ]; then - echo "Applying ${CRD}-patch" - ../../${YAML_PATCH} -o "../patches/${CRD}-patch" < "${CRD}" > "${CRD}.patched" - mv "${CRD}.patched" "${CRD}" - fi -done diff --git a/hack/verify-codegen-clients.sh b/hack/verify-codegen-clients.sh deleted file mode 100755 index a5420e1c..00000000 --- a/hack/verify-codegen-clients.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2021 The Kube Bind Authors. -# -# 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. - -# This script ensures that the generated client code checked into git is up-to-date -# with the generator. If it is not, re-generate the configuration to update it. - -set -o errexit -set -o nounset -set -o pipefail - -"$( dirname "${BASH_SOURCE[0]}")/update-codegen-clients.sh" -if ! git diff --quiet --exit-code -- pkg/client; then - cat << EOF -ERROR: This check enforces that the client code is generated correctly. -ERROR: The client code is out of date. Run the following command to re- -ERROR: generate the clients: -ERROR: $ hack/update-generated-clients.sh -ERROR: The following differences were found: -EOF - git diff - exit 1 -fi \ No newline at end of file diff --git a/hack/verify-go-versions.sh b/hack/verify-go-versions.sh deleted file mode 100755 index bf57eb10..00000000 --- a/hack/verify-go-versions.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2022 The Kube Bind Authors. -# -# 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. - -set -e -set -o pipefail - -VERSION=$(grep "go 1." go.mod | sed 's/go //') - -grep "FROM golang:" Dockerfile | { ! grep -v "${VERSION}"; } || { echo "Wrong go version in Dockerfile, expected ${VERSION}"; exit 1; } -grep "go-version:" .github/workflows/*.yaml | { ! grep -v "go-version: v${VERSION}"; } || { echo "Wrong go version in .github/workflows/*.yaml, expected ${VERSION}"; exit 1; } -grep "golang:" .ko.yaml | { ! grep -v "golang:${VERSION}"; } || { echo "Wrong go version in .ko.yaml, expected ${VERSION}"; exit 1; } -# Note CONTRIBUTING.md isn't copied in the Dockerfile -if [ -z "${IGNORE_GO_VERSION}" ]; then - go version | { ! grep -v go${VERSION}; } || { echo "Unexpected go version installed, expected ${VERSION}. Use IGNORE_GO_VERSION=1 to skip this check."; exit 1; } -fi diff --git a/hack/verify-imports.sh b/hack/verify-imports.sh deleted file mode 100755 index c21394ac..00000000 --- a/hack/verify-imports.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2022 The Kube Bind Authors. -# -# 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. - -# This script ensures that the generated client code checked into git is up-to-date -# with the generator. If it is not, re-generate the configuration to update it. - -set -o errexit -set -o nounset -set -o pipefail - -make -C "$( dirname "${BASH_SOURCE[0]}")/../" imports -if ! git diff --quiet --exit-code ; then - cat << EOF -ERROR: This check enforces that import statements are ordered correctly. -ERROR: The import statements are out of order. Run the following command -ERROR: to regenerate the statements: -ERROR: $ make imports -ERROR: The following differences were found: -EOF - git diff - exit 1 -fi \ No newline at end of file diff --git a/pkg/bootstrap/bootstrap.go b/pkg/bootstrap/bootstrap.go index 20366e82..83449ccc 100644 --- a/pkg/bootstrap/bootstrap.go +++ b/pkg/bootstrap/bootstrap.go @@ -1,11 +1,11 @@ /* -Copyright 2021 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -149,8 +149,10 @@ func CreateResourceFromFS(ctx context.Context, client dynamic.Interface, mapper return apimachineryerrors.NewAggregate(errs) } -const annotationCreateOnlyKey = "bootstrap.kube-bind.appscode.com/create-only" -const annotationBattery = "bootstrap.kube-bind.appscode.com/battery" +const ( + annotationCreateOnlyKey = "bootstrap.kube-bind.appscode.com/create-only" + annotationBattery = "bootstrap.kube-bind.appscode.com/battery" +) func createResourceFromFS(ctx context.Context, client dynamic.Interface, mapper meta.RESTMapper, raw []byte, batteriesIncluded sets.Set[string]) error { type Input struct { diff --git a/pkg/committer/committer.go b/pkg/committer/committer.go index 689c175c..beb75659 100644 --- a/pkg/committer/committer.go +++ b/pkg/committer/committer.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,7 +23,6 @@ import ( jsonpatch "github.com/evanphx/json-patch" "github.com/google/go-cmp/cmp" - "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/pkg/indexers/crd.go b/pkg/indexers/crd.go index efa0d1df..f0481195 100644 --- a/pkg/indexers/crd.go +++ b/pkg/indexers/crd.go @@ -1,11 +1,27 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the AppsCode Community License 1.0.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md + +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. +*/ + package indexers import ( "strings" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" ) const ( diff --git a/pkg/indexers/servicebinding.go b/pkg/indexers/servicebinding.go index e794a567..96221d2c 100644 --- a/pkg/indexers/servicebinding.go +++ b/pkg/indexers/servicebinding.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,7 +17,7 @@ limitations under the License. package indexers import ( - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" ) const ( diff --git a/pkg/indexers/serviceexport.go b/pkg/indexers/serviceexport.go index 0b9c41e2..beceb375 100644 --- a/pkg/indexers/serviceexport.go +++ b/pkg/indexers/serviceexport.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,7 +17,7 @@ limitations under the License. package indexers import ( - "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" ) const ( diff --git a/pkg/indexers/serviceexportrequest.go b/pkg/indexers/serviceexportrequest.go index 4a3942af..8c119e2f 100644 --- a/pkg/indexers/serviceexportrequest.go +++ b/pkg/indexers/serviceexportrequest.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,7 +17,7 @@ limitations under the License. package indexers import ( - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" ) const ( diff --git a/pkg/indexers/servicenamespace.go b/pkg/indexers/servicenamespace.go index 9a9be359..2581c54d 100644 --- a/pkg/indexers/servicenamespace.go +++ b/pkg/indexers/servicenamespace.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,7 +17,7 @@ limitations under the License. package indexers import ( - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" ) const ( diff --git a/pkg/indexers/util.go b/pkg/indexers/util.go index 12dc083b..8bee5eab 100644 --- a/pkg/indexers/util.go +++ b/pkg/indexers/util.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -24,7 +24,7 @@ import ( // Append is a helper function that merged a set of indexers. func Append(indexers ...cache.Indexers) (cache.Indexers, error) { - var ret = cache.Indexers{} + ret := cache.Indexers{} for _, ind := range indexers { for k, v := range ind { if _, found := ret[k]; found { diff --git a/pkg/konnector/config.go b/pkg/konnector/config.go index 9fea51b5..44498dcd 100644 --- a/pkg/konnector/config.go +++ b/pkg/konnector/config.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,16 +19,16 @@ package konnector import ( "time" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions" + "go.bytebuilders.dev/kube-bind/pkg/konnector/options" + apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions" kubeinformers "k8s.io/client-go/informers" kubernetesclient "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions" - "go.bytebuilders.dev/kube-bind/pkg/konnector/options" ) type Config struct { diff --git a/pkg/konnector/controllers/cluster/cluster_controller.go b/pkg/konnector/controllers/cluster/cluster_controller.go index 7f60549a..837ccb0e 100644 --- a/pkg/konnector/controllers/cluster/cluster_controller.go +++ b/pkg/konnector/controllers/cluster/cluster_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,8 +21,17 @@ import ( "reflect" "time" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/clusterbinding" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/namespacedeletion" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/servicebinding" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" crdlisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -34,18 +43,8 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/indexers" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/clusterbinding" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/namespacedeletion" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/servicebinding" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) const ( diff --git a/pkg/konnector/controllers/cluster/clusterbinding/clusterbinding_controller.go b/pkg/konnector/controllers/cluster/clusterbinding/clusterbinding_controller.go index 3887c0f9..16584ff4 100644 --- a/pkg/konnector/controllers/cluster/clusterbinding/clusterbinding_controller.go +++ b/pkg/konnector/controllers/cluster/clusterbinding/clusterbinding_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,8 +22,13 @@ import ( "reflect" "time" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -38,14 +43,8 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" - "go.bytebuilders.dev/kube-bind/pkg/indexers" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) const ( @@ -133,8 +132,8 @@ func NewController( }, }, - commit: committer.NewCommitter[*kubebindv1alpha1.ClusterBinding, *kubebindv1alpha1.ClusterBindingSpec, *kubebindv1alpha1.ClusterBindingStatus]( - func(ns string) committer.Patcher[*kubebindv1alpha1.ClusterBinding] { + commit: committer.NewCommitter[*v1alpha1.ClusterBinding, *v1alpha1.ClusterBindingSpec, *v1alpha1.ClusterBindingStatus]( + func(ns string) committer.Patcher[*v1alpha1.ClusterBinding] { providerInfo, err := konnectormodels.GetProviderInfoWithProviderNamespace(providerInfos, ns) if err != nil { klog.Warningf(err.Error()) @@ -181,11 +180,11 @@ func NewController( c.enqueueServiceExport(logger, obj) }, UpdateFunc: func(old, newObj interface{}) { - oldExport, ok := old.(*kubebindv1alpha1.APIServiceExport) + oldExport, ok := old.(*v1alpha1.APIServiceExport) if !ok { return } - newExport, ok := old.(*kubebindv1alpha1.APIServiceExport) + newExport, ok := old.(*v1alpha1.APIServiceExport) if !ok { return } @@ -221,8 +220,10 @@ func NewController( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.ClusterBindingSpec, *kubebindv1alpha1.ClusterBindingStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*v1alpha1.ClusterBindingSpec, *v1alpha1.ClusterBindingStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) // controller reconciles ClusterBindings on the service provider cluster, including heartbeating. type controller struct { @@ -433,10 +434,10 @@ func (c *controller) process(ctx context.Context, key string) error { errs = append(errs, err) // try to update service bindings - c.updateServiceBindings(ctx, func(binding *kubebindv1alpha1.APIServiceBinding) { + c.updateServiceBindings(ctx, func(binding *v1alpha1.APIServiceBinding) { conditions.MarkFalse( binding, - kubebindv1alpha1.APIServiceBindingConditionHeartbeating, + v1alpha1.APIServiceBindingConditionHeartbeating, "ClusterBindingUpdateFailed", conditionsapi.ConditionSeverityWarning, "Failed to update service provider ClusterBinding: %v", err, @@ -444,15 +445,15 @@ func (c *controller) process(ctx context.Context, key string) error { }, consumerSecretRefKey) } else { // try to update service bindings - c.updateServiceBindings(ctx, func(binding *kubebindv1alpha1.APIServiceBinding) { - conditions.MarkTrue(binding, kubebindv1alpha1.APIServiceBindingConditionHeartbeating) + c.updateServiceBindings(ctx, func(binding *v1alpha1.APIServiceBinding) { + conditions.MarkTrue(binding, v1alpha1.APIServiceBindingConditionHeartbeating) }, consumerSecretRefKey) } return utilerrors.NewAggregate(errs) } -func (c *controller) updateServiceBindings(ctx context.Context, update func(*kubebindv1alpha1.APIServiceBinding), consumerSecretRefKey string) { +func (c *controller) updateServiceBindings(ctx context.Context, update func(*v1alpha1.APIServiceBinding), consumerSecretRefKey string) { logger := klog.FromContext(ctx) objs, err := c.serviceBindingInformer.Informer().GetIndexer().ByIndex(indexers.ByServiceBindingKubeconfigSecret, consumerSecretRefKey) @@ -461,7 +462,7 @@ func (c *controller) updateServiceBindings(ctx context.Context, update func(*kub return } for _, obj := range objs { - binding := obj.(*kubebindv1alpha1.APIServiceBinding) + binding := obj.(*v1alpha1.APIServiceBinding) orig := binding binding = binding.DeepCopy() update(binding) diff --git a/pkg/konnector/controllers/cluster/clusterbinding/clusterbinding_reconcile.go b/pkg/konnector/controllers/cluster/clusterbinding/clusterbinding_reconcile.go index 7670361e..a92f40b4 100644 --- a/pkg/konnector/controllers/cluster/clusterbinding/clusterbinding_reconcile.go +++ b/pkg/konnector/controllers/cluster/clusterbinding/clusterbinding_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,8 +20,9 @@ import ( "context" "time" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + "go.bytebuilders.dev/kube-bind/pkg/version" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -30,10 +31,8 @@ import ( "k8s.io/client-go/tools/cache" componentbaseversion "k8s.io/component-base/version" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" - "go.bytebuilders.dev/kube-bind/pkg/version" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) type reconciler struct { diff --git a/pkg/konnector/controllers/cluster/namespacedeletion/namespacedeletion_controller.go b/pkg/konnector/controllers/cluster/namespacedeletion/namespacedeletion_controller.go index 24fdc55d..a3099af4 100644 --- a/pkg/konnector/controllers/cluster/namespacedeletion/namespacedeletion_controller.go +++ b/pkg/konnector/controllers/cluster/namespacedeletion/namespacedeletion_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,11 @@ import ( "fmt" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -32,11 +37,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" ) const ( diff --git a/pkg/konnector/controllers/cluster/servicebinding/servicebinding_controller.go b/pkg/konnector/controllers/cluster/servicebinding/servicebinding_controller.go index c2e11011..86ef8d74 100644 --- a/pkg/konnector/controllers/cluster/servicebinding/servicebinding_controller.go +++ b/pkg/konnector/controllers/cluster/servicebinding/servicebinding_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,14 @@ import ( "fmt" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" @@ -33,14 +41,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" - "go.bytebuilders.dev/kube-bind/pkg/indexers" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" ) const ( @@ -49,7 +49,7 @@ const ( // NewController returns a new controller for ServiceBindings. func NewController( - reconcileServiceBinding func(binding *kubebindv1alpha1.APIServiceBinding) bool, + reconcileServiceBinding func(binding *v1alpha1.APIServiceBinding) bool, consumerConfig *rest.Config, serviceBindingInformer dynamic.Informer[bindlisters.APIServiceBindingLister], crdInformer dynamic.Informer[apiextensionslisters.CustomResourceDefinitionLister], @@ -90,21 +90,20 @@ func NewController( providerInfors: providerInfos, reconciler: reconciler{ - providerInfos: providerInfos, reconcileServiceBinding: reconcileServiceBinding, - getServiceExport: func(provider *konnectormodels.ProviderInfo, name string) (*kubebindv1alpha1.APIServiceExport, error) { + getServiceExport: func(provider *konnectormodels.ProviderInfo, name string) (*v1alpha1.APIServiceExport, error) { return provider.BindInformer.KubeBind().V1alpha1().APIServiceExports().Lister().APIServiceExports(provider.Namespace).Get(name) }, - getServiceBinding: func(name string) (*kubebindv1alpha1.APIServiceBinding, error) { + getServiceBinding: func(name string) (*v1alpha1.APIServiceBinding, error) { return serviceBindingInformer.Lister().Get(name) }, - getClusterBinding: func(ctx context.Context, provider *konnectormodels.ProviderInfo) (*kubebindv1alpha1.ClusterBinding, error) { + getClusterBinding: func(ctx context.Context, provider *konnectormodels.ProviderInfo) (*v1alpha1.ClusterBinding, error) { return provider.BindClient.KubeBindV1alpha1().ClusterBindings(provider.Namespace).Get(ctx, "cluster", metav1.GetOptions{}) }, - updateServiceExportStatus: func(ctx context.Context, export *kubebindv1alpha1.APIServiceExport, clusterID string) (*kubebindv1alpha1.APIServiceExport, error) { + updateServiceExportStatus: func(ctx context.Context, export *v1alpha1.APIServiceExport, clusterID string) (*v1alpha1.APIServiceExport, error) { provider, err := konnectormodels.GetProviderInfoWithClusterID(providerInfos, clusterID) if err != nil { return nil, err @@ -122,8 +121,8 @@ func NewController( }, }, - commit: committer.NewCommitter[*kubebindv1alpha1.APIServiceBinding, *kubebindv1alpha1.APIServiceBindingSpec, *kubebindv1alpha1.APIServiceBindingStatus]( - func(ns string) committer.Patcher[*kubebindv1alpha1.APIServiceBinding] { + commit: committer.NewCommitter[*v1alpha1.APIServiceBinding, *v1alpha1.APIServiceBindingSpec, *v1alpha1.APIServiceBindingStatus]( + func(ns string) committer.Patcher[*v1alpha1.APIServiceBinding] { return consumerBindClient.KubeBindV1alpha1().APIServiceBindings() }, ), @@ -153,8 +152,10 @@ func NewController( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.APIServiceBindingSpec, *kubebindv1alpha1.APIServiceBindingStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*v1alpha1.APIServiceBindingSpec, *v1alpha1.APIServiceBindingStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) // controller reconciles ServiceBindings with there ServiceExports counterparts. type controller struct { @@ -192,7 +193,7 @@ func (c *controller) enqueueServiceExport(logger klog.Logger, _ interface{}, pro fmt.Println(bindings) for _, obj := range bindings { - binding := obj.(*kubebindv1alpha1.APIServiceBinding) + binding := obj.(*v1alpha1.APIServiceBinding) key, err := cache.MetaNamespaceKeyFunc(binding) if err != nil { runtime.HandleError(err) @@ -220,7 +221,7 @@ func (c *controller) enqueueCRD(logger klog.Logger, obj interface{}) { exports = append(exports, exps...) } for _, obj := range exports { - export := obj.(*kubebindv1alpha1.APIServiceExport) + export := obj.(*v1alpha1.APIServiceExport) key := export.Name logger.V(2).Info("queueing APIServiceBinding", "key", key, "reason", "CustomResourceDefinition", "CustomResourceDefinitionKey", name) c.queue.Add(key) diff --git a/pkg/konnector/controllers/cluster/servicebinding/servicebinding_reconcile.go b/pkg/konnector/controllers/cluster/servicebinding/servicebinding_reconcile.go index a0de7d0c..2971ac3a 100644 --- a/pkg/konnector/controllers/cluster/servicebinding/servicebinding_reconcile.go +++ b/pkg/konnector/controllers/cluster/servicebinding/servicebinding_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,36 +19,35 @@ package servicebinding import ( "context" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1/helpers" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/utils/ptr" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - kubebindhelpers "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1/helpers" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) type reconciler struct { providerInfos []*konnectormodels.ProviderInfo - reconcileServiceBinding func(binding *kubebindv1alpha1.APIServiceBinding) bool - getServiceExport func(provider *konnectormodels.ProviderInfo, ns string) (*kubebindv1alpha1.APIServiceExport, error) - getServiceBinding func(name string) (*kubebindv1alpha1.APIServiceBinding, error) - getClusterBinding func(ctx context.Context, provider *konnectormodels.ProviderInfo) (*kubebindv1alpha1.ClusterBinding, error) + reconcileServiceBinding func(binding *v1alpha1.APIServiceBinding) bool + getServiceExport func(provider *konnectormodels.ProviderInfo, ns string) (*v1alpha1.APIServiceExport, error) + getServiceBinding func(name string) (*v1alpha1.APIServiceBinding, error) + getClusterBinding func(ctx context.Context, provider *konnectormodels.ProviderInfo) (*v1alpha1.ClusterBinding, error) - updateServiceExportStatus func(ctx context.Context, export *kubebindv1alpha1.APIServiceExport, clusterID string) (*kubebindv1alpha1.APIServiceExport, error) + updateServiceExportStatus func(ctx context.Context, export *v1alpha1.APIServiceExport, clusterID string) (*v1alpha1.APIServiceExport, error) getCRD func(name string) (*apiextensionsv1.CustomResourceDefinition, error) updateCRD func(ctx context.Context, crd *apiextensionsv1.CustomResourceDefinition) (*apiextensionsv1.CustomResourceDefinition, error) createCRD func(ctx context.Context, crd *apiextensionsv1.CustomResourceDefinition) (*apiextensionsv1.CustomResourceDefinition, error) } -func (r *reconciler) reconcile(ctx context.Context, binding *kubebindv1alpha1.APIServiceBinding) error { +func (r *reconciler) reconcile(ctx context.Context, binding *v1alpha1.APIServiceBinding) error { var errs []error // As konnector is running APIServiceBinding controller for each provider cluster, @@ -74,14 +73,14 @@ func (r *reconciler) reconcile(ctx context.Context, binding *kubebindv1alpha1.AP return utilerrors.NewAggregate(errs) } -func (r *reconciler) ensureValidServiceExport(ctx context.Context, binding *kubebindv1alpha1.APIServiceBinding) error { +func (r *reconciler) ensureValidServiceExport(ctx context.Context, binding *v1alpha1.APIServiceBinding) error { for _, provider := range r.providerInfos { if _, err := r.getServiceExport(provider, binding.Name); err != nil && !errors.IsNotFound(err) { return err } else if errors.IsNotFound(err) { conditions.MarkFalse( binding, - kubebindv1alpha1.APIServiceBindingConditionConnected, + v1alpha1.APIServiceBindingConditionConnected, "APIServiceExportNotFound", conditionsapi.ConditionSeverityError, "APIServiceExport %s not found on the service provider cluster. Rerun kubectl bind for repair.", @@ -93,13 +92,13 @@ func (r *reconciler) ensureValidServiceExport(ctx context.Context, binding *kube conditions.MarkTrue( binding, - kubebindv1alpha1.APIServiceBindingConditionConnected, + v1alpha1.APIServiceBindingConditionConnected, ) return nil } -func (r *reconciler) ensureCRDs(ctx context.Context, binding *kubebindv1alpha1.APIServiceBinding) error { +func (r *reconciler) ensureCRDs(ctx context.Context, binding *v1alpha1.APIServiceBinding) error { var errs []error for _, provider := range r.providerInfos { @@ -109,7 +108,7 @@ func (r *reconciler) ensureCRDs(ctx context.Context, binding *kubebindv1alpha1.A } else if errors.IsNotFound(err) { conditions.MarkFalse( binding, - kubebindv1alpha1.APIServiceBindingConditionConnected, + v1alpha1.APIServiceBindingConditionConnected, "APIServiceExportNotFound", conditionsapi.ConditionSeverityError, "APIServiceExport %s not found on the service provider cluster %s.", @@ -119,11 +118,11 @@ func (r *reconciler) ensureCRDs(ctx context.Context, binding *kubebindv1alpha1.A return nil // nothing we can do here } - crd, err := kubebindhelpers.ServiceExportToCRD(export) + crd, err := helpers.ServiceExportToCRD(export) if err != nil { conditions.MarkFalse( binding, - kubebindv1alpha1.APIServiceBindingConditionConnected, + v1alpha1.APIServiceBindingConditionConnected, "APIServiceExportInvalid", conditionsapi.ConditionSeverityError, "APIServiceExport %s on the service provider cluster is invalid: %s", @@ -134,7 +133,7 @@ func (r *reconciler) ensureCRDs(ctx context.Context, binding *kubebindv1alpha1.A // put binding owner reference on the CRD. newReference := metav1.OwnerReference{ - APIVersion: kubebindv1alpha1.SchemeGroupVersion.String(), + APIVersion: v1alpha1.SchemeGroupVersion.String(), Kind: "APIServiceBinding", Name: binding.Name, UID: binding.UID, @@ -151,7 +150,7 @@ func (r *reconciler) ensureCRDs(ctx context.Context, binding *kubebindv1alpha1.A } else if errors.IsInvalid(err) { conditions.MarkFalse( binding, - kubebindv1alpha1.APIServiceBindingConditionConnected, + v1alpha1.APIServiceBindingConditionConnected, "CustomResourceDefinitionCreateFailed", conditionsapi.ConditionSeverityError, "CustomResourceDefinition %s cannot be created: %s", @@ -160,15 +159,15 @@ func (r *reconciler) ensureCRDs(ctx context.Context, binding *kubebindv1alpha1.A return nil } - conditions.MarkTrue(binding, kubebindv1alpha1.APIServiceBindingConditionConnected) + conditions.MarkTrue(binding, v1alpha1.APIServiceBindingConditionConnected) return nil // we wait for a new reconcile to update APIServiceExport status } // first check this really ours and we don't override something else - if !kubebindhelpers.IsOwnedByBinding(binding.Name, binding.UID, existing.OwnerReferences) { + if !helpers.IsOwnedByBinding(binding.Name, binding.UID, existing.OwnerReferences) { conditions.MarkFalse( binding, - kubebindv1alpha1.APIServiceBindingConditionConnected, + v1alpha1.APIServiceBindingConditionConnected, "ForeignCustomResourceDefinition", conditionsapi.ConditionSeverityError, "CustomResourceDefinition %s is not owned by kube-bind.appscode.com.", @@ -183,7 +182,7 @@ func (r *reconciler) ensureCRDs(ctx context.Context, binding *kubebindv1alpha1.A } else if errors.IsInvalid(err) { conditions.MarkFalse( binding, - kubebindv1alpha1.APIServiceBindingConditionConnected, + v1alpha1.APIServiceBindingConditionConnected, "CustomResourceDefinitionUpdateFailed", conditionsapi.ConditionSeverityError, "CustomResourceDefinition %s cannot be updated: %s", @@ -193,13 +192,13 @@ func (r *reconciler) ensureCRDs(ctx context.Context, binding *kubebindv1alpha1.A } } - conditions.MarkTrue(binding, kubebindv1alpha1.APIServiceBindingConditionConnected) + conditions.MarkTrue(binding, v1alpha1.APIServiceBindingConditionConnected) return utilerrors.NewAggregate(errs) } -func (r *reconciler) ensurePrettyName(ctx context.Context, binding *kubebindv1alpha1.APIServiceBinding) error { - binding.Status.Providers = []kubebindv1alpha1.Provider{} +func (r *reconciler) ensurePrettyName(ctx context.Context, binding *v1alpha1.APIServiceBinding) error { + binding.Status.Providers = []v1alpha1.Provider{} for _, provider := range r.providerInfos { clusterBinding, err := r.getClusterBinding(ctx, provider) if err != nil && !errors.IsNotFound(err) { @@ -207,8 +206,8 @@ func (r *reconciler) ensurePrettyName(ctx context.Context, binding *kubebindv1al } else if errors.IsNotFound(err) { return nil } - prov := kubebindv1alpha1.Provider{} - prov.Kubeconfig = &kubebindv1alpha1.ClusterSecretKeyRef{ + prov := v1alpha1.Provider{} + prov.Kubeconfig = &v1alpha1.ClusterSecretKeyRef{ LocalSecretKeyRef: clusterBinding.Spec.KubeconfigSecretRef, Namespace: clusterBinding.Namespace, } diff --git a/pkg/konnector/controllers/cluster/servicebinding/servicebinding_reconcile_test.go b/pkg/konnector/controllers/cluster/servicebinding/servicebinding_reconcile_test.go index e2acc8de..2b8c154b 100644 --- a/pkg/konnector/controllers/cluster/servicebinding/servicebinding_reconcile_test.go +++ b/pkg/konnector/controllers/cluster/servicebinding/servicebinding_reconcile_test.go @@ -1,11 +1,11 @@ /* -Copyright 2023 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,22 +20,21 @@ import ( "context" "testing" - "github.com/stretchr/testify/require" - conditionsapi "kmodules.xyz/client-go/api/v1" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + "github.com/stretchr/testify/require" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + conditionsapi "kmodules.xyz/client-go/api/v1" ) func TestEnsureCRDs(t *testing.T) { tests := []struct { name string bindingName string - getServiceExport func(provider *konnectormodels.ProviderInfo, name string) (*kubebindv1alpha1.APIServiceExport, error) + getServiceExport func(provider *konnectormodels.ProviderInfo, name string) (*v1alpha1.APIServiceExport, error) getCRD func(name string) (*apiextensionsv1.CustomResourceDefinition, error) expectConditions conditionsapi.Conditions }{ @@ -104,26 +103,26 @@ func newCRD(name string) *apiextensionsv1.CustomResourceDefinition { } } -func newGetServiceExport(name string, crd *kubebindv1alpha1.APIServiceExport) func(provider *konnectormodels.ProviderInfo, name string) (*kubebindv1alpha1.APIServiceExport, error) { - return func(provider *konnectormodels.ProviderInfo, n string) (*kubebindv1alpha1.APIServiceExport, error) { +func newGetServiceExport(name string, crd *v1alpha1.APIServiceExport) func(provider *konnectormodels.ProviderInfo, name string) (*v1alpha1.APIServiceExport, error) { + return func(provider *konnectormodels.ProviderInfo, n string) (*v1alpha1.APIServiceExport, error) { if n == name { return crd, nil } - return nil, errors.NewNotFound(kubebindv1alpha1.SchemeGroupVersion.WithResource("apiserviceexports").GroupResource(), "not found") + return nil, errors.NewNotFound(v1alpha1.SchemeGroupVersion.WithResource("apiserviceexports").GroupResource(), "not found") } } -func newServiceExport(name string) *kubebindv1alpha1.APIServiceExport { - return &kubebindv1alpha1.APIServiceExport{ +func newServiceExport(name string) *v1alpha1.APIServiceExport { + return &v1alpha1.APIServiceExport{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, - Spec: kubebindv1alpha1.APIServiceExportSpec{}, + Spec: v1alpha1.APIServiceExportSpec{}, } } -func newBinding(name string) *kubebindv1alpha1.APIServiceBinding { - return &kubebindv1alpha1.APIServiceBinding{ +func newBinding(name string) *v1alpha1.APIServiceBinding { + return &v1alpha1.APIServiceBinding{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, diff --git a/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped/utils.go b/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped/utils.go index 580538a8..d9e3f7cc 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped/utils.go +++ b/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped/utils.go @@ -1,11 +1,11 @@ /* -Copyright 2023 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped/utils_test.go b/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped/utils_test.go index ba29b611..a07850fe 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped/utils_test.go +++ b/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped/utils_test.go @@ -1,11 +1,11 @@ /* -Copyright 2023 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,7 +20,6 @@ import ( "testing" "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/pkg/konnector/controllers/cluster/serviceexport/multinsinformer/informer.go b/pkg/konnector/controllers/cluster/serviceexport/multinsinformer/informer.go index 89fa94bc..5b5ddfa1 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/multinsinformer/informer.go +++ b/pkg/konnector/controllers/cluster/serviceexport/multinsinformer/informer.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,6 +22,11 @@ import ( "sync" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" @@ -34,11 +39,6 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/indexers" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" ) const ( diff --git a/pkg/konnector/controllers/cluster/serviceexport/serviceexport_controller.go b/pkg/konnector/controllers/cluster/serviceexport/serviceexport_controller.go index c8be0841..c232cc8e 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/serviceexport_controller.go +++ b/pkg/konnector/controllers/cluster/serviceexport/serviceexport_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,14 @@ import ( "fmt" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -31,14 +39,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" - "go.bytebuilders.dev/kube-bind/pkg/indexers" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" ) const ( @@ -64,7 +64,7 @@ func NewController( provider.Config = rest.CopyConfig(provider.Config) provider.Config = rest.AddUserAgent(provider.Config, controllerName) - //create shared informer factory + // create shared informer factory var err error if provider.BindClient, err = bindclient.NewForConfig(provider.Config); err != nil { return nil, err @@ -90,13 +90,13 @@ func NewController( getCRD: func(name string) (*apiextensionsv1.CustomResourceDefinition, error) { return crdInformer.Lister().Get(name) }, - getServiceBinding: func(name string) (*kubebindv1alpha1.APIServiceBinding, error) { + getServiceBinding: func(name string) (*v1alpha1.APIServiceBinding, error) { return serviceBindingInformer.Lister().Get(name) }, }, - commit: committer.NewCommitter[*kubebindv1alpha1.APIServiceExport, *kubebindv1alpha1.APIServiceExportSpec, *kubebindv1alpha1.APIServiceExportStatus]( - func(ns string) committer.Patcher[*kubebindv1alpha1.APIServiceExport] { + commit: committer.NewCommitter[*v1alpha1.APIServiceExport, *v1alpha1.APIServiceExportSpec, *v1alpha1.APIServiceExportStatus]( + func(ns string) committer.Patcher[*v1alpha1.APIServiceExport] { provider, err := konnectormodels.GetProviderInfoWithProviderNamespace(providerInfos, ns) if err != nil { klog.Errorf(fmt.Sprintf("failed to get any provider with namespace: %s", ns)) @@ -131,8 +131,10 @@ func NewController( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.APIServiceExportSpec, *kubebindv1alpha1.APIServiceExportStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*v1alpha1.APIServiceExportSpec, *v1alpha1.APIServiceExportStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) // controller reconciles ServiceExportResources and starts and stop syncers. type controller struct { @@ -160,7 +162,7 @@ func (c *controller) enqueueServiceExport(logger klog.Logger, obj interface{}) { } func (c *controller) enqueueServiceBinding(logger klog.Logger, obj interface{}) { - binding, ok := obj.(*kubebindv1alpha1.APIServiceBinding) + binding, ok := obj.(*v1alpha1.APIServiceBinding) if !ok { runtime.HandleError(fmt.Errorf("unexpected type %T", obj)) return diff --git a/pkg/konnector/controllers/cluster/serviceexport/serviceexport_reconcile.go b/pkg/konnector/controllers/cluster/serviceexport/serviceexport_reconcile.go index e653eee7..f37f6c58 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/serviceexport_reconcile.go +++ b/pkg/konnector/controllers/cluster/serviceexport/serviceexport_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,8 +21,11 @@ import ( "sync" "time" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/multinsinformer" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/spec" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/status" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -34,12 +37,8 @@ import ( "k8s.io/client-go/dynamic/dynamicinformer" "k8s.io/client-go/rest" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/multinsinformer" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/spec" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/status" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) type syncInfo struct { @@ -55,7 +54,7 @@ type reconciler struct { providerInfos []*konnectormodels.ProviderInfo getCRD func(name string) (*apiextensionsv1.CustomResourceDefinition, error) - getServiceBinding func(name string) (*kubebindv1alpha1.APIServiceBinding, error) + getServiceBinding func(name string) (*v1alpha1.APIServiceBinding, error) } type syncContext struct { @@ -63,7 +62,7 @@ type syncContext struct { cancel func() } -func (r *reconciler) reconcile(ctx context.Context, sync *syncInfo, export *kubebindv1alpha1.APIServiceExport) error { +func (r *reconciler) reconcile(ctx context.Context, sync *syncInfo, export *v1alpha1.APIServiceExport) error { errs := []error{} if err := r.ensureControllers(ctx, sync, export); err != nil { @@ -82,7 +81,7 @@ func (r *reconciler) reconcile(ctx context.Context, sync *syncInfo, export *kube return utilerrors.NewAggregate(errs) } -func (r *reconciler) ensureControllers(ctx context.Context, sync *syncInfo, export *kubebindv1alpha1.APIServiceExport) error { +func (r *reconciler) ensureControllers(ctx context.Context, sync *syncInfo, export *v1alpha1.APIServiceExport) error { logger := klog.FromContext(ctx) if export == nil { @@ -193,7 +192,7 @@ func (r *reconciler) ensureControllers(ctx context.Context, sync *syncInfo, expo provider.NamespaceUID = string(pns.GetUID()) } - if crd.Spec.Scope == apiextensionsv1.ClusterScoped || export.Spec.InformerScope == kubebindv1alpha1.ClusterScope { + if crd.Spec.Scope == apiextensionsv1.ClusterScoped || export.Spec.InformerScope == v1alpha1.ClusterScope { factory := dynamicinformer.NewDynamicSharedInformerFactory(dynamicProviderClient, time.Minute*30) factory.ForResource(gvr).Lister() // wire the GVR up in the informer factory provider.ProviderDynamicInformer = multinsinformer.GetterInformerWrapper{ @@ -274,14 +273,14 @@ func (r *reconciler) ensureControllers(ctx context.Context, sync *syncInfo, expo return utilerrors.NewAggregate(errs) } -func (r *reconciler) ensureServiceBindingConditionCopied(ctx context.Context, export *kubebindv1alpha1.APIServiceExport) error { +func (r *reconciler) ensureServiceBindingConditionCopied(ctx context.Context, export *v1alpha1.APIServiceExport) error { binding, err := r.getServiceBinding(export.Name) if err != nil && !errors.IsNotFound(err) { return err } else if errors.IsNotFound(err) { conditions.MarkFalse( export, - kubebindv1alpha1.APIServiceExportConditionConnected, + v1alpha1.APIServiceExportConditionConnected, "APIServiceBindingNotFound", conditionsapi.ConditionSeverityInfo, "No APIServiceBinding exists.", @@ -289,7 +288,7 @@ func (r *reconciler) ensureServiceBindingConditionCopied(ctx context.Context, ex conditions.MarkFalse( export, - kubebindv1alpha1.APIServiceExportConditionConsumerInSync, + v1alpha1.APIServiceExportConditionConsumerInSync, "NA", conditionsapi.ConditionSeverityInfo, "No APIServiceBinding exists.", @@ -298,16 +297,16 @@ func (r *reconciler) ensureServiceBindingConditionCopied(ctx context.Context, ex return nil } - conditions.MarkTrue(export, kubebindv1alpha1.APIServiceExportConditionConnected) + conditions.MarkTrue(export, v1alpha1.APIServiceExportConditionConnected) - if inSync := conditions.Get(binding, kubebindv1alpha1.APIServiceBindingConditionSchemaInSync); inSync != nil { + if inSync := conditions.Get(binding, v1alpha1.APIServiceBindingConditionSchemaInSync); inSync != nil { inSync := inSync.DeepCopy() - inSync.Type = kubebindv1alpha1.APIServiceExportConditionConsumerInSync + inSync.Type = v1alpha1.APIServiceExportConditionConsumerInSync conditions.Set(export, inSync) } else { conditions.MarkFalse( export, - kubebindv1alpha1.APIServiceExportConditionConsumerInSync, + v1alpha1.APIServiceExportConditionConsumerInSync, "Unknown", conditionsapi.ConditionSeverityInfo, "APIServiceBinding %s in the consumer cluster does not have a SchemaInSync condition.", @@ -318,12 +317,12 @@ func (r *reconciler) ensureServiceBindingConditionCopied(ctx context.Context, ex return nil } -func (r *reconciler) ensureCRDConditionsCopied(export *kubebindv1alpha1.APIServiceExport) error { +func (r *reconciler) ensureCRDConditionsCopied(export *v1alpha1.APIServiceExport) error { crd, err := r.getCRD(export.Name) if err != nil && !errors.IsNotFound(err) { return err } else if errors.IsNotFound(err) { - return nil //nothing to copy. + return nil // nothing to copy. } exportIndex := map[conditionsapi.ConditionType]int{} diff --git a/pkg/konnector/controllers/cluster/serviceexport/serviceexport_reconcile_test.go b/pkg/konnector/controllers/cluster/serviceexport/serviceexport_reconcile_test.go index a8379c55..842bba5a 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/serviceexport_reconcile_test.go +++ b/pkg/konnector/controllers/cluster/serviceexport/serviceexport_reconcile_test.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,15 +19,14 @@ package serviceexport import ( "testing" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" - conditionsapi "kmodules.xyz/client-go/api/v1" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + conditionsapi "kmodules.xyz/client-go/api/v1" ) func TestEnsureCRDConditionsCopied(t *testing.T) { diff --git a/pkg/konnector/controllers/cluster/serviceexport/spec/spec_controller.go b/pkg/konnector/controllers/cluster/serviceexport/spec/spec_controller.go index 05c6a27e..b9ad5657 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/spec/spec_controller.go +++ b/pkg/konnector/controllers/cluster/serviceexport/spec/spec_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,6 +22,12 @@ import ( "fmt" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + clusterscoped "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -37,12 +43,6 @@ import ( "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" "k8s.io/utils/ptr" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - "go.bytebuilders.dev/kube-bind/pkg/indexers" - clusterscoped "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" ) const ( diff --git a/pkg/konnector/controllers/cluster/serviceexport/spec/spec_reconcile.go b/pkg/konnector/controllers/cluster/serviceexport/spec/spec_reconcile.go index c66b2186..053ee77a 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/spec/spec_reconcile.go +++ b/pkg/konnector/controllers/cluster/serviceexport/spec/spec_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,19 +23,19 @@ import ( "reflect" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" ) type reconciler struct { getProviderInfo func(obj *unstructured.Unstructured) (*konnectormodels.ProviderInfo, error) - getServiceNamespace func(provider *konnectormodels.ProviderInfo, name string) (*kubebindv1alpha1.APIServiceNamespace, error) - createServiceNamespace func(ctx context.Context, provider *konnectormodels.ProviderInfo, sn *kubebindv1alpha1.APIServiceNamespace) (*kubebindv1alpha1.APIServiceNamespace, error) + getServiceNamespace func(provider *konnectormodels.ProviderInfo, name string) (*v1alpha1.APIServiceNamespace, error) + createServiceNamespace func(ctx context.Context, provider *konnectormodels.ProviderInfo, sn *v1alpha1.APIServiceNamespace) (*v1alpha1.APIServiceNamespace, error) getProviderObject func(provider *konnectormodels.ProviderInfo, ns, name string) (*unstructured.Unstructured, error) createProviderObject func(ctx context.Context, provider *konnectormodels.ProviderInfo, obj *unstructured.Unstructured) (*unstructured.Unstructured, error) @@ -66,7 +66,7 @@ func (r *reconciler) reconcile(ctx context.Context, obj *unstructured.Unstructur return err } else if errors.IsNotFound(err) { logger.V(1).Info("creating APIServiceNamespace", "namespace", ns) - sn, err = r.createServiceNamespace(ctx, provider, &kubebindv1alpha1.APIServiceNamespace{ + sn, err = r.createServiceNamespace(ctx, provider, &v1alpha1.APIServiceNamespace{ ObjectMeta: metav1.ObjectMeta{ Name: ns, Namespace: provider.Namespace, @@ -199,7 +199,7 @@ func (r *reconciler) ensureDownstreamFinalizer(ctx context.Context, obj *unstruc // check that downstream has our finalizer found := false for _, f := range obj.GetFinalizers() { - if f == kubebindv1alpha1.DownstreamFinalizer { + if f == v1alpha1.DownstreamFinalizer { found = true break } @@ -208,7 +208,7 @@ func (r *reconciler) ensureDownstreamFinalizer(ctx context.Context, obj *unstruc if !found { logger.V(2).Info("adding finalizer to downstream object") obj = obj.DeepCopy() - obj.SetFinalizers(append(obj.GetFinalizers(), kubebindv1alpha1.DownstreamFinalizer)) + obj.SetFinalizers(append(obj.GetFinalizers(), v1alpha1.DownstreamFinalizer)) var err error if obj, err = r.updateConsumerObject(ctx, obj); err != nil { return nil, err @@ -224,7 +224,7 @@ func (r *reconciler) removeDownstreamFinalizer(ctx context.Context, obj *unstruc var finalizers []string found := false for _, f := range obj.GetFinalizers() { - if f == kubebindv1alpha1.DownstreamFinalizer { + if f == v1alpha1.DownstreamFinalizer { found = true continue } diff --git a/pkg/konnector/controllers/cluster/serviceexport/status/status_controller.go b/pkg/konnector/controllers/cluster/serviceexport/status/status_controller.go index 65762d13..b8911a32 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/status/status_controller.go +++ b/pkg/konnector/controllers/cluster/serviceexport/status/status_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,15 +19,15 @@ package status import ( "context" "fmt" - corev1 "k8s.io/api/core/v1" - "sigs.k8s.io/controller-runtime/pkg/client" "strings" "time" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" "go.bytebuilders.dev/kube-bind/pkg/indexers" clusterscoped "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped" konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -43,6 +43,7 @@ import ( "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" kmc "kmodules.xyz/client-go/client" + "sigs.k8s.io/controller-runtime/pkg/client" ) const ( @@ -79,7 +80,7 @@ func NewController( if err != nil { return nil, err } - //TODO: provider.dynamic client association is removed. Add it if needed + // TODO: provider.dynamic client association is removed. Add it if needed dynamicConsumerLister := dynamiclister.New(consumerDynamicInformer.Informer().GetIndexer(), gvr) c := &controller{ @@ -103,15 +104,15 @@ func NewController( return konnectormodels.GetProviderInfoWithClusterID(providerInfos, clusterID) } }, - getServiceNamespace: func(provider *konnectormodels.ProviderInfo, upstreamNamespace string) (*kubebindv1alpha1.APIServiceNamespace, error) { + getServiceNamespace: func(provider *konnectormodels.ProviderInfo, upstreamNamespace string) (*v1alpha1.APIServiceNamespace, error) { sns, err := provider.DynamicServiceNamespaceInformer.Informer().GetIndexer().ByIndex(indexers.ServiceNamespaceByNamespace, upstreamNamespace) if err != nil { return nil, err } if len(sns) == 0 { - return nil, errors.NewNotFound(kubebindv1alpha1.SchemeGroupVersion.WithResource("APIServiceNamespace").GroupResource(), upstreamNamespace) + return nil, errors.NewNotFound(v1alpha1.SchemeGroupVersion.WithResource("APIServiceNamespace").GroupResource(), upstreamNamespace) } - return sns[0].(*kubebindv1alpha1.APIServiceNamespace), nil + return sns[0].(*v1alpha1.APIServiceNamespace), nil }, getConsumerObject: func(provider *konnectormodels.ProviderInfo, ns, name string) (*unstructured.Unstructured, error) { if ns != "" { @@ -178,7 +179,7 @@ func NewController( Data: providerSecret.Data, } - //delete backdated secret from consumer + // delete backdated secret from consumer oldSecretName, found, err := unstructured.NestedString(downstream.Object, "status", "secretRef", "name") if err != nil { return "", err @@ -283,7 +284,7 @@ func (c *controller) enqueueProvider(logger klog.Logger, provider *konnectormode return } for _, obj := range sns { - sns := obj.(*kubebindv1alpha1.APIServiceNamespace) + sns := obj.(*v1alpha1.APIServiceNamespace) if sns.Namespace == provider.Namespace { logger.V(2).Info("queueing Unstructured", "key", key) c.queue.Add(provider.ClusterID + "/" + key) @@ -517,7 +518,7 @@ func (c *controller) removeDownstreamFinalizer(ctx context.Context, obj *unstruc var finalizers []string found := false for _, f := range obj.GetFinalizers() { - if f == kubebindv1alpha1.DownstreamFinalizer { + if f == v1alpha1.DownstreamFinalizer { found = true continue } diff --git a/pkg/konnector/controllers/cluster/serviceexport/status/status_reconcile.go b/pkg/konnector/controllers/cluster/serviceexport/status/status_reconcile.go index 59059c85..fa0eb47e 100644 --- a/pkg/konnector/controllers/cluster/serviceexport/status/status_reconcile.go +++ b/pkg/konnector/controllers/cluster/serviceexport/status/status_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,13 +20,13 @@ import ( "context" "reflect" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" ) type reconciler struct { diff --git a/pkg/konnector/controllers/dynamic/eventhandler.go b/pkg/konnector/controllers/dynamic/eventhandler.go index 871803fb..5a5a4009 100644 --- a/pkg/konnector/controllers/dynamic/eventhandler.go +++ b/pkg/konnector/controllers/dynamic/eventhandler.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/konnector/controllers/servicebinding/servicebinding_controller.go b/pkg/konnector/controllers/servicebinding/servicebinding_controller.go index 3c3971a5..8a0215df 100644 --- a/pkg/konnector/controllers/servicebinding/servicebinding_controller.go +++ b/pkg/konnector/controllers/servicebinding/servicebinding_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,13 @@ import ( "fmt" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind/v1alpha1" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors" @@ -32,13 +39,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind/v1alpha1" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" - "go.bytebuilders.dev/kube-bind/pkg/indexers" ) const ( @@ -122,8 +122,10 @@ func NewController( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.APIServiceBindingSpec, *kubebindv1alpha1.APIServiceBindingStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*kubebindv1alpha1.APIServiceBindingSpec, *kubebindv1alpha1.APIServiceBindingStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) // controller reconciles ServiceBindings' kubeconfig secret references. It is // here as an individual controller because the cluster controller is not running diff --git a/pkg/konnector/controllers/servicebinding/servicebinding_reconcile.go b/pkg/konnector/controllers/servicebinding/servicebinding_reconcile.go index 17f640d7..1acef380 100644 --- a/pkg/konnector/controllers/servicebinding/servicebinding_reconcile.go +++ b/pkg/konnector/controllers/servicebinding/servicebinding_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,15 +19,14 @@ package servicebinding import ( "context" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/client-go/tools/clientcmd" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) type reconciler struct { diff --git a/pkg/konnector/konnector_controller.go b/pkg/konnector/konnector_controller.go index d1590dbc..6a64e2d1 100644 --- a/pkg/konnector/konnector_controller.go +++ b/pkg/konnector/konnector_controller.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,17 @@ import ( "fmt" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions/kubebind/v1alpha1" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/committer" + "go.bytebuilders.dev/kube-bind/pkg/indexers" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/servicebinding" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + corev1 "k8s.io/api/core/v1" crdinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1" apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" @@ -34,17 +45,6 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions/kubebind/v1alpha1" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/committer" - "go.bytebuilders.dev/kube-bind/pkg/indexers" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/servicebinding" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" ) const ( @@ -100,7 +100,6 @@ func New( }, providerInfos: make([]*konnectormodels.ProviderInfo, 0), newClusterController: func(providerInfos []*konnectormodels.ProviderInfo, reconcileServiceBinding func(binding *kubebindv1alpha1.APIServiceBinding) bool) (startable, error) { - for _, provider := range providerInfos { provider.Config = rest.CopyConfig(provider.Config) provider.Config = rest.AddUserAgent(provider.Config, controllerName) @@ -166,8 +165,10 @@ func New( return c, nil } -type Resource = committer.Resource[*kubebindv1alpha1.APIServiceBindingSpec, *kubebindv1alpha1.APIServiceBindingStatus] -type CommitFunc = func(context.Context, *Resource, *Resource) error +type ( + Resource = committer.Resource[*kubebindv1alpha1.APIServiceBindingSpec, *kubebindv1alpha1.APIServiceBindingStatus] + CommitFunc = func(context.Context, *Resource, *Resource) error +) type GenericController interface { Start(ctx context.Context, numThreads int) diff --git a/pkg/konnector/konnector_reconcile.go b/pkg/konnector/konnector_reconcile.go index 59b20d61..306fa5a3 100644 --- a/pkg/konnector/konnector_reconcile.go +++ b/pkg/konnector/konnector_reconcile.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,9 @@ import ( "reflect" "sync" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -28,9 +31,6 @@ import ( kubernetesclient "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - konnectormodels "go.bytebuilders.dev/kube-bind/pkg/konnector/models" ) const namespaceKubeSystem = "kube-system" diff --git a/pkg/konnector/models/helper.go b/pkg/konnector/models/helper.go index c0c9461e..d00a6c17 100644 --- a/pkg/konnector/models/helper.go +++ b/pkg/konnector/models/helper.go @@ -1,3 +1,19 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the AppsCode Community License 1.0.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md + +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. +*/ + package models const ( diff --git a/pkg/konnector/models/provider.go b/pkg/konnector/models/provider.go index 492e9a1b..92fa1312 100644 --- a/pkg/konnector/models/provider.go +++ b/pkg/konnector/models/provider.go @@ -1,19 +1,35 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the AppsCode Community License 1.0.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md + +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. +*/ + package models import ( "fmt" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + bindinformers "go.bytebuilders.dev/kube-bind/client/informers/externalversions" + bindlisters "go.bytebuilders.dev/kube-bind/client/listers/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/multinsinformer" + "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" dynamicclient "k8s.io/client-go/dynamic" kubernetesinformers "k8s.io/client-go/informers" kubernetesclient "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" - - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - bindinformers "go.bytebuilders.dev/kube-bind/pkg/client/informers/externalversions" - bindlisters "go.bytebuilders.dev/kube-bind/pkg/client/listers/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/multinsinformer" - "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/dynamic" ) type ProviderInfo struct { diff --git a/pkg/konnector/options/options.go b/pkg/konnector/options/options.go index ed5b0141..f89a2fee 100644 --- a/pkg/konnector/options/options.go +++ b/pkg/konnector/options/options.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,7 +22,6 @@ import ( "os" "github.com/spf13/pflag" - "k8s.io/component-base/logs" logsv1 "k8s.io/component-base/logs/api/v1" ) diff --git a/pkg/konnector/server.go b/pkg/konnector/server.go index ed9a02d1..8e9a4c3f 100644 --- a/pkg/konnector/server.go +++ b/pkg/konnector/server.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,11 +20,10 @@ import ( "context" "fmt" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/klog/v2" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/deploy/crd" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + "k8s.io/klog/v2" + "kmodules.xyz/client-go/apiextensions" ) type Server struct { @@ -63,10 +62,9 @@ type Prepared struct { func (s *Server) PrepareRun(ctx context.Context) (Prepared, error) { // install/upgrade CRDs - if err := crd.Create(ctx, - s.Config.ApiextensionsClient.ApiextensionsV1().CustomResourceDefinitions(), - metav1.GroupResource{Group: kubebindv1alpha1.GroupName, Resource: "apiservicebindings"}, - ); err != nil { + if err := apiextensions.RegisterCRDs(s.Config.ApiextensionsClient, []*apiextensions.CustomResourceDefinition{ + kubebindv1alpha1.APIServiceBinding{}.CustomResourceDefinition(), + }); err != nil { return Prepared{}, err } return Prepared{ diff --git a/pkg/kubectl/base/kubeconfig.go b/pkg/kubectl/base/kubeconfig.go index af0ae06e..bf079725 100644 --- a/pkg/kubectl/base/kubeconfig.go +++ b/pkg/kubectl/base/kubeconfig.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,7 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/retry" diff --git a/pkg/kubectl/base/options.go b/pkg/kubectl/base/options.go index e57017c9..137b3e08 100644 --- a/pkg/kubectl/base/options.go +++ b/pkg/kubectl/base/options.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -18,7 +18,6 @@ package base import ( "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/tools/clientcmd" ) diff --git a/pkg/kubectl/bind-apiservice/cmd/cmd.go b/pkg/kubectl/bind-apiservice/cmd/cmd.go index 5b4c88a8..6034f063 100644 --- a/pkg/kubectl/bind-apiservice/cmd/cmd.go +++ b/pkg/kubectl/bind-apiservice/cmd/cmd.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -19,19 +19,17 @@ package cmd import ( "fmt" + "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind-apiservice/plugin" + "github.com/fatih/color" "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericclioptions" _ "k8s.io/client-go/plugin/pkg/client/auth/exec" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" logsv1 "k8s.io/component-base/logs/api/v1" - - "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind-apiservice/plugin" ) -var ( - bindAPIServiceExampleUses = ` +var bindAPIServiceExampleUses = ` # bind to a remote API service. Use kubectl bind to create the APIServiceExportRequest interactively. %[1]s apiservice --remote-kubeconfig file -f apiservice-export-request.yaml @@ -41,7 +39,6 @@ var ( # bind to a API service directly without any remote agent or service provider. %[1]s apiservice --remote-kubeconfig file -n remote-namespace resources.group/v1 ` -) func New(streams genericclioptions.IOStreams) (*cobra.Command, error) { opts := plugin.NewBindAPIServiceOptions(streams) diff --git a/pkg/kubectl/bind-apiservice/plugin/bind.go b/pkg/kubectl/bind-apiservice/plugin/bind.go index c71c5a6c..f7cfab35 100644 --- a/pkg/kubectl/bind-apiservice/plugin/bind.go +++ b/pkg/kubectl/bind-apiservice/plugin/bind.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -26,8 +26,10 @@ import ( "os" "strings" - "github.com/spf13/cobra" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/kubectl/base" + "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/cli-runtime/pkg/genericclioptions" @@ -38,9 +40,6 @@ import ( "k8s.io/component-base/logs" logsv1 "k8s.io/component-base/logs/api/v1" "sigs.k8s.io/yaml" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/kubectl/base" ) // BindAPIServiceOptions are the options for the kubectl-bind-apiservice command. @@ -72,7 +71,7 @@ func NewBindAPIServiceOptions(streams genericclioptions.IOStreams) *BindAPIServi return &BindAPIServiceOptions{ Options: base.NewOptions(streams), Logs: logs.NewOptions(), - Print: genericclioptions.NewPrintFlags("kubectl-bind-apiservice"), + Print: genericclioptions.NewPrintFlags("kubectl-connect-apiservice"), } } @@ -257,12 +256,12 @@ func (b *BindAPIServiceOptions) getRequestManifest() ([]byte, error) { return body, nil } -func (b *BindAPIServiceOptions) unmarshalManifest(bs []byte) (*kubebindv1alpha1.APIServiceExportRequest, error) { - var request kubebindv1alpha1.APIServiceExportRequest +func (b *BindAPIServiceOptions) unmarshalManifest(bs []byte) (*v1alpha1.APIServiceExportRequest, error) { + var request v1alpha1.APIServiceExportRequest if err := yaml.Unmarshal(bs, &request); err != nil { return nil, fmt.Errorf("failed to unmarshal manifest: %w", err) } - if request.APIVersion != kubebindv1alpha1.SchemeGroupVersion.String() { + if request.APIVersion != v1alpha1.SchemeGroupVersion.String() { return nil, fmt.Errorf("invalid apiVersion %q", request.APIVersion) } if request.Kind != "APIServiceExportRequest" { diff --git a/pkg/kubectl/bind-apiservice/plugin/konnector.go b/pkg/kubectl/bind-apiservice/plugin/konnector.go index 0e95751f..e0c2eff0 100644 --- a/pkg/kubectl/bind-apiservice/plugin/konnector.go +++ b/pkg/kubectl/bind-apiservice/plugin/konnector.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,8 +22,11 @@ import ( "strings" "time" - "github.com/blang/semver/v4" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + "go.bytebuilders.dev/kube-bind/deploy/konnector" + "go.bytebuilders.dev/kube-bind/pkg/version" + "github.com/blang/semver/v4" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" @@ -33,14 +36,10 @@ import ( clientgoversion "k8s.io/client-go/pkg/version" "k8s.io/client-go/rest" "k8s.io/klog/v2" - - "go.bytebuilders.dev/kube-bind/deploy/konnector" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" - "go.bytebuilders.dev/kube-bind/pkg/version" ) const ( - //konnectorImage = "ghcr.io/kube-bind/konnector" + // konnectorImage = "ghcr.io/kube-bind/konnector" konnectorImage = "superm4n/konnector" ) diff --git a/pkg/kubectl/bind-apiservice/plugin/secret.go b/pkg/kubectl/bind-apiservice/plugin/secret.go index 52d6010e..bb737aaa 100644 --- a/pkg/kubectl/bind-apiservice/plugin/secret.go +++ b/pkg/kubectl/bind-apiservice/plugin/secret.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,13 +20,13 @@ import ( "context" "fmt" + "go.bytebuilders.dev/kube-bind/pkg/kubectl/base" + corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubeclient "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" - - "go.bytebuilders.dev/kube-bind/pkg/kubectl/base" ) func (b *BindAPIServiceOptions) createKubeconfigSecret(ctx context.Context, config *rest.Config, remoteHost, remoteNamespace, kubeconfig string) (string, error) { diff --git a/pkg/kubectl/bind-apiservice/plugin/servicebindings.go b/pkg/kubectl/bind-apiservice/plugin/servicebindings.go index 47654497..e493cd83 100644 --- a/pkg/kubectl/bind-apiservice/plugin/servicebindings.go +++ b/pkg/kubectl/bind-apiservice/plugin/servicebindings.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,25 +21,24 @@ import ( "fmt" "time" - conditionsapi "kmodules.xyz/client-go/api/v1" - "kmodules.xyz/client-go/conditions" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1/helpers" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/rest" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1/helpers" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" + conditionsapi "kmodules.xyz/client-go/api/v1" + "kmodules.xyz/client-go/conditions" ) const ( kubeconfigSecretNamespace = "kube-bind" ) -func (b *BindAPIServiceOptions) createAPIServiceBindings(ctx context.Context, config *rest.Config, request *kubebindv1alpha1.APIServiceExportRequest, secretName string) ([]*kubebindv1alpha1.APIServiceBinding, error) { +func (b *BindAPIServiceOptions) createAPIServiceBindings(ctx context.Context, config *rest.Config, request *v1alpha1.APIServiceExportRequest, secretName string) ([]*v1alpha1.APIServiceBinding, error) { bindClient, err := bindclient.NewForConfig(config) if err != nil { return nil, err @@ -49,7 +48,7 @@ func (b *BindAPIServiceOptions) createAPIServiceBindings(ctx context.Context, co return nil, err } - var bindings []*kubebindv1alpha1.APIServiceBinding + var bindings []*v1alpha1.APIServiceBinding for _, resource := range request.Spec.Resources { name := resource.Resource + "." + resource.Group existing, err := bindClient.KubeBindV1alpha1().APIServiceBindings().Get(ctx, name, metav1.GetOptions{}) @@ -74,8 +73,8 @@ func (b *BindAPIServiceOptions) createAPIServiceBindings(ctx context.Context, co fmt.Fprintf(b.Options.IOStreams.ErrOut, "✅ Updating existing APIServiceBinding %s.\n", existing.Name) // nolint: errcheck - existing.Spec.KubeconfigSecretRefs = append(existing.Spec.KubeconfigSecretRefs, kubebindv1alpha1.ClusterSecretKeyRef{ - LocalSecretKeyRef: kubebindv1alpha1.LocalSecretKeyRef{ + existing.Spec.KubeconfigSecretRefs = append(existing.Spec.KubeconfigSecretRefs, v1alpha1.ClusterSecretKeyRef{ + LocalSecretKeyRef: v1alpha1.LocalSecretKeyRef{ Name: secretName, Key: "kubeconfig", }, @@ -108,15 +107,15 @@ func (b *BindAPIServiceOptions) createAPIServiceBindings(ctx context.Context, co first = false fmt.Fprint(b.Options.IOStreams.ErrOut, ".") // nolint: errcheck } - created, err := bindClient.KubeBindV1alpha1().APIServiceBindings().Create(ctx, &kubebindv1alpha1.APIServiceBinding{ + created, err := bindClient.KubeBindV1alpha1().APIServiceBindings().Create(ctx, &v1alpha1.APIServiceBinding{ ObjectMeta: metav1.ObjectMeta{ Name: resource.Resource + "." + resource.Group, Namespace: "kube-bind", }, - Spec: kubebindv1alpha1.APIServiceBindingSpec{ - KubeconfigSecretRefs: []kubebindv1alpha1.ClusterSecretKeyRef{ + Spec: v1alpha1.APIServiceBindingSpec{ + KubeconfigSecretRefs: []v1alpha1.ClusterSecretKeyRef{ { - LocalSecretKeyRef: kubebindv1alpha1.LocalSecretKeyRef{ + LocalSecretKeyRef: v1alpha1.LocalSecretKeyRef{ Name: secretName, Key: "kubeconfig", }, diff --git a/pkg/kubectl/bind-apiservice/plugin/serviceexportrequest.go b/pkg/kubectl/bind-apiservice/plugin/serviceexportrequest.go index ead4079d..81930d3e 100644 --- a/pkg/kubectl/bind-apiservice/plugin/serviceexportrequest.go +++ b/pkg/kubectl/bind-apiservice/plugin/serviceexportrequest.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,6 +21,9 @@ import ( "fmt" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + bindclient "go.bytebuilders.dev/kube-bind/client/clientset/versioned" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -28,17 +31,14 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/cli-runtime/pkg/printers" "k8s.io/client-go/rest" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - bindclient "go.bytebuilders.dev/kube-bind/pkg/client/clientset/versioned" ) func (b *BindAPIServiceOptions) createServiceExportRequest( ctx context.Context, remoteConfig *rest.Config, ns string, - request *kubebindv1alpha1.APIServiceExportRequest, -) (*kubebindv1alpha1.APIServiceExportRequest, error) { + request *v1alpha1.APIServiceExportRequest, +) (*v1alpha1.APIServiceExportRequest, error) { bindRemoteClient, err := bindclient.NewForConfig(remoteConfig) if err != nil { return nil, err @@ -63,7 +63,7 @@ func (b *BindAPIServiceOptions) createServiceExportRequest( } // wait for the request to be Successful, Failed or deleted - var result *kubebindv1alpha1.APIServiceExportRequest + var result *v1alpha1.APIServiceExportRequest if err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 10*time.Minute, true, func(ctx context.Context) (bool, error) { request, err := bindRemoteClient.KubeBindV1alpha1().APIServiceExportRequests(ns).Get(ctx, created.Name, metav1.GetOptions{}) if err != nil && !apierrors.IsNotFound(err) { @@ -71,11 +71,11 @@ func (b *BindAPIServiceOptions) createServiceExportRequest( } else if apierrors.IsNotFound(err) { return false, fmt.Errorf("APIServiceExportRequest %s was deleted by the service provider", created.Name) } - if request.Status.Phase == kubebindv1alpha1.APIServiceExportRequestPhaseSucceeded { + if request.Status.Phase == v1alpha1.APIServiceExportRequestPhaseSucceeded { result = request return true, nil } - if request.Status.Phase == kubebindv1alpha1.APIServiceExportRequestPhaseFailed { + if request.Status.Phase == v1alpha1.APIServiceExportRequestPhaseFailed { return false, fmt.Errorf("binding request failed: %s", request.Status.TerminalMessage) } return false, nil @@ -86,16 +86,16 @@ func (b *BindAPIServiceOptions) createServiceExportRequest( return result, nil } -func (b *BindAPIServiceOptions) printTable(ctx context.Context, config *rest.Config, bindings []*kubebindv1alpha1.APIServiceBinding) error { +func (b *BindAPIServiceOptions) printTable(ctx context.Context, config *rest.Config, bindings []*v1alpha1.APIServiceBinding) error { printer := printers.NewTablePrinter(printers.PrintOptions{ WithKind: true, - Kind: kubebindv1alpha1.SchemeGroupVersion.WithKind("APIServiceBinding").GroupKind(), + Kind: v1alpha1.SchemeGroupVersion.WithKind("APIServiceBinding").GroupKind(), }) tableConfig := rest.CopyConfig(config) tableConfig.APIPath = "/apis" tableConfig.ContentConfig.AcceptContentTypes = fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1.SchemeGroupVersion.Version, metav1.GroupName) - tableConfig.GroupVersion = &kubebindv1alpha1.SchemeGroupVersion + tableConfig.GroupVersion = &v1alpha1.SchemeGroupVersion scheme := runtime.NewScheme() if err := metav1.AddMetaToScheme(scheme); err != nil { return err diff --git a/pkg/kubectl/bind/authenticator/authenticator.go b/pkg/kubectl/bind/authenticator/authenticator.go index 0828bc7e..8f9817a3 100644 --- a/pkg/kubectl/bind/authenticator/authenticator.go +++ b/pkg/kubectl/bind/authenticator/authenticator.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -27,13 +27,13 @@ import ( "sync" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/klog/v2" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" ) var ( diff --git a/pkg/kubectl/bind/cmd/cmd.go b/pkg/kubectl/bind/cmd/cmd.go index 6ddd1bad..33b21115 100644 --- a/pkg/kubectl/bind/cmd/cmd.go +++ b/pkg/kubectl/bind/cmd/cmd.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,20 +20,18 @@ import ( "fmt" "strings" + "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind/plugin" + "github.com/fatih/color" "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericclioptions" _ "k8s.io/client-go/plugin/pkg/client/auth/exec" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" logsv1 "k8s.io/component-base/logs/api/v1" - - "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind/plugin" ) -var ( - // TODO: add other examples related to permission claim commands. - bindExampleUses = ` +// TODO: add other examples related to permission claim commands. +var bindExampleUses = ` # select a kube-bind.appscode.com compatible service from the given URL, e.g. an API service. %[1]s bind https://mangodb.com/exports @@ -46,7 +44,6 @@ var ( # bind to a remote API service via a request manifest from a https URL. %[1]s bind apiservice --remote-kubeconfig name https://some-url.com/apiservice-export-requests.yaml ` -) func New(streams genericclioptions.IOStreams) (*cobra.Command, error) { opts := plugin.NewBindOptions(streams) diff --git a/pkg/kubectl/bind/plugin/authenticate.go b/pkg/kubectl/bind/plugin/authenticate.go index 030ff14e..d8d2e505 100644 --- a/pkg/kubectl/bind/plugin/authenticate.go +++ b/pkg/kubectl/bind/plugin/authenticate.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -26,13 +26,12 @@ import ( "net/url" "strings" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/version" + "github.com/blang/semver/v4" "github.com/mdp/qrterminal/v3" - clientgoversion "k8s.io/client-go/pkg/version" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/version" ) func getProvider(url string) (*kubebindv1alpha1.BindingProvider, error) { diff --git a/pkg/kubectl/bind/plugin/authenticate_test.go b/pkg/kubectl/bind/plugin/authenticate_test.go index ed8f33a7..313ead82 100644 --- a/pkg/kubectl/bind/plugin/authenticate_test.go +++ b/pkg/kubectl/bind/plugin/authenticate_test.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/kubectl/bind/plugin/bind.go b/pkg/kubectl/bind/plugin/bind.go index 5f25ef8b..030bd9e7 100644 --- a/pkg/kubectl/bind/plugin/bind.go +++ b/pkg/kubectl/bind/plugin/bind.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -31,9 +31,12 @@ import ( "strings" "time" + "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + "go.bytebuilders.dev/kube-bind/pkg/kubectl/base" + "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind/authenticator" + "github.com/spf13/cobra" "github.com/spf13/pflag" - corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,10 +45,6 @@ import ( kubeclient "k8s.io/client-go/kubernetes" "k8s.io/component-base/logs" logsv1 "k8s.io/component-base/logs/api/v1" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/kubectl/base" - "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind/authenticator" ) // BindOptions contains the options for creating an APIBinding. @@ -78,7 +77,7 @@ func NewBindOptions(streams genericclioptions.IOStreams) *BindOptions { opts := &BindOptions{ Options: base.NewOptions(streams), Logs: logs.NewOptions(), - Print: genericclioptions.NewPrintFlags("kubectl-bind").WithDefaultOutput("yaml"), + Print: genericclioptions.NewPrintFlags("kubectl-connect").WithDefaultOutput("yaml"), Runner: func(cmd *exec.Cmd) error { return cmd.Run() @@ -155,7 +154,7 @@ func (b *BindOptions) Run(ctx context.Context, urlCh chan<- string) error { return fmt.Errorf("failed to fetch authentication url %q: %v", exportURL, err) } - if provider.APIVersion != kubebindv1alpha1.GroupVersion { + if provider.APIVersion != v1alpha1.GroupVersion { return fmt.Errorf("unsupported binding provider version: %q", provider.APIVersion) } @@ -197,10 +196,10 @@ func (b *BindOptions) Run(ctx context.Context, urlCh chan<- string) error { fmt.Fprintf(b.IOStreams.ErrOut, "🔑 Successfully authenticated to %s\n", exportURL.String()) // nolint: errcheck // verify the response - if gvk.GroupVersion() != kubebindv1alpha1.SchemeGroupVersion || gvk.Kind != "BindingResponse" { - return fmt.Errorf("unexpected response type %s, only supporting %s", gvk, kubebindv1alpha1.SchemeGroupVersion.WithKind("BindingResponse")) + if gvk.GroupVersion() != v1alpha1.SchemeGroupVersion || gvk.Kind != "BindingResponse" { + return fmt.Errorf("unexpected response type %s, only supporting %s", gvk, v1alpha1.SchemeGroupVersion.WithKind("BindingResponse")) } - bindingResponse, ok := response.(*kubebindv1alpha1.BindingResponse) + bindingResponse, ok := response.(*v1alpha1.BindingResponse) if !ok { return fmt.Errorf("unexpected response type %T", response) } @@ -212,16 +211,16 @@ func (b *BindOptions) Run(ctx context.Context, urlCh chan<- string) error { } // extract the requests - var apiRequests []*kubebindv1alpha1.APIServiceExportRequestResponse + var apiRequests []*v1alpha1.APIServiceExportRequestResponse for i, request := range bindingResponse.Requests { var meta metav1.TypeMeta if err := json.Unmarshal(request.Raw, &meta); err != nil { return fmt.Errorf("unexpected response: failed to unmarshal request #%d: %v", i, err) } - if got, expected := meta.APIVersion, kubebindv1alpha1.SchemeGroupVersion.String(); got != expected { + if got, expected := meta.APIVersion, v1alpha1.SchemeGroupVersion.String(); got != expected { return fmt.Errorf("unexpected response: request #%d is not %s, got %s", i, expected, got) } - var apiRequest kubebindv1alpha1.APIServiceExportRequestResponse + var apiRequest v1alpha1.APIServiceExportRequestResponse if err := json.Unmarshal(request.Raw, &apiRequest); err != nil { return fmt.Errorf("failed to unmarshal api request #%d: %v", i+1, err) } diff --git a/pkg/kubectl/bind/plugin/flags.go b/pkg/kubectl/bind/plugin/flags.go index 58c1ef5b..b25e4d0a 100644 --- a/pkg/kubectl/bind/plugin/flags.go +++ b/pkg/kubectl/bind/plugin/flags.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/kubectl/bind/plugin/flags_test.go b/pkg/kubectl/bind/plugin/flags_test.go index f31c12cc..4c73796d 100644 --- a/pkg/kubectl/bind/plugin/flags_test.go +++ b/pkg/kubectl/bind/plugin/flags_test.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/util/sets" "k8s.io/cli-runtime/pkg/genericclioptions" ) diff --git a/pkg/version/version.go b/pkg/version/version.go index 18600c31..efdedff4 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/pkg/version/version_test.go b/pkg/version/version_test.go index 8849b9e1..9331f353 100644 --- a/pkg/version/version_test.go +++ b/pkg/version/version_test.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/test/e2e/bind/fixtures/provider/bootstrap.go b/test/e2e/bind/fixtures/provider/bootstrap.go index 149eede8..b3c77323 100644 --- a/test/e2e/bind/fixtures/provider/bootstrap.go +++ b/test/e2e/bind/fixtures/provider/bootstrap.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,13 +21,12 @@ import ( "embed" "testing" - "github.com/stretchr/testify/require" + "go.bytebuilders.dev/kube-bind/pkg/bootstrap" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" - - "go.bytebuilders.dev/kube-bind/pkg/bootstrap" ) //go:embed *.yaml diff --git a/test/e2e/bind/happy-case_test.go b/test/e2e/bind/happy-case_test.go index b199b34e..693d051f 100644 --- a/test/e2e/bind/happy-case_test.go +++ b/test/e2e/bind/happy-case_test.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,9 +23,13 @@ import ( "testing" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + clusterscoped "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped" + providerfixtures "go.bytebuilders.dev/kube-bind/test/e2e/bind/fixtures/provider" + "go.bytebuilders.dev/kube-bind/test/e2e/framework" + "github.com/stretchr/testify/require" "gopkg.in/headzoo/surf.v1" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -35,11 +39,6 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/util/retry" "sigs.k8s.io/yaml" - - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - clusterscoped "go.bytebuilders.dev/kube-bind/pkg/konnector/controllers/cluster/serviceexport/cluster-scoped" - providerfixtures "go.bytebuilders.dev/kube-bind/test/e2e/bind/fixtures/provider" - "go.bytebuilders.dev/kube-bind/test/e2e/framework" ) func TestClusterScoped(t *testing.T) { diff --git a/test/e2e/framework/backend.go b/test/e2e/framework/backend.go index 2bcaaefa..66130c30 100644 --- a/test/e2e/framework/backend.go +++ b/test/e2e/framework/backend.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -24,21 +24,20 @@ import ( "testing" "time" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + backend "go.bytebuilders.dev/kube-bind/contrib/example-backend" + "go.bytebuilders.dev/kube-bind/contrib/example-backend/options" + dexapi "github.com/dexidp/dex/api/v2" "github.com/gorilla/securecookie" "github.com/spf13/pflag" "github.com/stretchr/testify/require" "google.golang.org/grpc" grpcinsecure "google.golang.org/grpc/credentials/insecure" - apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/rest" - - backend "go.bytebuilders.dev/kube-bind/contrib/example-backend" - "go.bytebuilders.dev/kube-bind/contrib/example-backend/options" - "go.bytebuilders.dev/kube-bind/deploy/crd" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" + "kmodules.xyz/client-go/apiextensions" ) func StartBackend(t *testing.T, clientConfig *rest.Config, args ...string) (net.Addr, *backend.Server) { @@ -61,13 +60,12 @@ func StartBackendWithoutDefaultArgs(t *testing.T, clientConfig *rest.Config, arg crdClient, err := apiextensionsclient.NewForConfig(clientConfig) require.NoError(t, err) - err = crd.Create(ctx, - crdClient.ApiextensionsV1().CustomResourceDefinitions(), - metav1.GroupResource{Group: kubebindv1alpha1.GroupName, Resource: "clusterbindings"}, - metav1.GroupResource{Group: kubebindv1alpha1.GroupName, Resource: "apiserviceexports"}, - metav1.GroupResource{Group: kubebindv1alpha1.GroupName, Resource: "apiservicenamespaces"}, - metav1.GroupResource{Group: kubebindv1alpha1.GroupName, Resource: "apiserviceexportrequests"}, - ) + err = apiextensions.RegisterCRDs(crdClient, []*apiextensions.CustomResourceDefinition{ + kubebindv1alpha1.ClusterBinding{}.CustomResourceDefinition(), + kubebindv1alpha1.APIServiceExport{}.CustomResourceDefinition(), + kubebindv1alpha1.APIServiceNamespace{}.CustomResourceDefinition(), + kubebindv1alpha1.APIServiceExportRequest{}.CustomResourceDefinition(), + }) require.NoError(t, err) fs := pflag.NewFlagSet("example-backend", pflag.ContinueOnError) diff --git a/test/e2e/framework/bind.go b/test/e2e/framework/bind.go index 2fa08c21..ea0d43ce 100644 --- a/test/e2e/framework/bind.go +++ b/test/e2e/framework/bind.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -25,13 +25,12 @@ import ( "strings" "testing" + bindapiserviceplugin "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind-apiservice/plugin" + bindplugin "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind/plugin" + "github.com/spf13/cobra" "github.com/stretchr/testify/require" - "k8s.io/cli-runtime/pkg/genericclioptions" - - bindapiserviceplugin "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind-apiservice/plugin" - bindplugin "go.bytebuilders.dev/kube-bind/pkg/kubectl/bind/plugin" ) func Bind(t *testing.T, iostreams genericclioptions.IOStreams, authURLCh chan<- string, invocations chan<- SubCommandInvocation, positionalArg string, flags ...string) { diff --git a/test/e2e/framework/browser.go b/test/e2e/framework/browser.go index 6a951daa..e2fd9faf 100644 --- a/test/e2e/framework/browser.go +++ b/test/e2e/framework/browser.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,7 +22,6 @@ import ( "github.com/headzoo/surf/browser" "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/util/wait" ) diff --git a/test/e2e/framework/clients.go b/test/e2e/framework/clients.go index 873de857..ba6076b4 100644 --- a/test/e2e/framework/clients.go +++ b/test/e2e/framework/clients.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,7 +20,6 @@ import ( "testing" "github.com/stretchr/testify/require" - apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" diff --git a/test/e2e/framework/env.go b/test/e2e/framework/env.go index 8881ac44..6f14aaee 100644 --- a/test/e2e/framework/env.go +++ b/test/e2e/framework/env.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -22,9 +22,7 @@ import ( "runtime" ) -var ( - WorkDir = os.Getenv("WORK_DIR") -) +var WorkDir = os.Getenv("WORK_DIR") func init() { if WorkDir == "" { diff --git a/test/e2e/framework/kcp.go b/test/e2e/framework/kcp.go index ac9e83d4..06d31bb4 100644 --- a/test/e2e/framework/kcp.go +++ b/test/e2e/framework/kcp.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -30,7 +30,6 @@ import ( tenancyv1alpha1 "github.com/kcp-dev/kcp/pkg/apis/tenancy/v1alpha1" "github.com/martinlindhe/base36" "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -46,9 +45,7 @@ type ( ClusterWorkspaceOption func(ws *tenancyv1alpha1.Workspace) ) -var ( - kcpScheme = runtime.NewScheme() -) +var kcpScheme = runtime.NewScheme() func init() { utilruntime.Must(tenancyv1alpha1.AddToScheme(kcpScheme)) diff --git a/test/e2e/framework/konnector.go b/test/e2e/framework/konnector.go index 902f98fa..f610a476 100644 --- a/test/e2e/framework/konnector.go +++ b/test/e2e/framework/konnector.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,17 +20,16 @@ import ( "context" "testing" + kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/apis/kubebind/v1alpha1" + // "go.bytebuilders.dev/kube-bind/deploy/crd" + "go.bytebuilders.dev/kube-bind/pkg/konnector" + "go.bytebuilders.dev/kube-bind/pkg/konnector/options" + "github.com/spf13/pflag" "github.com/stretchr/testify/require" - apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/rest" - - "go.bytebuilders.dev/kube-bind/deploy/crd" - kubebindv1alpha1 "go.bytebuilders.dev/kube-bind/pkg/apis/kubebind/v1alpha1" - "go.bytebuilders.dev/kube-bind/pkg/konnector" - "go.bytebuilders.dev/kube-bind/pkg/konnector/options" + "kmodules.xyz/client-go/apiextensions" ) func StartKonnector(t *testing.T, clientConfig *rest.Config, args ...string) *konnector.Server { @@ -39,10 +38,9 @@ func StartKonnector(t *testing.T, clientConfig *rest.Config, args ...string) *ko crdClient, err := apiextensionsclient.NewForConfig(clientConfig) require.NoError(t, err) - err = crd.Create(ctx, - crdClient.ApiextensionsV1().CustomResourceDefinitions(), - metav1.GroupResource{Group: kubebindv1alpha1.GroupName, Resource: "apiservicebindings"}, - ) + err = apiextensions.RegisterCRDs(crdClient, []*apiextensions.CustomResourceDefinition{ + kubebindv1alpha1.APIServiceBinding{}.CustomResourceDefinition(), + }) require.NoError(t, err) fs := pflag.NewFlagSet("konnector", pflag.ContinueOnError) diff --git a/test/e2e/framework/kubeconfig.go b/test/e2e/framework/kubeconfig.go index 33934ad3..1bdce776 100644 --- a/test/e2e/framework/kubeconfig.go +++ b/test/e2e/framework/kubeconfig.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,7 +21,6 @@ import ( "testing" "github.com/stretchr/testify/require" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" diff --git a/test/e2e/framework/logs.go b/test/e2e/framework/logs.go index 5e5bc1bf..74e93fd6 100644 --- a/test/e2e/framework/logs.go +++ b/test/e2e/framework/logs.go @@ -1,11 +1,11 @@ /* -Copyright 2022 The Kube Bind Authors. +Copyright AppsCode Inc. and Contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the AppsCode Community License 1.0.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 + https://github.com/appscode/licenses/raw/1.0.0/AppsCode-Community-1.0.0.md Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -20,7 +20,6 @@ import ( "os" "github.com/spf13/pflag" - "k8s.io/component-base/logs" logsv1 "k8s.io/component-base/logs/api/v1" ) diff --git a/vendor/github.com/gobuffalo/flect/.gitignore b/vendor/github.com/gobuffalo/flect/.gitignore deleted file mode 100644 index 36897185..00000000 --- a/vendor/github.com/gobuffalo/flect/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -*.log -.DS_Store -doc -tmp -pkg -*.gem -*.pid -coverage -coverage.data -build/* -*.pbxuser -*.mode1v3 -.svn -profile -.console_history -.sass-cache/* -.rake_tasks~ -*.log.lck -solr/ -.jhw-cache/ -jhw.* -*.sublime* -node_modules/ -dist/ -generated/ -.vendor/ -bin/* -gin-bin -.idea/ diff --git a/vendor/github.com/gobuffalo/flect/.gometalinter.json b/vendor/github.com/gobuffalo/flect/.gometalinter.json deleted file mode 100644 index e4f65a36..00000000 --- a/vendor/github.com/gobuffalo/flect/.gometalinter.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Enable": ["vet", "golint", "goimports", "deadcode", "gotype", "ineffassign", "misspell", "nakedret", "unconvert", "megacheck", "varcheck"] -} diff --git a/vendor/github.com/gobuffalo/flect/LICENSE b/vendor/github.com/gobuffalo/flect/LICENSE deleted file mode 100644 index 649efd43..00000000 --- a/vendor/github.com/gobuffalo/flect/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2019 Mark Bates - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/gobuffalo/flect/Makefile b/vendor/github.com/gobuffalo/flect/Makefile deleted file mode 100644 index 0ac539f1..00000000 --- a/vendor/github.com/gobuffalo/flect/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -TAGS ?= "" -GO_BIN ?= "go" - -install: - $(GO_BIN) install -tags ${TAGS} -v . - make tidy - -tidy: -ifeq ($(GO111MODULE),on) - $(GO_BIN) mod tidy -else - echo skipping go mod tidy -endif - -deps: - $(GO_BIN) get -tags ${TAGS} -t ./... - make tidy - -build: - $(GO_BIN) build -v . - make tidy - -test: - $(GO_BIN) test -cover -tags ${TAGS} ./... - make tidy - -ci-deps: - $(GO_BIN) get -tags ${TAGS} -t ./... - -ci-test: - $(GO_BIN) test -tags ${TAGS} -race ./... - -lint: - go get github.com/golangci/golangci-lint/cmd/golangci-lint - golangci-lint run --enable-all - make tidy - -update: -ifeq ($(GO111MODULE),on) - rm go.* - $(GO_BIN) mod init - $(GO_BIN) mod tidy -else - $(GO_BIN) get -u -tags ${TAGS} -endif - make test - make install - make tidy - -release-test: - $(GO_BIN) test -tags ${TAGS} -race ./... - make tidy - -release: - $(GO_BIN) get github.com/gobuffalo/release - make tidy - release -y -f version.go --skip-packr - make tidy - - - diff --git a/vendor/github.com/gobuffalo/flect/README.md b/vendor/github.com/gobuffalo/flect/README.md deleted file mode 100644 index 2d9a1bd3..00000000 --- a/vendor/github.com/gobuffalo/flect/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Flect - -

-GoDoc -CI -Go Report Card -

- -This is a new inflection engine to replace [https://github.com/markbates/inflect](https://github.com/markbates/inflect) designed to be more modular, more readable, and easier to fix issues on than the original. - -## Installation - -```bash -$ go get -u -v github.com/gobuffalo/flect -``` - -## `github.com/gobuffalo/flect` -GoDoc - -The `github.com/gobuffalo/flect` package contains "basic" inflection tools, like pluralization, singularization, etc... - -### The `Ident` Type - -In addition to helpful methods that take in a `string` and return a `string`, there is an `Ident` type that can be used to create new, custom, inflection rules. - -The `Ident` type contains two fields. - -* `Original` - This is the original `string` that was used to create the `Ident` -* `Parts` - This is a `[]string` that represents all of the "parts" of the string, that have been split apart, making the segments easier to work with - -Examples of creating new inflection rules using `Ident` can be found in the `github.com/gobuffalo/flect/name` package. - -## `github.com/gobuffalo/flect/name` -GoDoc - -The `github.com/gobuffalo/flect/name` package contains more "business" inflection rules like creating proper names, table names, etc... diff --git a/vendor/github.com/gobuffalo/flect/SHOULDERS.md b/vendor/github.com/gobuffalo/flect/SHOULDERS.md deleted file mode 100644 index 8c359f15..00000000 --- a/vendor/github.com/gobuffalo/flect/SHOULDERS.md +++ /dev/null @@ -1,10 +0,0 @@ -# github.com/gobuffalo/flect Stands on the Shoulders of Giants - -github.com/gobuffalo/flect does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work. - -Thank you to the following **GIANTS**: - - -* [github.com/davecgh/go-spew](https://godoc.org/github.com/davecgh/go-spew) - -* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify) diff --git a/vendor/github.com/gobuffalo/flect/acronyms.go b/vendor/github.com/gobuffalo/flect/acronyms.go deleted file mode 100644 index b169724a..00000000 --- a/vendor/github.com/gobuffalo/flect/acronyms.go +++ /dev/null @@ -1,152 +0,0 @@ -package flect - -import "sync" - -var acronymsMoot = &sync.RWMutex{} - -var baseAcronyms = map[string]bool{ - "OK": true, - "UTF8": true, - "HTML": true, - "JSON": true, - "JWT": true, - "ID": true, - "UUID": true, - "SQL": true, - "ACK": true, - "ACL": true, - "ADSL": true, - "AES": true, - "ANSI": true, - "API": true, - "ARP": true, - "ATM": true, - "BGP": true, - "BSS": true, - "CCITT": true, - "CHAP": true, - "CIDR": true, - "CIR": true, - "CLI": true, - "CPE": true, - "CPU": true, - "CRC": true, - "CRT": true, - "CSMA": true, - "CMOS": true, - "DCE": true, - "DEC": true, - "DES": true, - "DHCP": true, - "DNS": true, - "DRAM": true, - "DSL": true, - "DSLAM": true, - "DTE": true, - "DMI": true, - "EHA": true, - "EIA": true, - "EIGRP": true, - "EOF": true, - "ESS": true, - "FCC": true, - "FCS": true, - "FDDI": true, - "FTP": true, - "GBIC": true, - "gbps": true, - "GEPOF": true, - "HDLC": true, - "HTTP": true, - "HTTPS": true, - "IANA": true, - "ICMP": true, - "IDF": true, - "IDS": true, - "IEEE": true, - "IETF": true, - "IMAP": true, - "IP": true, - "IPS": true, - "ISDN": true, - "ISP": true, - "kbps": true, - "LACP": true, - "LAN": true, - "LAPB": true, - "LAPF": true, - "LLC": true, - "MAC": true, - "Mbps": true, - "MC": true, - "MDF": true, - "MIB": true, - "MoCA": true, - "MPLS": true, - "MTU": true, - "NAC": true, - "NAT": true, - "NBMA": true, - "NIC": true, - "NRZ": true, - "NRZI": true, - "NVRAM": true, - "OSI": true, - "OSPF": true, - "OUI": true, - "PAP": true, - "PAT": true, - "PC": true, - "PIM": true, - "PCM": true, - "PDU": true, - "POP3": true, - "POTS": true, - "PPP": true, - "PPTP": true, - "PTT": true, - "PVST": true, - "RAM": true, - "RARP": true, - "RFC": true, - "RIP": true, - "RLL": true, - "ROM": true, - "RSTP": true, - "RTP": true, - "RCP": true, - "SDLC": true, - "SFD": true, - "SFP": true, - "SLARP": true, - "SLIP": true, - "SMTP": true, - "SNA": true, - "SNAP": true, - "SNMP": true, - "SOF": true, - "SRAM": true, - "SSH": true, - "SSID": true, - "STP": true, - "SYN": true, - "TDM": true, - "TFTP": true, - "TIA": true, - "TOFU": true, - "UDP": true, - "URL": true, - "URI": true, - "USB": true, - "UTP": true, - "VC": true, - "VLAN": true, - "VLSM": true, - "VPN": true, - "W3C": true, - "WAN": true, - "WEP": true, - "WiFi": true, - "WPA": true, - "WWW": true, -} diff --git a/vendor/github.com/gobuffalo/flect/camelize.go b/vendor/github.com/gobuffalo/flect/camelize.go deleted file mode 100644 index d8851c8f..00000000 --- a/vendor/github.com/gobuffalo/flect/camelize.go +++ /dev/null @@ -1,44 +0,0 @@ -package flect - -import ( - "strings" - "unicode" -) - -// Camelize returns a camelize version of a string -// bob dylan = bobDylan -// widget_id = widgetID -// WidgetID = widgetID -func Camelize(s string) string { - return New(s).Camelize().String() -} - -// Camelize returns a camelize version of a string -// bob dylan = bobDylan -// widget_id = widgetID -// WidgetID = widgetID -func (i Ident) Camelize() Ident { - var out []string - for i, part := range i.Parts { - var x string - var capped bool - for _, c := range part { - if unicode.IsLetter(c) || unicode.IsDigit(c) { - if i == 0 { - x += string(unicode.ToLower(c)) - continue - } - if !capped { - capped = true - x += string(unicode.ToUpper(c)) - continue - } - x += string(c) - } - } - if x != "" { - out = append(out, x) - } - } - return New(strings.Join(out, "")) -} diff --git a/vendor/github.com/gobuffalo/flect/capitalize.go b/vendor/github.com/gobuffalo/flect/capitalize.go deleted file mode 100644 index 78334fc0..00000000 --- a/vendor/github.com/gobuffalo/flect/capitalize.go +++ /dev/null @@ -1,24 +0,0 @@ -package flect - -import "unicode" - -// Capitalize will cap the first letter of string -// user = User -// bob dylan = Bob dylan -// widget_id = Widget_id -func Capitalize(s string) string { - return New(s).Capitalize().String() -} - -// Capitalize will cap the first letter of string -// user = User -// bob dylan = Bob dylan -// widget_id = Widget_id -func (i Ident) Capitalize() Ident { - if len(i.Parts) == 0 { - return New("") - } - runes := []rune(i.Original) - runes[0] = unicode.ToTitle(runes[0]) - return New(string(runes)) -} diff --git a/vendor/github.com/gobuffalo/flect/custom_data.go b/vendor/github.com/gobuffalo/flect/custom_data.go deleted file mode 100644 index 9a2dfc74..00000000 --- a/vendor/github.com/gobuffalo/flect/custom_data.go +++ /dev/null @@ -1,83 +0,0 @@ -package flect - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" -) - -func init() { - loadCustomData("inflections.json", "INFLECT_PATH", "could not read inflection file", LoadInflections) - loadCustomData("acronyms.json", "ACRONYMS_PATH", "could not read acronyms file", LoadAcronyms) -} - -//CustomDataParser are functions that parse data like acronyms or -//plurals in the shape of a io.Reader it receives. -type CustomDataParser func(io.Reader) error - -func loadCustomData(defaultFile, env, readErrorMessage string, parser CustomDataParser) { - pwd, _ := os.Getwd() - path, found := os.LookupEnv(env) - if !found { - path = filepath.Join(pwd, defaultFile) - } - - if _, err := os.Stat(path); err != nil { - return - } - - b, err := ioutil.ReadFile(path) - if err != nil { - fmt.Printf("%s %s (%s)\n", readErrorMessage, path, err) - return - } - - if err = parser(bytes.NewReader(b)); err != nil { - fmt.Println(err) - } -} - -//LoadAcronyms loads rules from io.Reader param -func LoadAcronyms(r io.Reader) error { - m := []string{} - err := json.NewDecoder(r).Decode(&m) - - if err != nil { - return fmt.Errorf("could not decode acronyms JSON from reader: %s", err) - } - - acronymsMoot.Lock() - defer acronymsMoot.Unlock() - - for _, acronym := range m { - baseAcronyms[acronym] = true - } - - return nil -} - -//LoadInflections loads rules from io.Reader param -func LoadInflections(r io.Reader) error { - m := map[string]string{} - - err := json.NewDecoder(r).Decode(&m) - if err != nil { - return fmt.Errorf("could not decode inflection JSON from reader: %s", err) - } - - pluralMoot.Lock() - defer pluralMoot.Unlock() - singularMoot.Lock() - defer singularMoot.Unlock() - - for s, p := range m { - singleToPlural[s] = p - pluralToSingle[p] = s - } - - return nil -} diff --git a/vendor/github.com/gobuffalo/flect/dasherize.go b/vendor/github.com/gobuffalo/flect/dasherize.go deleted file mode 100644 index c7a8a33e..00000000 --- a/vendor/github.com/gobuffalo/flect/dasherize.go +++ /dev/null @@ -1,34 +0,0 @@ -package flect - -import ( - "strings" - "unicode" -) - -// Dasherize returns an alphanumeric, lowercased, dashed string -// Donald E. Knuth = donald-e-knuth -// Test with + sign = test-with-sign -// admin/WidgetID = admin-widget-id -func Dasherize(s string) string { - return New(s).Dasherize().String() -} - -// Dasherize returns an alphanumeric, lowercased, dashed string -// Donald E. Knuth = donald-e-knuth -// Test with + sign = test-with-sign -// admin/WidgetID = admin-widget-id -func (i Ident) Dasherize() Ident { - var parts []string - - for _, part := range i.Parts { - var x string - for _, c := range part { - if unicode.IsLetter(c) || unicode.IsDigit(c) { - x += string(c) - } - } - parts = xappend(parts, x) - } - - return New(strings.ToLower(strings.Join(parts, "-"))) -} diff --git a/vendor/github.com/gobuffalo/flect/flect.go b/vendor/github.com/gobuffalo/flect/flect.go deleted file mode 100644 index ee81b6f2..00000000 --- a/vendor/github.com/gobuffalo/flect/flect.go +++ /dev/null @@ -1,43 +0,0 @@ -/* -Package flect is a new inflection engine to replace [https://github.com/markbates/inflect](https://github.com/markbates/inflect) designed to be more modular, more readable, and easier to fix issues on than the original. -*/ -package flect - -import ( - "strings" - "unicode" -) - -var spaces = []rune{'_', ' ', ':', '-', '/'} - -func isSpace(c rune) bool { - for _, r := range spaces { - if r == c { - return true - } - } - return unicode.IsSpace(c) -} - -func xappend(a []string, ss ...string) []string { - for _, s := range ss { - s = strings.TrimSpace(s) - for _, x := range spaces { - s = strings.Trim(s, string(x)) - } - if _, ok := baseAcronyms[strings.ToUpper(s)]; ok { - s = strings.ToUpper(s) - } - if s != "" { - a = append(a, s) - } - } - return a -} - -func abs(x int) int { - if x < 0 { - return -x - } - return x -} diff --git a/vendor/github.com/gobuffalo/flect/humanize.go b/vendor/github.com/gobuffalo/flect/humanize.go deleted file mode 100644 index 6a0b75af..00000000 --- a/vendor/github.com/gobuffalo/flect/humanize.go +++ /dev/null @@ -1,35 +0,0 @@ -package flect - -import ( - "strings" -) - -// Humanize returns first letter of sentence capitalized. -// Common acronyms are capitalized as well. -// Other capital letters in string are left as provided. -// employee_salary = Employee salary -// employee_id = employee ID -// employee_mobile_number = Employee mobile number -// first_Name = First Name -// firstName = First Name -func Humanize(s string) string { - return New(s).Humanize().String() -} - -// Humanize First letter of sentence capitalized -func (i Ident) Humanize() Ident { - if len(i.Original) == 0 { - return New("") - } - - var parts []string - for index, part := range i.Parts { - if index == 0 { - part = strings.Title(i.Parts[0]) - } - - parts = xappend(parts, part) - } - - return New(strings.Join(parts, " ")) -} diff --git a/vendor/github.com/gobuffalo/flect/ident.go b/vendor/github.com/gobuffalo/flect/ident.go deleted file mode 100644 index 9189e9a3..00000000 --- a/vendor/github.com/gobuffalo/flect/ident.go +++ /dev/null @@ -1,122 +0,0 @@ -package flect - -import ( - "encoding" - "strings" - "unicode" - "unicode/utf8" -) - -// Ident represents the string and it's parts -type Ident struct { - Original string - Parts []string -} - -// String implements fmt.Stringer and returns the original string -func (i Ident) String() string { - return i.Original -} - -// New creates a new Ident from the string -func New(s string) Ident { - i := Ident{ - Original: s, - Parts: toParts(s), - } - - return i -} - -func toParts(s string) []string { - parts := []string{} - s = strings.TrimSpace(s) - if len(s) == 0 { - return parts - } - if _, ok := baseAcronyms[strings.ToUpper(s)]; ok { - return []string{strings.ToUpper(s)} - } - var prev rune - var x strings.Builder - x.Grow(len(s)) - for _, c := range s { - // fmt.Println("### cs ->", cs) - // fmt.Println("### unicode.IsControl(c) ->", unicode.IsControl(c)) - // fmt.Println("### unicode.IsDigit(c) ->", unicode.IsDigit(c)) - // fmt.Println("### unicode.IsGraphic(c) ->", unicode.IsGraphic(c)) - // fmt.Println("### unicode.IsLetter(c) ->", unicode.IsLetter(c)) - // fmt.Println("### unicode.IsLower(c) ->", unicode.IsLower(c)) - // fmt.Println("### unicode.IsMark(c) ->", unicode.IsMark(c)) - // fmt.Println("### unicode.IsPrint(c) ->", unicode.IsPrint(c)) - // fmt.Println("### unicode.IsPunct(c) ->", unicode.IsPunct(c)) - // fmt.Println("### unicode.IsSpace(c) ->", unicode.IsSpace(c)) - // fmt.Println("### unicode.IsTitle(c) ->", unicode.IsTitle(c)) - // fmt.Println("### unicode.IsUpper(c) ->", unicode.IsUpper(c)) - if !utf8.ValidRune(c) { - continue - } - - if isSpace(c) { - parts = xappend(parts, x.String()) - x.Reset() - x.WriteRune(c) - prev = c - continue - } - - if unicode.IsUpper(c) && !unicode.IsUpper(prev) { - parts = xappend(parts, x.String()) - x.Reset() - x.WriteRune(c) - prev = c - continue - } - if unicode.IsUpper(c) && baseAcronyms[strings.ToUpper(x.String())] { - parts = xappend(parts, x.String()) - x.Reset() - x.WriteRune(c) - prev = c - continue - } - if unicode.IsLetter(c) || unicode.IsDigit(c) || unicode.IsPunct(c) || c == '`' { - prev = c - x.WriteRune(c) - continue - } - - parts = xappend(parts, x.String()) - x.Reset() - prev = c - } - parts = xappend(parts, x.String()) - - return parts -} - -var _ encoding.TextUnmarshaler = &Ident{} -var _ encoding.TextMarshaler = &Ident{} - -// LastPart returns the last part/word of the original string -func (i *Ident) LastPart() string { - if len(i.Parts) == 0 { - return "" - } - return i.Parts[len(i.Parts)-1] -} - -// ReplaceSuffix creates a new Ident with the original suffix replaced by new -func (i Ident) ReplaceSuffix(orig, new string) Ident { - return New(strings.TrimSuffix(i.Original, orig) + new) -} - -//UnmarshalText unmarshalls byte array into the Ident -func (i *Ident) UnmarshalText(data []byte) error { - (*i) = New(string(data)) - return nil -} - -//MarshalText marshals Ident into byte array -func (i Ident) MarshalText() ([]byte, error) { - return []byte(i.Original), nil -} diff --git a/vendor/github.com/gobuffalo/flect/lower_upper.go b/vendor/github.com/gobuffalo/flect/lower_upper.go deleted file mode 100644 index 930da58d..00000000 --- a/vendor/github.com/gobuffalo/flect/lower_upper.go +++ /dev/null @@ -1,13 +0,0 @@ -package flect - -import "strings" - -// ToUpper is a convience wrapper for strings.ToUpper -func (i Ident) ToUpper() Ident { - return New(strings.ToUpper(i.Original)) -} - -// ToLower is a convience wrapper for strings.ToLower -func (i Ident) ToLower() Ident { - return New(strings.ToLower(i.Original)) -} diff --git a/vendor/github.com/gobuffalo/flect/ordinalize.go b/vendor/github.com/gobuffalo/flect/ordinalize.go deleted file mode 100644 index 1ce27b3a..00000000 --- a/vendor/github.com/gobuffalo/flect/ordinalize.go +++ /dev/null @@ -1,43 +0,0 @@ -package flect - -import ( - "fmt" - "strconv" -) - -// Ordinalize converts a number to an ordinal version -// 42 = 42nd -// 45 = 45th -// 1 = 1st -func Ordinalize(s string) string { - return New(s).Ordinalize().String() -} - -// Ordinalize converts a number to an ordinal version -// 42 = 42nd -// 45 = 45th -// 1 = 1st -func (i Ident) Ordinalize() Ident { - number, err := strconv.Atoi(i.Original) - if err != nil { - return i - } - var s string - switch abs(number) % 100 { - case 11, 12, 13: - s = fmt.Sprintf("%dth", number) - default: - switch abs(number) % 10 { - case 1: - s = fmt.Sprintf("%dst", number) - case 2: - s = fmt.Sprintf("%dnd", number) - case 3: - s = fmt.Sprintf("%drd", number) - } - } - if s != "" { - return New(s) - } - return New(fmt.Sprintf("%dth", number)) -} diff --git a/vendor/github.com/gobuffalo/flect/pascalize.go b/vendor/github.com/gobuffalo/flect/pascalize.go deleted file mode 100644 index 6396d0d4..00000000 --- a/vendor/github.com/gobuffalo/flect/pascalize.go +++ /dev/null @@ -1,32 +0,0 @@ -package flect - -import ( - "strings" -) - -// Pascalize returns a string with each segment capitalized -// user = User -// bob dylan = BobDylan -// widget_id = WidgetID -func Pascalize(s string) string { - return New(s).Pascalize().String() -} - -// Pascalize returns a string with each segment capitalized -// user = User -// bob dylan = BobDylan -// widget_id = WidgetID -func (i Ident) Pascalize() Ident { - c := i.Camelize() - if len(c.String()) == 0 { - return c - } - if len(i.Parts) == 0 { - return i - } - capLen := 1 - if _, ok := baseAcronyms[strings.ToUpper(i.Parts[0])]; ok { - capLen = len(i.Parts[0]) - } - return New(string(strings.ToUpper(c.Original[0:capLen])) + c.Original[capLen:]) -} diff --git a/vendor/github.com/gobuffalo/flect/plural_rules.go b/vendor/github.com/gobuffalo/flect/plural_rules.go deleted file mode 100644 index 61d34d39..00000000 --- a/vendor/github.com/gobuffalo/flect/plural_rules.go +++ /dev/null @@ -1,287 +0,0 @@ -package flect - -var pluralRules = []rule{} - -// AddPlural adds a rule that will replace the given suffix with the replacement suffix. -func AddPlural(suffix string, repl string) { - pluralMoot.Lock() - defer pluralMoot.Unlock() - pluralRules = append([]rule{{ - suffix: suffix, - fn: func(s string) string { - s = s[:len(s)-len(suffix)] - return s + repl - }, - }}, pluralRules...) - - pluralRules = append([]rule{{ - suffix: repl, - fn: noop, - }}, pluralRules...) -} - -var singleToPlural = map[string]string{ - "aircraft": "aircraft", - "alias": "aliases", - "alumna": "alumnae", - "alumnus": "alumni", - "analysis": "analyses", - "antenna": "antennas", - "antithesis": "antitheses", - "apex": "apexes", - "appendix": "appendices", - "axis": "axes", - "bacillus": "bacilli", - "bacterium": "bacteria", - "basis": "bases", - "beau": "beaus", - "bison": "bison", - "bureau": "bureaus", - "bus": "buses", - "campus": "campuses", - "caucus": "caucuses", - "child": "children", - "château": "châteaux", - "circus": "circuses", - "codex": "codices", - "concerto": "concertos", - "corpus": "corpora", - "crisis": "crises", - "curriculum": "curriculums", - "datum": "data", - "deer": "deer", - "diagnosis": "diagnoses", - "die": "dice", - "dwarf": "dwarves", - "ellipsis": "ellipses", - "equipment": "equipment", - "erratum": "errata", - "faux pas": "faux pas", - "fez": "fezzes", - "fish": "fish", - "focus": "foci", - "foo": "foos", - "foot": "feet", - "formula": "formulas", - "fungus": "fungi", - "genus": "genera", - "goose": "geese", - "graffito": "graffiti", - "grouse": "grouse", - "half": "halves", - "halo": "halos", - "hoof": "hooves", - "human": "humans", - "hypothesis": "hypotheses", - "index": "indices", - "information": "information", - "jeans": "jeans", - "larva": "larvae", - "libretto": "librettos", - "loaf": "loaves", - "locus": "loci", - "louse": "lice", - "matrix": "matrices", - "minutia": "minutiae", - "money": "money", - "moose": "moose", - "mouse": "mice", - "nebula": "nebulae", - "news": "news", - "nucleus": "nuclei", - "oasis": "oases", - "octopus": "octopi", - "offspring": "offspring", - "opus": "opera", - "ovum": "ova", - "ox": "oxen", - "parenthesis": "parentheses", - "phenomenon": "phenomena", - "photo": "photos", - "phylum": "phyla", - "piano": "pianos", - "plus": "pluses", - "police": "police", - "prognosis": "prognoses", - "prometheus": "prometheuses", - "quiz": "quizzes", - "quota": "quotas", - "radius": "radiuses", - "referendum": "referendums", - "ress": "resses", - "rice": "rice", - "salmon": "salmon", - "sex": "sexes", - "series": "series", - "sheep": "sheep", - "shoe": "shoes", - "shrimp": "shrimp", - "species": "species", - "stimulus": "stimuli", - "stratum": "strata", - "swine": "swine", - "syllabus": "syllabi", - "symposium": "symposiums", - "synapse": "synapses", - "synopsis": "synopses", - "tableau": "tableaus", - "testis": "testes", - "thesis": "theses", - "thief": "thieves", - "tooth": "teeth", - "trout": "trout", - "tuna": "tuna", - "vedalia": "vedalias", - "vertebra": "vertebrae", - "vertix": "vertices", - "vita": "vitae", - "vortex": "vortices", - "wharf": "wharves", - "wife": "wives", - "woman": "women", - "wolf": "wolves", - "you": "you", -} - -var pluralToSingle = map[string]string{} - -func init() { - for k, v := range singleToPlural { - pluralToSingle[v] = k - } -} - -type singularToPluralSuffix struct { - singular string - plural string -} - -var singularToPluralSuffixList = []singularToPluralSuffix{ - {"iterion", "iteria"}, - {"campus", "campuses"}, - {"genera", "genus"}, - {"person", "people"}, - {"phylum", "phyla"}, - {"randum", "randa"}, - {"actus", "acti"}, - {"adium", "adia"}, - {"basis", "basis"}, - {"child", "children"}, - {"chive", "chives"}, - {"focus", "foci"}, - {"hello", "hellos"}, - {"jeans", "jeans"}, - {"louse", "lice"}, - {"media", "media"}, - {"mouse", "mice"}, - {"movie", "movies"}, - {"oasis", "oasis"}, - {"atum", "ata"}, - {"atus", "atuses"}, - {"base", "bases"}, - {"cess", "cesses"}, - {"dium", "diums"}, - {"eses", "esis"}, - {"half", "halves"}, - {"hive", "hives"}, - {"iano", "ianos"}, - {"irus", "iri"}, - {"isis", "ises"}, - {"leus", "li"}, - {"mnus", "mni"}, - {"move", "moves"}, - {"news", "news"}, - {"odex", "odice"}, - {"oose", "eese"}, - {"ouse", "ouses"}, - {"ovum", "ova"}, - {"rion", "ria"}, - {"shoe", "shoes"}, - {"stis", "stes"}, - {"tive", "tives"}, - {"vice", "vices"}, - {"wife", "wives"}, - {"afe", "aves"}, - {"bfe", "bves"}, - {"box", "boxes"}, - {"cfe", "cves"}, - {"dfe", "dves"}, - {"dge", "dges"}, - {"efe", "eves"}, - {"gfe", "gves"}, - {"hfe", "hves"}, - {"ife", "ives"}, - {"itz", "itzes"}, - {"ium", "ia"}, - {"ize", "izes"}, - {"jfe", "jves"}, - {"kfe", "kves"}, - {"man", "men"}, - {"mfe", "mves"}, - {"nfe", "nves"}, - {"nna", "nnas"}, - {"oaf", "oaves"}, - {"oci", "ocus"}, - {"ode", "odes"}, - {"ofe", "oves"}, - {"pfe", "pves"}, - {"pse", "psis"}, - {"qfe", "qves"}, - {"quy", "quies"}, - {"rfe", "rves"}, - {"sfe", "sves"}, - {"tfe", "tves"}, - {"tum", "ta"}, - {"tus", "tuses"}, - {"ufe", "uves"}, - {"ula", "ulae"}, - {"ula", "ulas"}, - {"uli", "ulus"}, - {"use", "uses"}, - {"uss", "usses"}, - {"vfe", "vves"}, - {"wfe", "wves"}, - {"xfe", "xves"}, - {"yfe", "yves"}, - {"you", "you"}, - {"zfe", "zves"}, - {"by", "bies"}, - {"ch", "ches"}, - {"cy", "cies"}, - {"dy", "dies"}, - {"ex", "ices"}, - {"fy", "fies"}, - {"gy", "gies"}, - {"hy", "hies"}, - {"io", "ios"}, - {"jy", "jies"}, - {"ky", "kies"}, - {"lf", "lves"}, - {"ly", "lies"}, - {"my", "mies"}, - {"ny", "nies"}, - {"py", "pies"}, - {"qy", "qies"}, - {"rf", "rves"}, - {"ry", "ries"}, - {"sh", "shes"}, - {"ss", "sses"}, - {"sy", "sies"}, - {"ty", "ties"}, - {"tz", "tzes"}, - {"va", "vae"}, - {"vy", "vies"}, - {"wy", "wies"}, - {"xy", "xies"}, - {"zy", "zies"}, - {"zz", "zzes"}, - {"o", "oes"}, - {"x", "xes"}, -} - -func init() { - for i := len(singularToPluralSuffixList) - 1; i >= 0; i-- { - AddPlural(singularToPluralSuffixList[i].singular, singularToPluralSuffixList[i].plural) - AddSingular(singularToPluralSuffixList[i].plural, singularToPluralSuffixList[i].singular) - } -} diff --git a/vendor/github.com/gobuffalo/flect/pluralize.go b/vendor/github.com/gobuffalo/flect/pluralize.go deleted file mode 100644 index e265f84e..00000000 --- a/vendor/github.com/gobuffalo/flect/pluralize.go +++ /dev/null @@ -1,59 +0,0 @@ -package flect - -import ( - "strings" - "sync" -) - -var pluralMoot = &sync.RWMutex{} - -// Pluralize returns a plural version of the string -// user = users -// person = people -// datum = data -func Pluralize(s string) string { - return New(s).Pluralize().String() -} - -// PluralizeWithSize will pluralize a string taking a number number into account. -// PluralizeWithSize("user", 1) = user -// PluralizeWithSize("user", 2) = users -func PluralizeWithSize(s string, i int) string { - if i == 1 || i == -1 { - return New(s).Singularize().String() - } - return New(s).Pluralize().String() -} - -// Pluralize returns a plural version of the string -// user = users -// person = people -// datum = data -func (i Ident) Pluralize() Ident { - s := i.LastPart() - if len(s) == 0 { - return New("") - } - - pluralMoot.RLock() - defer pluralMoot.RUnlock() - - ls := strings.ToLower(s) - if _, ok := pluralToSingle[ls]; ok { - return i - } - if p, ok := singleToPlural[ls]; ok { - return i.ReplaceSuffix(s, p) - } - for _, r := range pluralRules { - if strings.HasSuffix(ls, r.suffix) { - return i.ReplaceSuffix(s, r.fn(s)) - } - } - - if strings.HasSuffix(ls, "s") { - return i - } - - return New(i.String() + "s") -} diff --git a/vendor/github.com/gobuffalo/flect/rule.go b/vendor/github.com/gobuffalo/flect/rule.go deleted file mode 100644 index dc616b33..00000000 --- a/vendor/github.com/gobuffalo/flect/rule.go +++ /dev/null @@ -1,10 +0,0 @@ -package flect - -type ruleFn func(string) string - -type rule struct { - suffix string - fn ruleFn -} - -func noop(s string) string { return s } diff --git a/vendor/github.com/gobuffalo/flect/singular_rules.go b/vendor/github.com/gobuffalo/flect/singular_rules.go deleted file mode 100644 index 9b85a873..00000000 --- a/vendor/github.com/gobuffalo/flect/singular_rules.go +++ /dev/null @@ -1,23 +0,0 @@ -package flect - -var singularRules = []rule{} - -// AddSingular adds a rule that will replace the given suffix with the replacement suffix. -func AddSingular(ext string, repl string) { - singularMoot.Lock() - defer singularMoot.Unlock() - singularRules = append([]rule{{ - suffix: ext, - fn: func(s string) string { - s = s[:len(s)-len(ext)] - return s + repl - }, - }}, singularRules...) - - singularRules = append([]rule{{ - suffix: repl, - fn: func(s string) string { - return s - }, - }}, singularRules...) -} diff --git a/vendor/github.com/gobuffalo/flect/singularize.go b/vendor/github.com/gobuffalo/flect/singularize.go deleted file mode 100644 index 1ed49950..00000000 --- a/vendor/github.com/gobuffalo/flect/singularize.go +++ /dev/null @@ -1,57 +0,0 @@ -package flect - -import ( - "strings" - "sync" -) - -var singularMoot = &sync.RWMutex{} - -// Singularize returns a singular version of the string -// users = user -// data = datum -// people = person -func Singularize(s string) string { - return New(s).Singularize().String() -} - -// SingularizeWithSize will singular a string taking a number number into account. -// SingularizeWithSize("user", 1) = user -// SingularizeWithSize("user", 2) = users -func SingularizeWithSize(s string, i int) string { - if i == 1 || i == -1 { - return New(s).Singularize().String() - } - return New(s).Pluralize().String() -} - -// Singularize returns a singular version of the string -// users = user -// data = datum -// people = person -func (i Ident) Singularize() Ident { - s := i.Original - if len(s) == 0 { - return i - } - - singularMoot.RLock() - defer singularMoot.RUnlock() - ls := strings.ToLower(s) - if p, ok := pluralToSingle[ls]; ok { - return New(p) - } - if _, ok := singleToPlural[ls]; ok { - return i - } - for _, r := range singularRules { - if strings.HasSuffix(ls, r.suffix) { - return New(r.fn(s)) - } - } - - if strings.HasSuffix(s, "s") { - return New(s[:len(s)-1]) - } - return i -} diff --git a/vendor/github.com/gobuffalo/flect/titleize.go b/vendor/github.com/gobuffalo/flect/titleize.go deleted file mode 100644 index cbbf08a5..00000000 --- a/vendor/github.com/gobuffalo/flect/titleize.go +++ /dev/null @@ -1,30 +0,0 @@ -package flect - -import ( - "strings" - "unicode" -) - -// Titleize will capitalize the start of each part -// "Nice to see you!" = "Nice To See You!" -// "i've read a book! have you?" = "I've Read A Book! Have You?" -// "This is `code` ok" = "This Is `code` OK" -func Titleize(s string) string { - return New(s).Titleize().String() -} - -// Titleize will capitalize the start of each part -// "Nice to see you!" = "Nice To See You!" -// "i've read a book! have you?" = "I've Read A Book! Have You?" -// "This is `code` ok" = "This Is `code` OK" -func (i Ident) Titleize() Ident { - var parts []string - for _, part := range i.Parts { - x := string(unicode.ToTitle(rune(part[0]))) - if len(part) > 1 { - x += part[1:] - } - parts = append(parts, x) - } - return New(strings.Join(parts, " ")) -} diff --git a/vendor/github.com/gobuffalo/flect/underscore.go b/vendor/github.com/gobuffalo/flect/underscore.go deleted file mode 100644 index e1466d99..00000000 --- a/vendor/github.com/gobuffalo/flect/underscore.go +++ /dev/null @@ -1,35 +0,0 @@ -package flect - -import ( - "strings" - "unicode" -) - -// Underscore a string -// bob dylan = bob_dylan -// Nice to see you! = nice_to_see_you -// widgetID = widget_id -func Underscore(s string) string { - return New(s).Underscore().String() -} - -// Underscore a string -// bob dylan = bob_dylan -// Nice to see you! = nice_to_see_you -// widgetID = widget_id -func (i Ident) Underscore() Ident { - out := make([]string, 0, len(i.Parts)) - for _, part := range i.Parts { - var x strings.Builder - x.Grow(len(part)) - for _, c := range part { - if unicode.IsLetter(c) || unicode.IsDigit(c) { - x.WriteRune(c) - } - } - if x.Len() > 0 { - out = append(out, x.String()) - } - } - return New(strings.ToLower(strings.Join(out, "_"))) -} diff --git a/vendor/github.com/gobuffalo/flect/version.go b/vendor/github.com/gobuffalo/flect/version.go deleted file mode 100644 index 9624d5df..00000000 --- a/vendor/github.com/gobuffalo/flect/version.go +++ /dev/null @@ -1,4 +0,0 @@ -package flect - -//Version holds Flect version number -const Version = "v0.1.6" diff --git a/vendor/github.com/gorilla/mux/.editorconfig b/vendor/github.com/gorilla/mux/.editorconfig new file mode 100644 index 00000000..c6b74c3e --- /dev/null +++ b/vendor/github.com/gorilla/mux/.editorconfig @@ -0,0 +1,20 @@ +; https://editorconfig.org/ + +root = true + +[*] +insert_final_newline = true +charset = utf-8 +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +[{Makefile,go.mod,go.sum,*.go,.gitmodules}] +indent_style = tab +indent_size = 4 + +[*.md] +indent_size = 4 +trim_trailing_whitespace = false + +eclint_indent_style = unset \ No newline at end of file diff --git a/vendor/github.com/gorilla/mux/.gitignore b/vendor/github.com/gorilla/mux/.gitignore new file mode 100644 index 00000000..84039fec --- /dev/null +++ b/vendor/github.com/gorilla/mux/.gitignore @@ -0,0 +1 @@ +coverage.coverprofile diff --git a/vendor/github.com/gorilla/mux/AUTHORS b/vendor/github.com/gorilla/mux/AUTHORS deleted file mode 100644 index b722392e..00000000 --- a/vendor/github.com/gorilla/mux/AUTHORS +++ /dev/null @@ -1,8 +0,0 @@ -# This is the official list of gorilla/mux authors for copyright purposes. -# -# Please keep the list sorted. - -Google LLC (https://opensource.google.com/) -Kamil Kisielk -Matt Silverlock -Rodrigo Moraes (https://github.com/moraes) diff --git a/vendor/github.com/gorilla/mux/LICENSE b/vendor/github.com/gorilla/mux/LICENSE index 6903df63..bb9d80bc 100644 --- a/vendor/github.com/gorilla/mux/LICENSE +++ b/vendor/github.com/gorilla/mux/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved. +Copyright (c) 2023 The Gorilla Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/vendor/github.com/gorilla/mux/Makefile b/vendor/github.com/gorilla/mux/Makefile new file mode 100644 index 00000000..98f5ab75 --- /dev/null +++ b/vendor/github.com/gorilla/mux/Makefile @@ -0,0 +1,34 @@ +GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '') +GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest + +GO_SEC=$(shell which gosec 2> /dev/null || echo '') +GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest + +GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '') +GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest + +.PHONY: golangci-lint +golangci-lint: + $(if $(GO_LINT), ,go install $(GO_LINT_URI)) + @echo "##### Running golangci-lint" + golangci-lint run -v + +.PHONY: gosec +gosec: + $(if $(GO_SEC), ,go install $(GO_SEC_URI)) + @echo "##### Running gosec" + gosec ./... + +.PHONY: govulncheck +govulncheck: + $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI)) + @echo "##### Running govulncheck" + govulncheck ./... + +.PHONY: verify +verify: golangci-lint gosec govulncheck + +.PHONY: test +test: + @echo "##### Running tests" + go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./... \ No newline at end of file diff --git a/vendor/github.com/gorilla/mux/README.md b/vendor/github.com/gorilla/mux/README.md index 35eea9f1..382513d5 100644 --- a/vendor/github.com/gorilla/mux/README.md +++ b/vendor/github.com/gorilla/mux/README.md @@ -1,12 +1,12 @@ # gorilla/mux -[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux) -[![CircleCI](https://circleci.com/gh/gorilla/mux.svg?style=svg)](https://circleci.com/gh/gorilla/mux) -[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge) +![testing](https://github.com/gorilla/mux/actions/workflows/test.yml/badge.svg) +[![codecov](https://codecov.io/github/gorilla/mux/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/mux) +[![godoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux) +[![sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge) -![Gorilla Logo](https://cloud-cdn.questionable.services/gorilla-icon-64.png) -https://www.gorillatoolkit.org/pkg/mux +![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5) Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to their respective handler. @@ -247,32 +247,25 @@ type spaHandler struct { // file located at the index path on the SPA handler will be served. This // is suitable behavior for serving an SPA (single page application). func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // get the absolute path to prevent directory traversal - path, err := filepath.Abs(r.URL.Path) - if err != nil { - // if we failed to get the absolute path respond with a 400 bad request - // and stop - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - // prepend the path with the path to the static directory - path = filepath.Join(h.staticPath, path) + // Join internally call path.Clean to prevent directory traversal + path := filepath.Join(h.staticPath, r.URL.Path) - // check whether a file exists at the given path - _, err = os.Stat(path) - if os.IsNotExist(err) { - // file does not exist, serve index.html + // check whether a file exists or is a directory at the given path + fi, err := os.Stat(path) + if os.IsNotExist(err) || fi.IsDir() { + // file does not exist or path is a directory, serve index.html http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath)) return - } else if err != nil { - // if we got an error (that wasn't that the file doesn't exist) stating the - // file, return a 500 internal server error and stop + } + + if err != nil { + // if we got an error (that wasn't that the file doesn't exist) stating the + // file, return a 500 internal server error and stop http.Error(w, err.Error(), http.StatusInternalServerError) - return + return } - // otherwise, use http.FileServer to serve the static dir + // otherwise, use http.FileServer to serve the static file http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r) } @@ -375,6 +368,19 @@ url, err := r.Get("article").URL("subdomain", "news", "id", "42") ``` +To find all the required variables for a given route when calling `URL()`, the method `GetVarNames()` is available: +```go +r := mux.NewRouter() +r.Host("{domain}"). + Path("/{group}/{item_id}"). + Queries("some_data1", "{some_data1}"). + Queries("some_data2", "{some_data2}"). + Name("article") + +// Will print [domain group item_id some_data1 some_data2] +fmt.Println(r.Get("article").GetVarNames()) + +``` ### Walking Routes The `Walk` function on `mux.Router` can be used to visit all of the routes that are registered on a router. For example, @@ -572,7 +578,7 @@ func (amw *authenticationMiddleware) Middleware(next http.Handler) http.Handler r := mux.NewRouter() r.HandleFunc("/", handler) -amw := authenticationMiddleware{} +amw := authenticationMiddleware{tokenUsers: make(map[string]string)} amw.Populate() r.Use(amw.Middleware) @@ -758,7 +764,8 @@ func TestMetricsHandler(t *testing.T) { rr := httptest.NewRecorder() - // Need to create a router that we can pass the request through so that the vars will be added to the context + // To add the vars to the context, + // we need to create a router through which we can pass the request. router := mux.NewRouter() router.HandleFunc("/metrics/{type}", MetricsHandler) router.ServeHTTP(rr, req) diff --git a/vendor/github.com/gorilla/mux/doc.go b/vendor/github.com/gorilla/mux/doc.go index bd5a38b5..80601351 100644 --- a/vendor/github.com/gorilla/mux/doc.go +++ b/vendor/github.com/gorilla/mux/doc.go @@ -10,18 +10,18 @@ http.ServeMux, mux.Router matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions. The main features are: - * Requests can be matched based on URL host, path, path prefix, schemes, - header and query values, HTTP methods or using custom matchers. - * URL hosts, paths and query values can have variables with an optional - regular expression. - * Registered URLs can be built, or "reversed", which helps maintaining - references to resources. - * Routes can be used as subrouters: nested routes are only tested if the - parent route matches. This is useful to define groups of routes that - share common conditions like a host, a path prefix or other repeated - attributes. As a bonus, this optimizes request matching. - * It implements the http.Handler interface so it is compatible with the - standard http.ServeMux. + - Requests can be matched based on URL host, path, path prefix, schemes, + header and query values, HTTP methods or using custom matchers. + - URL hosts, paths and query values can have variables with an optional + regular expression. + - Registered URLs can be built, or "reversed", which helps maintaining + references to resources. + - Routes can be used as subrouters: nested routes are only tested if the + parent route matches. This is useful to define groups of routes that + share common conditions like a host, a path prefix or other repeated + attributes. As a bonus, this optimizes request matching. + - It implements the http.Handler interface so it is compatible with the + standard http.ServeMux. Let's start registering a couple of URL paths and handlers: @@ -301,6 +301,5 @@ A more complex authentication middleware, which maps session token to users, cou r.Use(amw.Middleware) Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. - */ package mux diff --git a/vendor/github.com/gorilla/mux/mux.go b/vendor/github.com/gorilla/mux/mux.go index 782a34b2..1e089906 100644 --- a/vendor/github.com/gorilla/mux/mux.go +++ b/vendor/github.com/gorilla/mux/mux.go @@ -31,24 +31,26 @@ func NewRouter() *Router { // It implements the http.Handler interface, so it can be registered to serve // requests: // -// var router = mux.NewRouter() +// var router = mux.NewRouter() // -// func main() { -// http.Handle("/", router) -// } +// func main() { +// http.Handle("/", router) +// } // // Or, for Google App Engine, register it in a init() function: // -// func init() { -// http.Handle("/", router) -// } +// func init() { +// http.Handle("/", router) +// } // // This will send all incoming requests to the router. type Router struct { // Configurable Handler to be used when no route matches. + // This can be used to render your own 404 Not Found errors. NotFoundHandler http.Handler // Configurable Handler to be used when the request method does not match the route. + // This can be used to render your own 405 Method Not Allowed errors. MethodNotAllowedHandler http.Handler // Routes to be matched, in order. diff --git a/vendor/github.com/gorilla/mux/regexp.go b/vendor/github.com/gorilla/mux/regexp.go index 0144842b..5d05cfa0 100644 --- a/vendor/github.com/gorilla/mux/regexp.go +++ b/vendor/github.com/gorilla/mux/regexp.go @@ -22,10 +22,10 @@ type routeRegexpOptions struct { type regexpType int const ( - regexpTypePath regexpType = 0 - regexpTypeHost regexpType = 1 - regexpTypePrefix regexpType = 2 - regexpTypeQuery regexpType = 3 + regexpTypePath regexpType = iota + regexpTypeHost + regexpTypePrefix + regexpTypeQuery ) // newRouteRegexp parses a route template and returns a routeRegexp, @@ -195,7 +195,7 @@ func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool { // url builds a URL part using the given values. func (r *routeRegexp) url(values map[string]string) (string, error) { - urlValues := make([]interface{}, len(r.varsN), len(r.varsN)) + urlValues := make([]interface{}, len(r.varsN)) for k, v := range r.varsN { value, ok := values[v] if !ok { diff --git a/vendor/github.com/gorilla/mux/route.go b/vendor/github.com/gorilla/mux/route.go index 750afe57..e8f11df2 100644 --- a/vendor/github.com/gorilla/mux/route.go +++ b/vendor/github.com/gorilla/mux/route.go @@ -64,8 +64,18 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool { match.MatchErr = nil } - matchErr = nil + matchErr = nil // nolint:ineffassign return false + } else { + // Multiple routes may share the same path but use different HTTP methods. For instance: + // Route 1: POST "/users/{id}". + // Route 2: GET "/users/{id}", parameters: "id": "[0-9]+". + // + // The router must handle these cases correctly. For a GET request to "/users/abc" with "id" as "-2", + // The router should return a "Not Found" error as no route fully matches this request. + if match.MatchErr == ErrMethodMismatch { + match.MatchErr = nil + } } } @@ -230,9 +240,9 @@ func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool { // Headers adds a matcher for request header values. // It accepts a sequence of key/value pairs to be matched. For example: // -// r := mux.NewRouter() -// r.Headers("Content-Type", "application/json", -// "X-Requested-With", "XMLHttpRequest") +// r := mux.NewRouter().NewRoute() +// r.Headers("Content-Type", "application/json", +// "X-Requested-With", "XMLHttpRequest") // // The above route will only match if both request header values match. // If the value is an empty string, it will match any value if the key is set. @@ -255,9 +265,9 @@ func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) bool { // HeadersRegexp accepts a sequence of key/value pairs, where the value has regex // support. For example: // -// r := mux.NewRouter() -// r.HeadersRegexp("Content-Type", "application/(text|json)", -// "X-Requested-With", "XMLHttpRequest") +// r := mux.NewRouter().NewRoute() +// r.HeadersRegexp("Content-Type", "application/(text|json)", +// "X-Requested-With", "XMLHttpRequest") // // The above route will only match if both the request header matches both regular expressions. // If the value is an empty string, it will match any value if the key is set. @@ -283,10 +293,10 @@ func (r *Route) HeadersRegexp(pairs ...string) *Route { // // For example: // -// r := mux.NewRouter() -// r.Host("www.example.com") -// r.Host("{subdomain}.domain.com") -// r.Host("{subdomain:[a-z]+}.domain.com") +// r := mux.NewRouter().NewRoute() +// r.Host("www.example.com") +// r.Host("{subdomain}.domain.com") +// r.Host("{subdomain:[a-z]+}.domain.com") // // Variable names must be unique in a given route. They can be retrieved // calling mux.Vars(request). @@ -342,11 +352,11 @@ func (r *Route) Methods(methods ...string) *Route { // // For example: // -// r := mux.NewRouter() -// r.Path("/products/").Handler(ProductsHandler) -// r.Path("/products/{key}").Handler(ProductsHandler) -// r.Path("/articles/{category}/{id:[0-9]+}"). -// Handler(ArticleHandler) +// r := mux.NewRouter().NewRoute() +// r.Path("/products/").Handler(ProductsHandler) +// r.Path("/products/{key}").Handler(ProductsHandler) +// r.Path("/articles/{category}/{id:[0-9]+}"). +// Handler(ArticleHandler) // // Variable names must be unique in a given route. They can be retrieved // calling mux.Vars(request). @@ -377,8 +387,8 @@ func (r *Route) PathPrefix(tpl string) *Route { // It accepts a sequence of key/value pairs. Values may define variables. // For example: // -// r := mux.NewRouter() -// r.Queries("foo", "bar", "id", "{id:[0-9]+}") +// r := mux.NewRouter().NewRoute() +// r.Queries("foo", "bar", "id", "{id:[0-9]+}") // // The above route will only match if the URL contains the defined queries // values, e.g.: ?foo=bar&id=42. @@ -473,11 +483,11 @@ func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route { // // It will test the inner routes only if the parent route matched. For example: // -// r := mux.NewRouter() -// s := r.Host("www.example.com").Subrouter() -// s.HandleFunc("/products/", ProductsHandler) -// s.HandleFunc("/products/{key}", ProductHandler) -// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) +// r := mux.NewRouter().NewRoute() +// s := r.Host("www.example.com").Subrouter() +// s.HandleFunc("/products/", ProductsHandler) +// s.HandleFunc("/products/{key}", ProductHandler) +// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) // // Here, the routes registered in the subrouter won't be tested if the host // doesn't match. @@ -497,36 +507,36 @@ func (r *Route) Subrouter() *Router { // It accepts a sequence of key/value pairs for the route variables. For // example, given this route: // -// r := mux.NewRouter() -// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). -// Name("article") +// r := mux.NewRouter() +// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). +// Name("article") // // ...a URL for it can be built using: // -// url, err := r.Get("article").URL("category", "technology", "id", "42") +// url, err := r.Get("article").URL("category", "technology", "id", "42") // // ...which will return an url.URL with the following path: // -// "/articles/technology/42" +// "/articles/technology/42" // // This also works for host variables: // -// r := mux.NewRouter() -// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). -// Host("{subdomain}.domain.com"). -// Name("article") +// r := mux.NewRouter() +// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). +// Host("{subdomain}.domain.com"). +// Name("article") // -// // url.String() will be "http://news.domain.com/articles/technology/42" -// url, err := r.Get("article").URL("subdomain", "news", -// "category", "technology", -// "id", "42") +// // url.String() will be "http://news.domain.com/articles/technology/42" +// url, err := r.Get("article").URL("subdomain", "news", +// "category", "technology", +// "id", "42") // // The scheme of the resulting url will be the first argument that was passed to Schemes: // -// // url.String() will be "https://example.com" -// r := mux.NewRouter() -// url, err := r.Host("example.com") -// .Schemes("https", "http").URL() +// // url.String() will be "https://example.com" +// r := mux.NewRouter().NewRoute() +// url, err := r.Host("example.com") +// .Schemes("https", "http").URL() // // All variables defined in the route are required, and their values must // conform to the corresponding patterns. @@ -718,6 +728,25 @@ func (r *Route) GetHostTemplate() (string, error) { return r.regexp.host.template, nil } +// GetVarNames returns the names of all variables added by regexp matchers +// These can be used to know which route variables should be passed into r.URL() +func (r *Route) GetVarNames() ([]string, error) { + if r.err != nil { + return nil, r.err + } + var varNames []string + if r.regexp.host != nil { + varNames = append(varNames, r.regexp.host.varsN...) + } + if r.regexp.path != nil { + varNames = append(varNames, r.regexp.path.varsN...) + } + for _, regx := range r.regexp.queries { + varNames = append(varNames, regx.varsN...) + } + return varNames, nil +} + // prepareVars converts the route variable pairs into a map. If the route has a // BuildVarsFunc, it is invoked. func (r *Route) prepareVars(pairs ...string) (map[string]string, error) { diff --git a/vendor/github.com/vmihailenco/msgpack/v4/decode_value.go b/vendor/github.com/vmihailenco/msgpack/v4/decode_value.go index 810d3be8..f4a8b7f1 100644 --- a/vendor/github.com/vmihailenco/msgpack/v4/decode_value.go +++ b/vendor/github.com/vmihailenco/msgpack/v4/decode_value.go @@ -62,6 +62,12 @@ func getDecoder(typ reflect.Type) decoderFunc { func _getDecoder(typ reflect.Type) decoderFunc { kind := typ.Kind() + if kind == reflect.Ptr { + if _, ok := typeDecMap.Load(typ.Elem()); ok { + return ptrDecoderFunc(typ) + } + } + if typ.Implements(customDecoderType) { return decodeCustomValue } diff --git a/vendor/github.com/vmihailenco/msgpack/v4/encode.go b/vendor/github.com/vmihailenco/msgpack/v4/encode.go index 37f09870..8fa2424e 100644 --- a/vendor/github.com/vmihailenco/msgpack/v4/encode.go +++ b/vendor/github.com/vmihailenco/msgpack/v4/encode.go @@ -74,9 +74,8 @@ func Marshal(v interface{}) ([]byte, error) { type Encoder struct { w writer - buf []byte - timeBuf []byte - bootstrap [9 + 12]byte + buf []byte + timeBuf []byte intern map[string]int @@ -85,9 +84,9 @@ type Encoder struct { // NewEncoder returns a new encoder that writes to w. func NewEncoder(w io.Writer) *Encoder { - e := new(Encoder) - e.buf = e.bootstrap[:9] - e.timeBuf = e.bootstrap[9 : 9+12] + e := &Encoder{ + buf: make([]byte, 9), + } e.Reset(w) return e } diff --git a/vendor/github.com/vmihailenco/msgpack/v4/time.go b/vendor/github.com/vmihailenco/msgpack/v4/time.go index bf53eb2a..c6662720 100644 --- a/vendor/github.com/vmihailenco/msgpack/v4/time.go +++ b/vendor/github.com/vmihailenco/msgpack/v4/time.go @@ -30,14 +30,20 @@ func (e *Encoder) EncodeTime(tm time.Time) error { } func (e *Encoder) encodeTime(tm time.Time) []byte { + if e.timeBuf == nil { + e.timeBuf = make([]byte, 12) + } + secs := uint64(tm.Unix()) if secs>>34 == 0 { data := uint64(tm.Nanosecond())<<34 | secs + if data&0xffffffff00000000 == 0 { b := e.timeBuf[:4] binary.BigEndian.PutUint32(b, uint32(data)) return b } + b := e.timeBuf[:8] binary.BigEndian.PutUint64(b, data) return b diff --git a/vendor/golang.org/x/exp/maps/maps.go b/vendor/golang.org/x/exp/maps/maps.go new file mode 100644 index 00000000..ecc0dabb --- /dev/null +++ b/vendor/golang.org/x/exp/maps/maps.go @@ -0,0 +1,94 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package maps defines various functions useful with maps of any type. +package maps + +// Keys returns the keys of the map m. +// The keys will be in an indeterminate order. +func Keys[M ~map[K]V, K comparable, V any](m M) []K { + r := make([]K, 0, len(m)) + for k := range m { + r = append(r, k) + } + return r +} + +// Values returns the values of the map m. +// The values will be in an indeterminate order. +func Values[M ~map[K]V, K comparable, V any](m M) []V { + r := make([]V, 0, len(m)) + for _, v := range m { + r = append(r, v) + } + return r +} + +// Equal reports whether two maps contain the same key/value pairs. +// Values are compared using ==. +func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool { + if len(m1) != len(m2) { + return false + } + for k, v1 := range m1 { + if v2, ok := m2[k]; !ok || v1 != v2 { + return false + } + } + return true +} + +// EqualFunc is like Equal, but compares values using eq. +// Keys are still compared with ==. +func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool { + if len(m1) != len(m2) { + return false + } + for k, v1 := range m1 { + if v2, ok := m2[k]; !ok || !eq(v1, v2) { + return false + } + } + return true +} + +// Clear removes all entries from m, leaving it empty. +func Clear[M ~map[K]V, K comparable, V any](m M) { + for k := range m { + delete(m, k) + } +} + +// Clone returns a copy of m. This is a shallow clone: +// the new keys and values are set using ordinary assignment. +func Clone[M ~map[K]V, K comparable, V any](m M) M { + // Preserve nil in case it matters. + if m == nil { + return nil + } + r := make(M, len(m)) + for k, v := range m { + r[k] = v + } + return r +} + +// Copy copies all key/value pairs in src adding them to dst. +// When a key in src is already present in dst, +// the value in dst will be overwritten by the value associated +// with the key in src. +func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) { + for k, v := range src { + dst[k] = v + } +} + +// DeleteFunc deletes any key/value pairs from m for which del returns true. +func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) { + for k, v := range m { + if del(k, v) { + delete(m, k) + } + } +} diff --git a/vendor/golang.org/x/mod/LICENSE b/vendor/golang.org/x/mod/LICENSE deleted file mode 100644 index 6a66aea5..00000000 --- a/vendor/golang.org/x/mod/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/mod/PATENTS b/vendor/golang.org/x/mod/PATENTS deleted file mode 100644 index 73309904..00000000 --- a/vendor/golang.org/x/mod/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go b/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go deleted file mode 100644 index 150f887e..00000000 --- a/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package lazyregexp is a thin wrapper over regexp, allowing the use of global -// regexp variables without forcing them to be compiled at init. -package lazyregexp - -import ( - "os" - "regexp" - "strings" - "sync" -) - -// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be -// compiled the first time it is needed. -type Regexp struct { - str string - once sync.Once - rx *regexp.Regexp -} - -func (r *Regexp) re() *regexp.Regexp { - r.once.Do(r.build) - return r.rx -} - -func (r *Regexp) build() { - r.rx = regexp.MustCompile(r.str) - r.str = "" -} - -func (r *Regexp) FindSubmatch(s []byte) [][]byte { - return r.re().FindSubmatch(s) -} - -func (r *Regexp) FindStringSubmatch(s string) []string { - return r.re().FindStringSubmatch(s) -} - -func (r *Regexp) FindStringSubmatchIndex(s string) []int { - return r.re().FindStringSubmatchIndex(s) -} - -func (r *Regexp) ReplaceAllString(src, repl string) string { - return r.re().ReplaceAllString(src, repl) -} - -func (r *Regexp) FindString(s string) string { - return r.re().FindString(s) -} - -func (r *Regexp) FindAllString(s string, n int) []string { - return r.re().FindAllString(s, n) -} - -func (r *Regexp) MatchString(s string) bool { - return r.re().MatchString(s) -} - -func (r *Regexp) SubexpNames() []string { - return r.re().SubexpNames() -} - -var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") - -// New creates a new lazy regexp, delaying the compiling work until it is first -// needed. If the code is being run as part of tests, the regexp compiling will -// happen immediately. -func New(str string) *Regexp { - lr := &Regexp{str: str} - if inTest { - // In tests, always compile the regexps early. - lr.re() - } - return lr -} diff --git a/vendor/golang.org/x/mod/module/module.go b/vendor/golang.org/x/mod/module/module.go deleted file mode 100644 index 2a364b22..00000000 --- a/vendor/golang.org/x/mod/module/module.go +++ /dev/null @@ -1,841 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package module defines the module.Version type along with support code. -// -// The [module.Version] type is a simple Path, Version pair: -// -// type Version struct { -// Path string -// Version string -// } -// -// There are no restrictions imposed directly by use of this structure, -// but additional checking functions, most notably [Check], verify that -// a particular path, version pair is valid. -// -// # Escaped Paths -// -// Module paths appear as substrings of file system paths -// (in the download cache) and of web server URLs in the proxy protocol. -// In general we cannot rely on file systems to be case-sensitive, -// nor can we rely on web servers, since they read from file systems. -// That is, we cannot rely on the file system to keep rsc.io/QUOTE -// and rsc.io/quote separate. Windows and macOS don't. -// Instead, we must never require two different casings of a file path. -// Because we want the download cache to match the proxy protocol, -// and because we want the proxy protocol to be possible to serve -// from a tree of static files (which might be stored on a case-insensitive -// file system), the proxy protocol must never require two different casings -// of a URL path either. -// -// One possibility would be to make the escaped form be the lowercase -// hexadecimal encoding of the actual path bytes. This would avoid ever -// needing different casings of a file path, but it would be fairly illegible -// to most programmers when those paths appeared in the file system -// (including in file paths in compiler errors and stack traces) -// in web server logs, and so on. Instead, we want a safe escaped form that -// leaves most paths unaltered. -// -// The safe escaped form is to replace every uppercase letter -// with an exclamation mark followed by the letter's lowercase equivalent. -// -// For example, -// -// github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go. -// github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy -// github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus. -// -// Import paths that avoid upper-case letters are left unchanged. -// Note that because import paths are ASCII-only and avoid various -// problematic punctuation (like : < and >), the escaped form is also ASCII-only -// and avoids the same problematic punctuation. -// -// Import paths have never allowed exclamation marks, so there is no -// need to define how to escape a literal !. -// -// # Unicode Restrictions -// -// Today, paths are disallowed from using Unicode. -// -// Although paths are currently disallowed from using Unicode, -// we would like at some point to allow Unicode letters as well, to assume that -// file systems and URLs are Unicode-safe (storing UTF-8), and apply -// the !-for-uppercase convention for escaping them in the file system. -// But there are at least two subtle considerations. -// -// First, note that not all case-fold equivalent distinct runes -// form an upper/lower pair. -// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin) -// are three distinct runes that case-fold to each other. -// When we do add Unicode letters, we must not assume that upper/lower -// are the only case-equivalent pairs. -// Perhaps the Kelvin symbol would be disallowed entirely, for example. -// Or perhaps it would escape as "!!k", or perhaps as "(212A)". -// -// Second, it would be nice to allow Unicode marks as well as letters, -// but marks include combining marks, and then we must deal not -// only with case folding but also normalization: both U+00E9 ('é') -// and U+0065 U+0301 ('e' followed by combining acute accent) -// look the same on the page and are treated by some file systems -// as the same path. If we do allow Unicode marks in paths, there -// must be some kind of normalization to allow only one canonical -// encoding of any character used in an import path. -package module - -// IMPORTANT NOTE -// -// This file essentially defines the set of valid import paths for the go command. -// There are many subtle considerations, including Unicode ambiguity, -// security, network, and file system representations. -// -// This file also defines the set of valid module path and version combinations, -// another topic with many subtle considerations. -// -// Changes to the semantics in this file require approval from rsc. - -import ( - "errors" - "fmt" - "path" - "sort" - "strings" - "unicode" - "unicode/utf8" - - "golang.org/x/mod/semver" -) - -// A Version (for clients, a module.Version) is defined by a module path and version pair. -// These are stored in their plain (unescaped) form. -type Version struct { - // Path is a module path, like "golang.org/x/text" or "rsc.io/quote/v2". - Path string - - // Version is usually a semantic version in canonical form. - // There are three exceptions to this general rule. - // First, the top-level target of a build has no specific version - // and uses Version = "". - // Second, during MVS calculations the version "none" is used - // to represent the decision to take no version of a given module. - // Third, filesystem paths found in "replace" directives are - // represented by a path with an empty version. - Version string `json:",omitempty"` -} - -// String returns a representation of the Version suitable for logging -// (Path@Version, or just Path if Version is empty). -func (m Version) String() string { - if m.Version == "" { - return m.Path - } - return m.Path + "@" + m.Version -} - -// A ModuleError indicates an error specific to a module. -type ModuleError struct { - Path string - Version string - Err error -} - -// VersionError returns a [ModuleError] derived from a [Version] and error, -// or err itself if it is already such an error. -func VersionError(v Version, err error) error { - var mErr *ModuleError - if errors.As(err, &mErr) && mErr.Path == v.Path && mErr.Version == v.Version { - return err - } - return &ModuleError{ - Path: v.Path, - Version: v.Version, - Err: err, - } -} - -func (e *ModuleError) Error() string { - if v, ok := e.Err.(*InvalidVersionError); ok { - return fmt.Sprintf("%s@%s: invalid %s: %v", e.Path, v.Version, v.noun(), v.Err) - } - if e.Version != "" { - return fmt.Sprintf("%s@%s: %v", e.Path, e.Version, e.Err) - } - return fmt.Sprintf("module %s: %v", e.Path, e.Err) -} - -func (e *ModuleError) Unwrap() error { return e.Err } - -// An InvalidVersionError indicates an error specific to a version, with the -// module path unknown or specified externally. -// -// A [ModuleError] may wrap an InvalidVersionError, but an InvalidVersionError -// must not wrap a ModuleError. -type InvalidVersionError struct { - Version string - Pseudo bool - Err error -} - -// noun returns either "version" or "pseudo-version", depending on whether -// e.Version is a pseudo-version. -func (e *InvalidVersionError) noun() string { - if e.Pseudo { - return "pseudo-version" - } - return "version" -} - -func (e *InvalidVersionError) Error() string { - return fmt.Sprintf("%s %q invalid: %s", e.noun(), e.Version, e.Err) -} - -func (e *InvalidVersionError) Unwrap() error { return e.Err } - -// An InvalidPathError indicates a module, import, or file path doesn't -// satisfy all naming constraints. See [CheckPath], [CheckImportPath], -// and [CheckFilePath] for specific restrictions. -type InvalidPathError struct { - Kind string // "module", "import", or "file" - Path string - Err error -} - -func (e *InvalidPathError) Error() string { - return fmt.Sprintf("malformed %s path %q: %v", e.Kind, e.Path, e.Err) -} - -func (e *InvalidPathError) Unwrap() error { return e.Err } - -// Check checks that a given module path, version pair is valid. -// In addition to the path being a valid module path -// and the version being a valid semantic version, -// the two must correspond. -// For example, the path "yaml/v2" only corresponds to -// semantic versions beginning with "v2.". -func Check(path, version string) error { - if err := CheckPath(path); err != nil { - return err - } - if !semver.IsValid(version) { - return &ModuleError{ - Path: path, - Err: &InvalidVersionError{Version: version, Err: errors.New("not a semantic version")}, - } - } - _, pathMajor, _ := SplitPathVersion(path) - if err := CheckPathMajor(version, pathMajor); err != nil { - return &ModuleError{Path: path, Err: err} - } - return nil -} - -// firstPathOK reports whether r can appear in the first element of a module path. -// The first element of the path must be an LDH domain name, at least for now. -// To avoid case ambiguity, the domain name must be entirely lower case. -func firstPathOK(r rune) bool { - return r == '-' || r == '.' || - '0' <= r && r <= '9' || - 'a' <= r && r <= 'z' -} - -// modPathOK reports whether r can appear in a module path element. -// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~. -// -// This matches what "go get" has historically recognized in import paths, -// and avoids confusing sequences like '%20' or '+' that would change meaning -// if used in a URL. -// -// TODO(rsc): We would like to allow Unicode letters, but that requires additional -// care in the safe encoding (see "escaped paths" above). -func modPathOK(r rune) bool { - if r < utf8.RuneSelf { - return r == '-' || r == '.' || r == '_' || r == '~' || - '0' <= r && r <= '9' || - 'A' <= r && r <= 'Z' || - 'a' <= r && r <= 'z' - } - return false -} - -// importPathOK reports whether r can appear in a package import path element. -// -// Import paths are intermediate between module paths and file paths: we allow -// disallow characters that would be confusing or ambiguous as arguments to -// 'go get' (such as '@' and ' ' ), but allow certain characters that are -// otherwise-unambiguous on the command line and historically used for some -// binary names (such as '++' as a suffix for compiler binaries and wrappers). -func importPathOK(r rune) bool { - return modPathOK(r) || r == '+' -} - -// fileNameOK reports whether r can appear in a file name. -// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters. -// If we expand the set of allowed characters here, we have to -// work harder at detecting potential case-folding and normalization collisions. -// See note about "escaped paths" above. -func fileNameOK(r rune) bool { - if r < utf8.RuneSelf { - // Entire set of ASCII punctuation, from which we remove characters: - // ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ - // We disallow some shell special characters: " ' * < > ? ` | - // (Note that some of those are disallowed by the Windows file system as well.) - // We also disallow path separators / : and \ (fileNameOK is only called on path element characters). - // We allow spaces (U+0020) in file names. - const allowed = "!#$%&()+,-.=@[]^_{}~ " - if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' { - return true - } - return strings.ContainsRune(allowed, r) - } - // It may be OK to add more ASCII punctuation here, but only carefully. - // For example Windows disallows < > \, and macOS disallows :, so we must not allow those. - return unicode.IsLetter(r) -} - -// CheckPath checks that a module path is valid. -// A valid module path is a valid import path, as checked by [CheckImportPath], -// with three additional constraints. -// First, the leading path element (up to the first slash, if any), -// by convention a domain name, must contain only lower-case ASCII letters, -// ASCII digits, dots (U+002E), and dashes (U+002D); -// it must contain at least one dot and cannot start with a dash. -// Second, for a final path element of the form /vN, where N looks numeric -// (ASCII digits and dots) must not begin with a leading zero, must not be /v1, -// and must not contain any dots. For paths beginning with "gopkg.in/", -// this second requirement is replaced by a requirement that the path -// follow the gopkg.in server's conventions. -// Third, no path element may begin with a dot. -func CheckPath(path string) (err error) { - defer func() { - if err != nil { - err = &InvalidPathError{Kind: "module", Path: path, Err: err} - } - }() - - if err := checkPath(path, modulePath); err != nil { - return err - } - i := strings.Index(path, "/") - if i < 0 { - i = len(path) - } - if i == 0 { - return fmt.Errorf("leading slash") - } - if !strings.Contains(path[:i], ".") { - return fmt.Errorf("missing dot in first path element") - } - if path[0] == '-' { - return fmt.Errorf("leading dash in first path element") - } - for _, r := range path[:i] { - if !firstPathOK(r) { - return fmt.Errorf("invalid char %q in first path element", r) - } - } - if _, _, ok := SplitPathVersion(path); !ok { - return fmt.Errorf("invalid version") - } - return nil -} - -// CheckImportPath checks that an import path is valid. -// -// A valid import path consists of one or more valid path elements -// separated by slashes (U+002F). (It must not begin with nor end in a slash.) -// -// A valid path element is a non-empty string made up of -// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~. -// It must not end with a dot (U+002E), nor contain two dots in a row. -// -// The element prefix up to the first dot must not be a reserved file name -// on Windows, regardless of case (CON, com1, NuL, and so on). The element -// must not have a suffix of a tilde followed by one or more ASCII digits -// (to exclude paths elements that look like Windows short-names). -// -// CheckImportPath may be less restrictive in the future, but see the -// top-level package documentation for additional information about -// subtleties of Unicode. -func CheckImportPath(path string) error { - if err := checkPath(path, importPath); err != nil { - return &InvalidPathError{Kind: "import", Path: path, Err: err} - } - return nil -} - -// pathKind indicates what kind of path we're checking. Module paths, -// import paths, and file paths have different restrictions. -type pathKind int - -const ( - modulePath pathKind = iota - importPath - filePath -) - -// checkPath checks that a general path is valid. kind indicates what -// specific constraints should be applied. -// -// checkPath returns an error describing why the path is not valid. -// Because these checks apply to module, import, and file paths, -// and because other checks may be applied, the caller is expected to wrap -// this error with [InvalidPathError]. -func checkPath(path string, kind pathKind) error { - if !utf8.ValidString(path) { - return fmt.Errorf("invalid UTF-8") - } - if path == "" { - return fmt.Errorf("empty string") - } - if path[0] == '-' && kind != filePath { - return fmt.Errorf("leading dash") - } - if strings.Contains(path, "//") { - return fmt.Errorf("double slash") - } - if path[len(path)-1] == '/' { - return fmt.Errorf("trailing slash") - } - elemStart := 0 - for i, r := range path { - if r == '/' { - if err := checkElem(path[elemStart:i], kind); err != nil { - return err - } - elemStart = i + 1 - } - } - if err := checkElem(path[elemStart:], kind); err != nil { - return err - } - return nil -} - -// checkElem checks whether an individual path element is valid. -func checkElem(elem string, kind pathKind) error { - if elem == "" { - return fmt.Errorf("empty path element") - } - if strings.Count(elem, ".") == len(elem) { - return fmt.Errorf("invalid path element %q", elem) - } - if elem[0] == '.' && kind == modulePath { - return fmt.Errorf("leading dot in path element") - } - if elem[len(elem)-1] == '.' { - return fmt.Errorf("trailing dot in path element") - } - for _, r := range elem { - ok := false - switch kind { - case modulePath: - ok = modPathOK(r) - case importPath: - ok = importPathOK(r) - case filePath: - ok = fileNameOK(r) - default: - panic(fmt.Sprintf("internal error: invalid kind %v", kind)) - } - if !ok { - return fmt.Errorf("invalid char %q", r) - } - } - - // Windows disallows a bunch of path elements, sadly. - // See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file - short := elem - if i := strings.Index(short, "."); i >= 0 { - short = short[:i] - } - for _, bad := range badWindowsNames { - if strings.EqualFold(bad, short) { - return fmt.Errorf("%q disallowed as path element component on Windows", short) - } - } - - if kind == filePath { - // don't check for Windows short-names in file names. They're - // only an issue for import paths. - return nil - } - - // Reject path components that look like Windows short-names. - // Those usually end in a tilde followed by one or more ASCII digits. - if tilde := strings.LastIndexByte(short, '~'); tilde >= 0 && tilde < len(short)-1 { - suffix := short[tilde+1:] - suffixIsDigits := true - for _, r := range suffix { - if r < '0' || r > '9' { - suffixIsDigits = false - break - } - } - if suffixIsDigits { - return fmt.Errorf("trailing tilde and digits in path element") - } - } - - return nil -} - -// CheckFilePath checks that a slash-separated file path is valid. -// The definition of a valid file path is the same as the definition -// of a valid import path except that the set of allowed characters is larger: -// all Unicode letters, ASCII digits, the ASCII space character (U+0020), -// and the ASCII punctuation characters -// “!#$%&()+,-.=@[]^_{}~”. -// (The excluded punctuation characters, " * < > ? ` ' | / \ and :, -// have special meanings in certain shells or operating systems.) -// -// CheckFilePath may be less restrictive in the future, but see the -// top-level package documentation for additional information about -// subtleties of Unicode. -func CheckFilePath(path string) error { - if err := checkPath(path, filePath); err != nil { - return &InvalidPathError{Kind: "file", Path: path, Err: err} - } - return nil -} - -// badWindowsNames are the reserved file path elements on Windows. -// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file -var badWindowsNames = []string{ - "CON", - "PRN", - "AUX", - "NUL", - "COM1", - "COM2", - "COM3", - "COM4", - "COM5", - "COM6", - "COM7", - "COM8", - "COM9", - "LPT1", - "LPT2", - "LPT3", - "LPT4", - "LPT5", - "LPT6", - "LPT7", - "LPT8", - "LPT9", -} - -// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path -// and version is either empty or "/vN" for N >= 2. -// As a special case, gopkg.in paths are recognized directly; -// they require ".vN" instead of "/vN", and for all N, not just N >= 2. -// SplitPathVersion returns with ok = false when presented with -// a path whose last path element does not satisfy the constraints -// applied by [CheckPath], such as "example.com/pkg/v1" or "example.com/pkg/v1.2". -func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) { - if strings.HasPrefix(path, "gopkg.in/") { - return splitGopkgIn(path) - } - - i := len(path) - dot := false - for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') { - if path[i-1] == '.' { - dot = true - } - i-- - } - if i <= 1 || i == len(path) || path[i-1] != 'v' || path[i-2] != '/' { - return path, "", true - } - prefix, pathMajor = path[:i-2], path[i-2:] - if dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == "/v1" { - return path, "", false - } - return prefix, pathMajor, true -} - -// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths. -func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) { - if !strings.HasPrefix(path, "gopkg.in/") { - return path, "", false - } - i := len(path) - if strings.HasSuffix(path, "-unstable") { - i -= len("-unstable") - } - for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') { - i-- - } - if i <= 1 || path[i-1] != 'v' || path[i-2] != '.' { - // All gopkg.in paths must end in vN for some N. - return path, "", false - } - prefix, pathMajor = path[:i-2], path[i-2:] - if len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != ".v0" { - return path, "", false - } - return prefix, pathMajor, true -} - -// MatchPathMajor reports whether the semantic version v -// matches the path major version pathMajor. -// -// MatchPathMajor returns true if and only if [CheckPathMajor] returns nil. -func MatchPathMajor(v, pathMajor string) bool { - return CheckPathMajor(v, pathMajor) == nil -} - -// CheckPathMajor returns a non-nil error if the semantic version v -// does not match the path major version pathMajor. -func CheckPathMajor(v, pathMajor string) error { - // TODO(jayconrod): return errors or panic for invalid inputs. This function - // (and others) was covered by integration tests for cmd/go, and surrounding - // code protected against invalid inputs like non-canonical versions. - if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { - pathMajor = strings.TrimSuffix(pathMajor, "-unstable") - } - if strings.HasPrefix(v, "v0.0.0-") && pathMajor == ".v1" { - // Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1. - // For example, gopkg.in/yaml.v2@v2.2.1's go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405. - return nil - } - m := semver.Major(v) - if pathMajor == "" { - if m == "v0" || m == "v1" || semver.Build(v) == "+incompatible" { - return nil - } - pathMajor = "v0 or v1" - } else if pathMajor[0] == '/' || pathMajor[0] == '.' { - if m == pathMajor[1:] { - return nil - } - pathMajor = pathMajor[1:] - } - return &InvalidVersionError{ - Version: v, - Err: fmt.Errorf("should be %s, not %s", pathMajor, semver.Major(v)), - } -} - -// PathMajorPrefix returns the major-version tag prefix implied by pathMajor. -// An empty PathMajorPrefix allows either v0 or v1. -// -// Note that [MatchPathMajor] may accept some versions that do not actually begin -// with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1' -// pathMajor, even though that pathMajor implies 'v1' tagging. -func PathMajorPrefix(pathMajor string) string { - if pathMajor == "" { - return "" - } - if pathMajor[0] != '/' && pathMajor[0] != '.' { - panic("pathMajor suffix " + pathMajor + " passed to PathMajorPrefix lacks separator") - } - if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { - pathMajor = strings.TrimSuffix(pathMajor, "-unstable") - } - m := pathMajor[1:] - if m != semver.Major(m) { - panic("pathMajor suffix " + pathMajor + "passed to PathMajorPrefix is not a valid major version") - } - return m -} - -// CanonicalVersion returns the canonical form of the version string v. -// It is the same as [semver.Canonical] except that it preserves the special build suffix "+incompatible". -func CanonicalVersion(v string) string { - cv := semver.Canonical(v) - if semver.Build(v) == "+incompatible" { - cv += "+incompatible" - } - return cv -} - -// Sort sorts the list by Path, breaking ties by comparing [Version] fields. -// The Version fields are interpreted as semantic versions (using [semver.Compare]) -// optionally followed by a tie-breaking suffix introduced by a slash character, -// like in "v0.0.1/go.mod". -func Sort(list []Version) { - sort.Slice(list, func(i, j int) bool { - mi := list[i] - mj := list[j] - if mi.Path != mj.Path { - return mi.Path < mj.Path - } - // To help go.sum formatting, allow version/file. - // Compare semver prefix by semver rules, - // file by string order. - vi := mi.Version - vj := mj.Version - var fi, fj string - if k := strings.Index(vi, "/"); k >= 0 { - vi, fi = vi[:k], vi[k:] - } - if k := strings.Index(vj, "/"); k >= 0 { - vj, fj = vj[:k], vj[k:] - } - if vi != vj { - return semver.Compare(vi, vj) < 0 - } - return fi < fj - }) -} - -// EscapePath returns the escaped form of the given module path. -// It fails if the module path is invalid. -func EscapePath(path string) (escaped string, err error) { - if err := CheckPath(path); err != nil { - return "", err - } - - return escapeString(path) -} - -// EscapeVersion returns the escaped form of the given module version. -// Versions are allowed to be in non-semver form but must be valid file names -// and not contain exclamation marks. -func EscapeVersion(v string) (escaped string, err error) { - if err := checkElem(v, filePath); err != nil || strings.Contains(v, "!") { - return "", &InvalidVersionError{ - Version: v, - Err: fmt.Errorf("disallowed version string"), - } - } - return escapeString(v) -} - -func escapeString(s string) (escaped string, err error) { - haveUpper := false - for _, r := range s { - if r == '!' || r >= utf8.RuneSelf { - // This should be disallowed by CheckPath, but diagnose anyway. - // The correctness of the escaping loop below depends on it. - return "", fmt.Errorf("internal error: inconsistency in EscapePath") - } - if 'A' <= r && r <= 'Z' { - haveUpper = true - } - } - - if !haveUpper { - return s, nil - } - - var buf []byte - for _, r := range s { - if 'A' <= r && r <= 'Z' { - buf = append(buf, '!', byte(r+'a'-'A')) - } else { - buf = append(buf, byte(r)) - } - } - return string(buf), nil -} - -// UnescapePath returns the module path for the given escaped path. -// It fails if the escaped path is invalid or describes an invalid path. -func UnescapePath(escaped string) (path string, err error) { - path, ok := unescapeString(escaped) - if !ok { - return "", fmt.Errorf("invalid escaped module path %q", escaped) - } - if err := CheckPath(path); err != nil { - return "", fmt.Errorf("invalid escaped module path %q: %v", escaped, err) - } - return path, nil -} - -// UnescapeVersion returns the version string for the given escaped version. -// It fails if the escaped form is invalid or describes an invalid version. -// Versions are allowed to be in non-semver form but must be valid file names -// and not contain exclamation marks. -func UnescapeVersion(escaped string) (v string, err error) { - v, ok := unescapeString(escaped) - if !ok { - return "", fmt.Errorf("invalid escaped version %q", escaped) - } - if err := checkElem(v, filePath); err != nil { - return "", fmt.Errorf("invalid escaped version %q: %v", v, err) - } - return v, nil -} - -func unescapeString(escaped string) (string, bool) { - var buf []byte - - bang := false - for _, r := range escaped { - if r >= utf8.RuneSelf { - return "", false - } - if bang { - bang = false - if r < 'a' || 'z' < r { - return "", false - } - buf = append(buf, byte(r+'A'-'a')) - continue - } - if r == '!' { - bang = true - continue - } - if 'A' <= r && r <= 'Z' { - return "", false - } - buf = append(buf, byte(r)) - } - if bang { - return "", false - } - return string(buf), true -} - -// MatchPrefixPatterns reports whether any path prefix of target matches one of -// the glob patterns (as defined by [path.Match]) in the comma-separated globs -// list. This implements the algorithm used when matching a module path to the -// GOPRIVATE environment variable, as described by 'go help module-private'. -// -// It ignores any empty or malformed patterns in the list. -// Trailing slashes on patterns are ignored. -func MatchPrefixPatterns(globs, target string) bool { - for globs != "" { - // Extract next non-empty glob in comma-separated list. - var glob string - if i := strings.Index(globs, ","); i >= 0 { - glob, globs = globs[:i], globs[i+1:] - } else { - glob, globs = globs, "" - } - glob = strings.TrimSuffix(glob, "/") - if glob == "" { - continue - } - - // A glob with N+1 path elements (N slashes) needs to be matched - // against the first N+1 path elements of target, - // which end just before the N+1'th slash. - n := strings.Count(glob, "/") - prefix := target - // Walk target, counting slashes, truncating at the N+1'th slash. - for i := 0; i < len(target); i++ { - if target[i] == '/' { - if n == 0 { - prefix = target[:i] - break - } - n-- - } - } - if n > 0 { - // Not enough prefix elements. - continue - } - matched, _ := path.Match(glob, prefix) - if matched { - return true - } - } - return false -} diff --git a/vendor/golang.org/x/mod/module/pseudo.go b/vendor/golang.org/x/mod/module/pseudo.go deleted file mode 100644 index 9cf19d32..00000000 --- a/vendor/golang.org/x/mod/module/pseudo.go +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Pseudo-versions -// -// Code authors are expected to tag the revisions they want users to use, -// including prereleases. However, not all authors tag versions at all, -// and not all commits a user might want to try will have tags. -// A pseudo-version is a version with a special form that allows us to -// address an untagged commit and order that version with respect to -// other versions we might encounter. -// -// A pseudo-version takes one of the general forms: -// -// (1) vX.0.0-yyyymmddhhmmss-abcdef123456 -// (2) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 -// (3) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible -// (4) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 -// (5) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible -// -// If there is no recently tagged version with the right major version vX, -// then form (1) is used, creating a space of pseudo-versions at the bottom -// of the vX version range, less than any tagged version, including the unlikely v0.0.0. -// -// If the most recent tagged version before the target commit is vX.Y.Z or vX.Y.Z+incompatible, -// then the pseudo-version uses form (2) or (3), making it a prerelease for the next -// possible semantic version after vX.Y.Z. The leading 0 segment in the prerelease string -// ensures that the pseudo-version compares less than possible future explicit prereleases -// like vX.Y.(Z+1)-rc1 or vX.Y.(Z+1)-1. -// -// If the most recent tagged version before the target commit is vX.Y.Z-pre or vX.Y.Z-pre+incompatible, -// then the pseudo-version uses form (4) or (5), making it a slightly later prerelease. - -package module - -import ( - "errors" - "fmt" - "strings" - "time" - - "golang.org/x/mod/internal/lazyregexp" - "golang.org/x/mod/semver" -) - -var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`) - -const PseudoVersionTimestampFormat = "20060102150405" - -// PseudoVersion returns a pseudo-version for the given major version ("v1") -// preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time, -// and revision identifier (usually a 12-byte commit hash prefix). -func PseudoVersion(major, older string, t time.Time, rev string) string { - if major == "" { - major = "v0" - } - segment := fmt.Sprintf("%s-%s", t.UTC().Format(PseudoVersionTimestampFormat), rev) - build := semver.Build(older) - older = semver.Canonical(older) - if older == "" { - return major + ".0.0-" + segment // form (1) - } - if semver.Prerelease(older) != "" { - return older + ".0." + segment + build // form (4), (5) - } - - // Form (2), (3). - // Extract patch from vMAJOR.MINOR.PATCH - i := strings.LastIndex(older, ".") + 1 - v, patch := older[:i], older[i:] - - // Reassemble. - return v + incDecimal(patch) + "-0." + segment + build -} - -// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and -// revision, which may be used as a placeholder. -func ZeroPseudoVersion(major string) string { - return PseudoVersion(major, "", time.Time{}, "000000000000") -} - -// incDecimal returns the decimal string incremented by 1. -func incDecimal(decimal string) string { - // Scan right to left turning 9s to 0s until you find a digit to increment. - digits := []byte(decimal) - i := len(digits) - 1 - for ; i >= 0 && digits[i] == '9'; i-- { - digits[i] = '0' - } - if i >= 0 { - digits[i]++ - } else { - // digits is all zeros - digits[0] = '1' - digits = append(digits, '0') - } - return string(digits) -} - -// decDecimal returns the decimal string decremented by 1, or the empty string -// if the decimal is all zeroes. -func decDecimal(decimal string) string { - // Scan right to left turning 0s to 9s until you find a digit to decrement. - digits := []byte(decimal) - i := len(digits) - 1 - for ; i >= 0 && digits[i] == '0'; i-- { - digits[i] = '9' - } - if i < 0 { - // decimal is all zeros - return "" - } - if i == 0 && digits[i] == '1' && len(digits) > 1 { - digits = digits[1:] - } else { - digits[i]-- - } - return string(digits) -} - -// IsPseudoVersion reports whether v is a pseudo-version. -func IsPseudoVersion(v string) bool { - return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v) -} - -// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base, -// timestamp, and revision, as returned by [ZeroPseudoVersion]. -func IsZeroPseudoVersion(v string) bool { - return v == ZeroPseudoVersion(semver.Major(v)) -} - -// PseudoVersionTime returns the time stamp of the pseudo-version v. -// It returns an error if v is not a pseudo-version or if the time stamp -// embedded in the pseudo-version is not a valid time. -func PseudoVersionTime(v string) (time.Time, error) { - _, timestamp, _, _, err := parsePseudoVersion(v) - if err != nil { - return time.Time{}, err - } - t, err := time.Parse("20060102150405", timestamp) - if err != nil { - return time.Time{}, &InvalidVersionError{ - Version: v, - Pseudo: true, - Err: fmt.Errorf("malformed time %q", timestamp), - } - } - return t, nil -} - -// PseudoVersionRev returns the revision identifier of the pseudo-version v. -// It returns an error if v is not a pseudo-version. -func PseudoVersionRev(v string) (rev string, err error) { - _, _, rev, _, err = parsePseudoVersion(v) - return -} - -// PseudoVersionBase returns the canonical parent version, if any, upon which -// the pseudo-version v is based. -// -// If v has no parent version (that is, if it is "vX.0.0-[…]"), -// PseudoVersionBase returns the empty string and a nil error. -func PseudoVersionBase(v string) (string, error) { - base, _, _, build, err := parsePseudoVersion(v) - if err != nil { - return "", err - } - - switch pre := semver.Prerelease(base); pre { - case "": - // vX.0.0-yyyymmddhhmmss-abcdef123456 → "" - if build != "" { - // Pseudo-versions of the form vX.0.0-yyyymmddhhmmss-abcdef123456+incompatible - // are nonsensical: the "vX.0.0-" prefix implies that there is no parent tag, - // but the "+incompatible" suffix implies that the major version of - // the parent tag is not compatible with the module's import path. - // - // There are a few such entries in the index generated by proxy.golang.org, - // but we believe those entries were generated by the proxy itself. - return "", &InvalidVersionError{ - Version: v, - Pseudo: true, - Err: fmt.Errorf("lacks base version, but has build metadata %q", build), - } - } - return "", nil - - case "-0": - // vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z - // vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z+incompatible - base = strings.TrimSuffix(base, pre) - i := strings.LastIndexByte(base, '.') - if i < 0 { - panic("base from parsePseudoVersion missing patch number: " + base) - } - patch := decDecimal(base[i+1:]) - if patch == "" { - // vX.0.0-0 is invalid, but has been observed in the wild in the index - // generated by requests to proxy.golang.org. - // - // NOTE(bcmills): I cannot find a historical bug that accounts for - // pseudo-versions of this form, nor have I seen such versions in any - // actual go.mod files. If we find actual examples of this form and a - // reasonable theory of how they came into existence, it seems fine to - // treat them as equivalent to vX.0.0 (especially since the invalid - // pseudo-versions have lower precedence than the real ones). For now, we - // reject them. - return "", &InvalidVersionError{ - Version: v, - Pseudo: true, - Err: fmt.Errorf("version before %s would have negative patch number", base), - } - } - return base[:i+1] + patch + build, nil - - default: - // vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z-pre - // vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z-pre+incompatible - if !strings.HasSuffix(base, ".0") { - panic(`base from parsePseudoVersion missing ".0" before date: ` + base) - } - return strings.TrimSuffix(base, ".0") + build, nil - } -} - -var errPseudoSyntax = errors.New("syntax error") - -func parsePseudoVersion(v string) (base, timestamp, rev, build string, err error) { - if !IsPseudoVersion(v) { - return "", "", "", "", &InvalidVersionError{ - Version: v, - Pseudo: true, - Err: errPseudoSyntax, - } - } - build = semver.Build(v) - v = strings.TrimSuffix(v, build) - j := strings.LastIndex(v, "-") - v, rev = v[:j], v[j+1:] - i := strings.LastIndex(v, "-") - if j := strings.LastIndex(v, "."); j > i { - base = v[:j] // "vX.Y.Z-pre.0" or "vX.Y.(Z+1)-0" - timestamp = v[j+1:] - } else { - base = v[:i] // "vX.0.0" - timestamp = v[i+1:] - } - return base, timestamp, rev, build, nil -} diff --git a/vendor/golang.org/x/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go deleted file mode 100644 index 9a2dfd33..00000000 --- a/vendor/golang.org/x/mod/semver/semver.go +++ /dev/null @@ -1,401 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package semver implements comparison of semantic version strings. -// In this package, semantic version strings must begin with a leading "v", -// as in "v1.0.0". -// -// The general form of a semantic version string accepted by this package is -// -// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] -// -// where square brackets indicate optional parts of the syntax; -// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; -// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers -// using only alphanumeric characters and hyphens; and -// all-numeric PRERELEASE identifiers must not have leading zeros. -// -// This package follows Semantic Versioning 2.0.0 (see semver.org) -// with two exceptions. First, it requires the "v" prefix. Second, it recognizes -// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) -// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. -package semver - -import "sort" - -// parsed returns the parsed form of a semantic version string. -type parsed struct { - major string - minor string - patch string - short string - prerelease string - build string -} - -// IsValid reports whether v is a valid semantic version string. -func IsValid(v string) bool { - _, ok := parse(v) - return ok -} - -// Canonical returns the canonical formatting of the semantic version v. -// It fills in any missing .MINOR or .PATCH and discards build metadata. -// Two semantic versions compare equal only if their canonical formattings -// are identical strings. -// The canonical invalid semantic version is the empty string. -func Canonical(v string) string { - p, ok := parse(v) - if !ok { - return "" - } - if p.build != "" { - return v[:len(v)-len(p.build)] - } - if p.short != "" { - return v + p.short - } - return v -} - -// Major returns the major version prefix of the semantic version v. -// For example, Major("v2.1.0") == "v2". -// If v is an invalid semantic version string, Major returns the empty string. -func Major(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return v[:1+len(pv.major)] -} - -// MajorMinor returns the major.minor version prefix of the semantic version v. -// For example, MajorMinor("v2.1.0") == "v2.1". -// If v is an invalid semantic version string, MajorMinor returns the empty string. -func MajorMinor(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - i := 1 + len(pv.major) - if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { - return v[:j] - } - return v[:i] + "." + pv.minor -} - -// Prerelease returns the prerelease suffix of the semantic version v. -// For example, Prerelease("v2.1.0-pre+meta") == "-pre". -// If v is an invalid semantic version string, Prerelease returns the empty string. -func Prerelease(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return pv.prerelease -} - -// Build returns the build suffix of the semantic version v. -// For example, Build("v2.1.0+meta") == "+meta". -// If v is an invalid semantic version string, Build returns the empty string. -func Build(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return pv.build -} - -// Compare returns an integer comparing two versions according to -// semantic version precedence. -// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. -// -// An invalid semantic version string is considered less than a valid one. -// All invalid semantic version strings compare equal to each other. -func Compare(v, w string) int { - pv, ok1 := parse(v) - pw, ok2 := parse(w) - if !ok1 && !ok2 { - return 0 - } - if !ok1 { - return -1 - } - if !ok2 { - return +1 - } - if c := compareInt(pv.major, pw.major); c != 0 { - return c - } - if c := compareInt(pv.minor, pw.minor); c != 0 { - return c - } - if c := compareInt(pv.patch, pw.patch); c != 0 { - return c - } - return comparePrerelease(pv.prerelease, pw.prerelease) -} - -// Max canonicalizes its arguments and then returns the version string -// that compares greater. -// -// Deprecated: use [Compare] instead. In most cases, returning a canonicalized -// version is not expected or desired. -func Max(v, w string) string { - v = Canonical(v) - w = Canonical(w) - if Compare(v, w) > 0 { - return v - } - return w -} - -// ByVersion implements [sort.Interface] for sorting semantic version strings. -type ByVersion []string - -func (vs ByVersion) Len() int { return len(vs) } -func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } -func (vs ByVersion) Less(i, j int) bool { - cmp := Compare(vs[i], vs[j]) - if cmp != 0 { - return cmp < 0 - } - return vs[i] < vs[j] -} - -// Sort sorts a list of semantic version strings using [ByVersion]. -func Sort(list []string) { - sort.Sort(ByVersion(list)) -} - -func parse(v string) (p parsed, ok bool) { - if v == "" || v[0] != 'v' { - return - } - p.major, v, ok = parseInt(v[1:]) - if !ok { - return - } - if v == "" { - p.minor = "0" - p.patch = "0" - p.short = ".0.0" - return - } - if v[0] != '.' { - ok = false - return - } - p.minor, v, ok = parseInt(v[1:]) - if !ok { - return - } - if v == "" { - p.patch = "0" - p.short = ".0" - return - } - if v[0] != '.' { - ok = false - return - } - p.patch, v, ok = parseInt(v[1:]) - if !ok { - return - } - if len(v) > 0 && v[0] == '-' { - p.prerelease, v, ok = parsePrerelease(v) - if !ok { - return - } - } - if len(v) > 0 && v[0] == '+' { - p.build, v, ok = parseBuild(v) - if !ok { - return - } - } - if v != "" { - ok = false - return - } - ok = true - return -} - -func parseInt(v string) (t, rest string, ok bool) { - if v == "" { - return - } - if v[0] < '0' || '9' < v[0] { - return - } - i := 1 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - if v[0] == '0' && i != 1 { - return - } - return v[:i], v[i:], true -} - -func parsePrerelease(v string) (t, rest string, ok bool) { - // "A pre-release version MAY be denoted by appending a hyphen and - // a series of dot separated identifiers immediately following the patch version. - // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. - // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." - if v == "" || v[0] != '-' { - return - } - i := 1 - start := 1 - for i < len(v) && v[i] != '+' { - if !isIdentChar(v[i]) && v[i] != '.' { - return - } - if v[i] == '.' { - if start == i || isBadNum(v[start:i]) { - return - } - start = i + 1 - } - i++ - } - if start == i || isBadNum(v[start:i]) { - return - } - return v[:i], v[i:], true -} - -func parseBuild(v string) (t, rest string, ok bool) { - if v == "" || v[0] != '+' { - return - } - i := 1 - start := 1 - for i < len(v) { - if !isIdentChar(v[i]) && v[i] != '.' { - return - } - if v[i] == '.' { - if start == i { - return - } - start = i + 1 - } - i++ - } - if start == i { - return - } - return v[:i], v[i:], true -} - -func isIdentChar(c byte) bool { - return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' -} - -func isBadNum(v string) bool { - i := 0 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - return i == len(v) && i > 1 && v[0] == '0' -} - -func isNum(v string) bool { - i := 0 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - return i == len(v) -} - -func compareInt(x, y string) int { - if x == y { - return 0 - } - if len(x) < len(y) { - return -1 - } - if len(x) > len(y) { - return +1 - } - if x < y { - return -1 - } else { - return +1 - } -} - -func comparePrerelease(x, y string) int { - // "When major, minor, and patch are equal, a pre-release version has - // lower precedence than a normal version. - // Example: 1.0.0-alpha < 1.0.0. - // Precedence for two pre-release versions with the same major, minor, - // and patch version MUST be determined by comparing each dot separated - // identifier from left to right until a difference is found as follows: - // identifiers consisting of only digits are compared numerically and - // identifiers with letters or hyphens are compared lexically in ASCII - // sort order. Numeric identifiers always have lower precedence than - // non-numeric identifiers. A larger set of pre-release fields has a - // higher precedence than a smaller set, if all of the preceding - // identifiers are equal. - // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < - // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." - if x == y { - return 0 - } - if x == "" { - return +1 - } - if y == "" { - return -1 - } - for x != "" && y != "" { - x = x[1:] // skip - or . - y = y[1:] // skip - or . - var dx, dy string - dx, x = nextIdent(x) - dy, y = nextIdent(y) - if dx != dy { - ix := isNum(dx) - iy := isNum(dy) - if ix != iy { - if ix { - return -1 - } else { - return +1 - } - } - if ix { - if len(dx) < len(dy) { - return -1 - } - if len(dx) > len(dy) { - return +1 - } - } - if dx < dy { - return -1 - } else { - return +1 - } - } - } - if x == "" { - return -1 - } else { - return +1 - } -} - -func nextIdent(x string) (dx, rest string) { - i := 0 - for i < len(x) && x[i] != '.' { - i++ - } - return x[:i], x[i:] -} diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE deleted file mode 100644 index 6a66aea5..00000000 --- a/vendor/golang.org/x/tools/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS deleted file mode 100644 index 73309904..00000000 --- a/vendor/golang.org/x/tools/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go deleted file mode 100644 index 2c4c4e23..00000000 --- a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go +++ /dev/null @@ -1,634 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package astutil - -// This file defines utilities for working with source positions. - -import ( - "fmt" - "go/ast" - "go/token" - "sort" -) - -// PathEnclosingInterval returns the node that encloses the source -// interval [start, end), and all its ancestors up to the AST root. -// -// The definition of "enclosing" used by this function considers -// additional whitespace abutting a node to be enclosed by it. -// In this example: -// -// z := x + y // add them -// <-A-> -// <----B-----> -// -// the ast.BinaryExpr(+) node is considered to enclose interval B -// even though its [Pos()..End()) is actually only interval A. -// This behaviour makes user interfaces more tolerant of imperfect -// input. -// -// This function treats tokens as nodes, though they are not included -// in the result. e.g. PathEnclosingInterval("+") returns the -// enclosing ast.BinaryExpr("x + y"). -// -// If start==end, the 1-char interval following start is used instead. -// -// The 'exact' result is true if the interval contains only path[0] -// and perhaps some adjacent whitespace. It is false if the interval -// overlaps multiple children of path[0], or if it contains only -// interior whitespace of path[0]. -// In this example: -// -// z := x + y // add them -// <--C--> <---E--> -// ^ -// D -// -// intervals C, D and E are inexact. C is contained by the -// z-assignment statement, because it spans three of its children (:=, -// x, +). So too is the 1-char interval D, because it contains only -// interior whitespace of the assignment. E is considered interior -// whitespace of the BlockStmt containing the assignment. -// -// The resulting path is never empty; it always contains at least the -// 'root' *ast.File. Ideally PathEnclosingInterval would reject -// intervals that lie wholly or partially outside the range of the -// file, but unfortunately ast.File records only the token.Pos of -// the 'package' keyword, but not of the start of the file itself. -func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) { - // fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging - - // Precondition: node.[Pos..End) and adjoining whitespace contain [start, end). - var visit func(node ast.Node) bool - visit = func(node ast.Node) bool { - path = append(path, node) - - nodePos := node.Pos() - nodeEnd := node.End() - - // fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging - - // Intersect [start, end) with interval of node. - if start < nodePos { - start = nodePos - } - if end > nodeEnd { - end = nodeEnd - } - - // Find sole child that contains [start, end). - children := childrenOf(node) - l := len(children) - for i, child := range children { - // [childPos, childEnd) is unaugmented interval of child. - childPos := child.Pos() - childEnd := child.End() - - // [augPos, augEnd) is whitespace-augmented interval of child. - augPos := childPos - augEnd := childEnd - if i > 0 { - augPos = children[i-1].End() // start of preceding whitespace - } - if i < l-1 { - nextChildPos := children[i+1].Pos() - // Does [start, end) lie between child and next child? - if start >= augEnd && end <= nextChildPos { - return false // inexact match - } - augEnd = nextChildPos // end of following whitespace - } - - // fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n", - // i, augPos, augEnd, start, end) // debugging - - // Does augmented child strictly contain [start, end)? - if augPos <= start && end <= augEnd { - _, isToken := child.(tokenNode) - return isToken || visit(child) - } - - // Does [start, end) overlap multiple children? - // i.e. left-augmented child contains start - // but LR-augmented child does not contain end. - if start < childEnd && end > augEnd { - break - } - } - - // No single child contained [start, end), - // so node is the result. Is it exact? - - // (It's tempting to put this condition before the - // child loop, but it gives the wrong result in the - // case where a node (e.g. ExprStmt) and its sole - // child have equal intervals.) - if start == nodePos && end == nodeEnd { - return true // exact match - } - - return false // inexact: overlaps multiple children - } - - // Ensure [start,end) is nondecreasing. - if start > end { - start, end = end, start - } - - if start < root.End() && end > root.Pos() { - if start == end { - end = start + 1 // empty interval => interval of size 1 - } - exact = visit(root) - - // Reverse the path: - for i, l := 0, len(path); i < l/2; i++ { - path[i], path[l-1-i] = path[l-1-i], path[i] - } - } else { - // Selection lies within whitespace preceding the - // first (or following the last) declaration in the file. - // The result nonetheless always includes the ast.File. - path = append(path, root) - } - - return -} - -// tokenNode is a dummy implementation of ast.Node for a single token. -// They are used transiently by PathEnclosingInterval but never escape -// this package. -type tokenNode struct { - pos token.Pos - end token.Pos -} - -func (n tokenNode) Pos() token.Pos { - return n.pos -} - -func (n tokenNode) End() token.Pos { - return n.end -} - -func tok(pos token.Pos, len int) ast.Node { - return tokenNode{pos, pos + token.Pos(len)} -} - -// childrenOf returns the direct non-nil children of ast.Node n. -// It may include fake ast.Node implementations for bare tokens. -// it is not safe to call (e.g.) ast.Walk on such nodes. -func childrenOf(n ast.Node) []ast.Node { - var children []ast.Node - - // First add nodes for all true subtrees. - ast.Inspect(n, func(node ast.Node) bool { - if node == n { // push n - return true // recur - } - if node != nil { // push child - children = append(children, node) - } - return false // no recursion - }) - - // Then add fake Nodes for bare tokens. - switch n := n.(type) { - case *ast.ArrayType: - children = append(children, - tok(n.Lbrack, len("[")), - tok(n.Elt.End(), len("]"))) - - case *ast.AssignStmt: - children = append(children, - tok(n.TokPos, len(n.Tok.String()))) - - case *ast.BasicLit: - children = append(children, - tok(n.ValuePos, len(n.Value))) - - case *ast.BinaryExpr: - children = append(children, tok(n.OpPos, len(n.Op.String()))) - - case *ast.BlockStmt: - children = append(children, - tok(n.Lbrace, len("{")), - tok(n.Rbrace, len("}"))) - - case *ast.BranchStmt: - children = append(children, - tok(n.TokPos, len(n.Tok.String()))) - - case *ast.CallExpr: - children = append(children, - tok(n.Lparen, len("(")), - tok(n.Rparen, len(")"))) - if n.Ellipsis != 0 { - children = append(children, tok(n.Ellipsis, len("..."))) - } - - case *ast.CaseClause: - if n.List == nil { - children = append(children, - tok(n.Case, len("default"))) - } else { - children = append(children, - tok(n.Case, len("case"))) - } - children = append(children, tok(n.Colon, len(":"))) - - case *ast.ChanType: - switch n.Dir { - case ast.RECV: - children = append(children, tok(n.Begin, len("<-chan"))) - case ast.SEND: - children = append(children, tok(n.Begin, len("chan<-"))) - case ast.RECV | ast.SEND: - children = append(children, tok(n.Begin, len("chan"))) - } - - case *ast.CommClause: - if n.Comm == nil { - children = append(children, - tok(n.Case, len("default"))) - } else { - children = append(children, - tok(n.Case, len("case"))) - } - children = append(children, tok(n.Colon, len(":"))) - - case *ast.Comment: - // nop - - case *ast.CommentGroup: - // nop - - case *ast.CompositeLit: - children = append(children, - tok(n.Lbrace, len("{")), - tok(n.Rbrace, len("{"))) - - case *ast.DeclStmt: - // nop - - case *ast.DeferStmt: - children = append(children, - tok(n.Defer, len("defer"))) - - case *ast.Ellipsis: - children = append(children, - tok(n.Ellipsis, len("..."))) - - case *ast.EmptyStmt: - // nop - - case *ast.ExprStmt: - // nop - - case *ast.Field: - // TODO(adonovan): Field.{Doc,Comment,Tag}? - - case *ast.FieldList: - children = append(children, - tok(n.Opening, len("(")), // or len("[") - tok(n.Closing, len(")"))) // or len("]") - - case *ast.File: - // TODO test: Doc - children = append(children, - tok(n.Package, len("package"))) - - case *ast.ForStmt: - children = append(children, - tok(n.For, len("for"))) - - case *ast.FuncDecl: - // TODO(adonovan): FuncDecl.Comment? - - // Uniquely, FuncDecl breaks the invariant that - // preorder traversal yields tokens in lexical order: - // in fact, FuncDecl.Recv precedes FuncDecl.Type.Func. - // - // As a workaround, we inline the case for FuncType - // here and order things correctly. - // - children = nil // discard ast.Walk(FuncDecl) info subtrees - children = append(children, tok(n.Type.Func, len("func"))) - if n.Recv != nil { - children = append(children, n.Recv) - } - children = append(children, n.Name) - if tparams := n.Type.TypeParams; tparams != nil { - children = append(children, tparams) - } - if n.Type.Params != nil { - children = append(children, n.Type.Params) - } - if n.Type.Results != nil { - children = append(children, n.Type.Results) - } - if n.Body != nil { - children = append(children, n.Body) - } - - case *ast.FuncLit: - // nop - - case *ast.FuncType: - if n.Func != 0 { - children = append(children, - tok(n.Func, len("func"))) - } - - case *ast.GenDecl: - children = append(children, - tok(n.TokPos, len(n.Tok.String()))) - if n.Lparen != 0 { - children = append(children, - tok(n.Lparen, len("(")), - tok(n.Rparen, len(")"))) - } - - case *ast.GoStmt: - children = append(children, - tok(n.Go, len("go"))) - - case *ast.Ident: - children = append(children, - tok(n.NamePos, len(n.Name))) - - case *ast.IfStmt: - children = append(children, - tok(n.If, len("if"))) - - case *ast.ImportSpec: - // TODO(adonovan): ImportSpec.{Doc,EndPos}? - - case *ast.IncDecStmt: - children = append(children, - tok(n.TokPos, len(n.Tok.String()))) - - case *ast.IndexExpr: - children = append(children, - tok(n.Lbrack, len("[")), - tok(n.Rbrack, len("]"))) - - case *ast.IndexListExpr: - children = append(children, - tok(n.Lbrack, len("[")), - tok(n.Rbrack, len("]"))) - - case *ast.InterfaceType: - children = append(children, - tok(n.Interface, len("interface"))) - - case *ast.KeyValueExpr: - children = append(children, - tok(n.Colon, len(":"))) - - case *ast.LabeledStmt: - children = append(children, - tok(n.Colon, len(":"))) - - case *ast.MapType: - children = append(children, - tok(n.Map, len("map"))) - - case *ast.ParenExpr: - children = append(children, - tok(n.Lparen, len("(")), - tok(n.Rparen, len(")"))) - - case *ast.RangeStmt: - children = append(children, - tok(n.For, len("for")), - tok(n.TokPos, len(n.Tok.String()))) - - case *ast.ReturnStmt: - children = append(children, - tok(n.Return, len("return"))) - - case *ast.SelectStmt: - children = append(children, - tok(n.Select, len("select"))) - - case *ast.SelectorExpr: - // nop - - case *ast.SendStmt: - children = append(children, - tok(n.Arrow, len("<-"))) - - case *ast.SliceExpr: - children = append(children, - tok(n.Lbrack, len("[")), - tok(n.Rbrack, len("]"))) - - case *ast.StarExpr: - children = append(children, tok(n.Star, len("*"))) - - case *ast.StructType: - children = append(children, tok(n.Struct, len("struct"))) - - case *ast.SwitchStmt: - children = append(children, tok(n.Switch, len("switch"))) - - case *ast.TypeAssertExpr: - children = append(children, - tok(n.Lparen-1, len(".")), - tok(n.Lparen, len("(")), - tok(n.Rparen, len(")"))) - - case *ast.TypeSpec: - // TODO(adonovan): TypeSpec.{Doc,Comment}? - - case *ast.TypeSwitchStmt: - children = append(children, tok(n.Switch, len("switch"))) - - case *ast.UnaryExpr: - children = append(children, tok(n.OpPos, len(n.Op.String()))) - - case *ast.ValueSpec: - // TODO(adonovan): ValueSpec.{Doc,Comment}? - - case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt: - // nop - } - - // TODO(adonovan): opt: merge the logic of ast.Inspect() into - // the switch above so we can make interleaved callbacks for - // both Nodes and Tokens in the right order and avoid the need - // to sort. - sort.Sort(byPos(children)) - - return children -} - -type byPos []ast.Node - -func (sl byPos) Len() int { - return len(sl) -} -func (sl byPos) Less(i, j int) bool { - return sl[i].Pos() < sl[j].Pos() -} -func (sl byPos) Swap(i, j int) { - sl[i], sl[j] = sl[j], sl[i] -} - -// NodeDescription returns a description of the concrete type of n suitable -// for a user interface. -// -// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident, -// StarExpr) we could be much more specific given the path to the AST -// root. Perhaps we should do that. -func NodeDescription(n ast.Node) string { - switch n := n.(type) { - case *ast.ArrayType: - return "array type" - case *ast.AssignStmt: - return "assignment" - case *ast.BadDecl: - return "bad declaration" - case *ast.BadExpr: - return "bad expression" - case *ast.BadStmt: - return "bad statement" - case *ast.BasicLit: - return "basic literal" - case *ast.BinaryExpr: - return fmt.Sprintf("binary %s operation", n.Op) - case *ast.BlockStmt: - return "block" - case *ast.BranchStmt: - switch n.Tok { - case token.BREAK: - return "break statement" - case token.CONTINUE: - return "continue statement" - case token.GOTO: - return "goto statement" - case token.FALLTHROUGH: - return "fall-through statement" - } - case *ast.CallExpr: - if len(n.Args) == 1 && !n.Ellipsis.IsValid() { - return "function call (or conversion)" - } - return "function call" - case *ast.CaseClause: - return "case clause" - case *ast.ChanType: - return "channel type" - case *ast.CommClause: - return "communication clause" - case *ast.Comment: - return "comment" - case *ast.CommentGroup: - return "comment group" - case *ast.CompositeLit: - return "composite literal" - case *ast.DeclStmt: - return NodeDescription(n.Decl) + " statement" - case *ast.DeferStmt: - return "defer statement" - case *ast.Ellipsis: - return "ellipsis" - case *ast.EmptyStmt: - return "empty statement" - case *ast.ExprStmt: - return "expression statement" - case *ast.Field: - // Can be any of these: - // struct {x, y int} -- struct field(s) - // struct {T} -- anon struct field - // interface {I} -- interface embedding - // interface {f()} -- interface method - // func (A) func(B) C -- receiver, param(s), result(s) - return "field/method/parameter" - case *ast.FieldList: - return "field/method/parameter list" - case *ast.File: - return "source file" - case *ast.ForStmt: - return "for loop" - case *ast.FuncDecl: - return "function declaration" - case *ast.FuncLit: - return "function literal" - case *ast.FuncType: - return "function type" - case *ast.GenDecl: - switch n.Tok { - case token.IMPORT: - return "import declaration" - case token.CONST: - return "constant declaration" - case token.TYPE: - return "type declaration" - case token.VAR: - return "variable declaration" - } - case *ast.GoStmt: - return "go statement" - case *ast.Ident: - return "identifier" - case *ast.IfStmt: - return "if statement" - case *ast.ImportSpec: - return "import specification" - case *ast.IncDecStmt: - if n.Tok == token.INC { - return "increment statement" - } - return "decrement statement" - case *ast.IndexExpr: - return "index expression" - case *ast.IndexListExpr: - return "index list expression" - case *ast.InterfaceType: - return "interface type" - case *ast.KeyValueExpr: - return "key/value association" - case *ast.LabeledStmt: - return "statement label" - case *ast.MapType: - return "map type" - case *ast.Package: - return "package" - case *ast.ParenExpr: - return "parenthesized " + NodeDescription(n.X) - case *ast.RangeStmt: - return "range loop" - case *ast.ReturnStmt: - return "return statement" - case *ast.SelectStmt: - return "select statement" - case *ast.SelectorExpr: - return "selector" - case *ast.SendStmt: - return "channel send" - case *ast.SliceExpr: - return "slice expression" - case *ast.StarExpr: - return "*-operation" // load/store expr or pointer type - case *ast.StructType: - return "struct type" - case *ast.SwitchStmt: - return "switch statement" - case *ast.TypeAssertExpr: - return "type assertion" - case *ast.TypeSpec: - return "type specification" - case *ast.TypeSwitchStmt: - return "type switch" - case *ast.UnaryExpr: - return fmt.Sprintf("unary %s operation", n.Op) - case *ast.ValueSpec: - return "value specification" - - } - panic(fmt.Sprintf("unexpected node type: %T", n)) -} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go deleted file mode 100644 index 18d1adb0..00000000 --- a/vendor/golang.org/x/tools/go/ast/astutil/imports.go +++ /dev/null @@ -1,485 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package astutil contains common utilities for working with the Go AST. -package astutil // import "golang.org/x/tools/go/ast/astutil" - -import ( - "fmt" - "go/ast" - "go/token" - "strconv" - "strings" -) - -// AddImport adds the import path to the file f, if absent. -func AddImport(fset *token.FileSet, f *ast.File, path string) (added bool) { - return AddNamedImport(fset, f, "", path) -} - -// AddNamedImport adds the import with the given name and path to the file f, if absent. -// If name is not empty, it is used to rename the import. -// -// For example, calling -// -// AddNamedImport(fset, f, "pathpkg", "path") -// -// adds -// -// import pathpkg "path" -func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added bool) { - if imports(f, name, path) { - return false - } - - newImport := &ast.ImportSpec{ - Path: &ast.BasicLit{ - Kind: token.STRING, - Value: strconv.Quote(path), - }, - } - if name != "" { - newImport.Name = &ast.Ident{Name: name} - } - - // Find an import decl to add to. - // The goal is to find an existing import - // whose import path has the longest shared - // prefix with path. - var ( - bestMatch = -1 // length of longest shared prefix - lastImport = -1 // index in f.Decls of the file's final import decl - impDecl *ast.GenDecl // import decl containing the best match - impIndex = -1 // spec index in impDecl containing the best match - - isThirdPartyPath = isThirdParty(path) - ) - for i, decl := range f.Decls { - gen, ok := decl.(*ast.GenDecl) - if ok && gen.Tok == token.IMPORT { - lastImport = i - // Do not add to import "C", to avoid disrupting the - // association with its doc comment, breaking cgo. - if declImports(gen, "C") { - continue - } - - // Match an empty import decl if that's all that is available. - if len(gen.Specs) == 0 && bestMatch == -1 { - impDecl = gen - } - - // Compute longest shared prefix with imports in this group and find best - // matched import spec. - // 1. Always prefer import spec with longest shared prefix. - // 2. While match length is 0, - // - for stdlib package: prefer first import spec. - // - for third party package: prefer first third party import spec. - // We cannot use last import spec as best match for third party package - // because grouped imports are usually placed last by goimports -local - // flag. - // See issue #19190. - seenAnyThirdParty := false - for j, spec := range gen.Specs { - impspec := spec.(*ast.ImportSpec) - p := importPath(impspec) - n := matchLen(p, path) - if n > bestMatch || (bestMatch == 0 && !seenAnyThirdParty && isThirdPartyPath) { - bestMatch = n - impDecl = gen - impIndex = j - } - seenAnyThirdParty = seenAnyThirdParty || isThirdParty(p) - } - } - } - - // If no import decl found, add one after the last import. - if impDecl == nil { - impDecl = &ast.GenDecl{ - Tok: token.IMPORT, - } - if lastImport >= 0 { - impDecl.TokPos = f.Decls[lastImport].End() - } else { - // There are no existing imports. - // Our new import, preceded by a blank line, goes after the package declaration - // and after the comment, if any, that starts on the same line as the - // package declaration. - impDecl.TokPos = f.Package - - file := fset.File(f.Package) - pkgLine := file.Line(f.Package) - for _, c := range f.Comments { - if file.Line(c.Pos()) > pkgLine { - break - } - // +2 for a blank line - impDecl.TokPos = c.End() + 2 - } - } - f.Decls = append(f.Decls, nil) - copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:]) - f.Decls[lastImport+1] = impDecl - } - - // Insert new import at insertAt. - insertAt := 0 - if impIndex >= 0 { - // insert after the found import - insertAt = impIndex + 1 - } - impDecl.Specs = append(impDecl.Specs, nil) - copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:]) - impDecl.Specs[insertAt] = newImport - pos := impDecl.Pos() - if insertAt > 0 { - // If there is a comment after an existing import, preserve the comment - // position by adding the new import after the comment. - if spec, ok := impDecl.Specs[insertAt-1].(*ast.ImportSpec); ok && spec.Comment != nil { - pos = spec.Comment.End() - } else { - // Assign same position as the previous import, - // so that the sorter sees it as being in the same block. - pos = impDecl.Specs[insertAt-1].Pos() - } - } - if newImport.Name != nil { - newImport.Name.NamePos = pos - } - newImport.Path.ValuePos = pos - newImport.EndPos = pos - - // Clean up parens. impDecl contains at least one spec. - if len(impDecl.Specs) == 1 { - // Remove unneeded parens. - impDecl.Lparen = token.NoPos - } else if !impDecl.Lparen.IsValid() { - // impDecl needs parens added. - impDecl.Lparen = impDecl.Specs[0].Pos() - } - - f.Imports = append(f.Imports, newImport) - - if len(f.Decls) <= 1 { - return true - } - - // Merge all the import declarations into the first one. - var first *ast.GenDecl - for i := 0; i < len(f.Decls); i++ { - decl := f.Decls[i] - gen, ok := decl.(*ast.GenDecl) - if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") { - continue - } - if first == nil { - first = gen - continue // Don't touch the first one. - } - // We now know there is more than one package in this import - // declaration. Ensure that it ends up parenthesized. - first.Lparen = first.Pos() - // Move the imports of the other import declaration to the first one. - for _, spec := range gen.Specs { - spec.(*ast.ImportSpec).Path.ValuePos = first.Pos() - first.Specs = append(first.Specs, spec) - } - f.Decls = append(f.Decls[:i], f.Decls[i+1:]...) - i-- - } - - return true -} - -func isThirdParty(importPath string) bool { - // Third party package import path usually contains "." (".com", ".org", ...) - // This logic is taken from golang.org/x/tools/imports package. - return strings.Contains(importPath, ".") -} - -// DeleteImport deletes the import path from the file f, if present. -// If there are duplicate import declarations, all matching ones are deleted. -func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) { - return DeleteNamedImport(fset, f, "", path) -} - -// DeleteNamedImport deletes the import with the given name and path from the file f, if present. -// If there are duplicate import declarations, all matching ones are deleted. -func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) { - var delspecs []*ast.ImportSpec - var delcomments []*ast.CommentGroup - - // Find the import nodes that import path, if any. - for i := 0; i < len(f.Decls); i++ { - decl := f.Decls[i] - gen, ok := decl.(*ast.GenDecl) - if !ok || gen.Tok != token.IMPORT { - continue - } - for j := 0; j < len(gen.Specs); j++ { - spec := gen.Specs[j] - impspec := spec.(*ast.ImportSpec) - if importName(impspec) != name || importPath(impspec) != path { - continue - } - - // We found an import spec that imports path. - // Delete it. - delspecs = append(delspecs, impspec) - deleted = true - copy(gen.Specs[j:], gen.Specs[j+1:]) - gen.Specs = gen.Specs[:len(gen.Specs)-1] - - // If this was the last import spec in this decl, - // delete the decl, too. - if len(gen.Specs) == 0 { - copy(f.Decls[i:], f.Decls[i+1:]) - f.Decls = f.Decls[:len(f.Decls)-1] - i-- - break - } else if len(gen.Specs) == 1 { - if impspec.Doc != nil { - delcomments = append(delcomments, impspec.Doc) - } - if impspec.Comment != nil { - delcomments = append(delcomments, impspec.Comment) - } - for _, cg := range f.Comments { - // Found comment on the same line as the import spec. - if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line { - delcomments = append(delcomments, cg) - break - } - } - - spec := gen.Specs[0].(*ast.ImportSpec) - - // Move the documentation right after the import decl. - if spec.Doc != nil { - for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Doc.Pos()).Line { - fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line) - } - } - for _, cg := range f.Comments { - if cg.End() < spec.Pos() && fset.Position(cg.End()).Line == fset.Position(spec.Pos()).Line { - for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Pos()).Line { - fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line) - } - break - } - } - } - if j > 0 { - lastImpspec := gen.Specs[j-1].(*ast.ImportSpec) - lastLine := fset.PositionFor(lastImpspec.Path.ValuePos, false).Line - line := fset.PositionFor(impspec.Path.ValuePos, false).Line - - // We deleted an entry but now there may be - // a blank line-sized hole where the import was. - if line-lastLine > 1 || !gen.Rparen.IsValid() { - // There was a blank line immediately preceding the deleted import, - // so there's no need to close the hole. The right parenthesis is - // invalid after AddImport to an import statement without parenthesis. - // Do nothing. - } else if line != fset.File(gen.Rparen).LineCount() { - // There was no blank line. Close the hole. - fset.File(gen.Rparen).MergeLine(line) - } - } - j-- - } - } - - // Delete imports from f.Imports. - for i := 0; i < len(f.Imports); i++ { - imp := f.Imports[i] - for j, del := range delspecs { - if imp == del { - copy(f.Imports[i:], f.Imports[i+1:]) - f.Imports = f.Imports[:len(f.Imports)-1] - copy(delspecs[j:], delspecs[j+1:]) - delspecs = delspecs[:len(delspecs)-1] - i-- - break - } - } - } - - // Delete comments from f.Comments. - for i := 0; i < len(f.Comments); i++ { - cg := f.Comments[i] - for j, del := range delcomments { - if cg == del { - copy(f.Comments[i:], f.Comments[i+1:]) - f.Comments = f.Comments[:len(f.Comments)-1] - copy(delcomments[j:], delcomments[j+1:]) - delcomments = delcomments[:len(delcomments)-1] - i-- - break - } - } - } - - if len(delspecs) > 0 { - panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs)) - } - - return -} - -// RewriteImport rewrites any import of path oldPath to path newPath. -func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) { - for _, imp := range f.Imports { - if importPath(imp) == oldPath { - rewrote = true - // record old End, because the default is to compute - // it using the length of imp.Path.Value. - imp.EndPos = imp.End() - imp.Path.Value = strconv.Quote(newPath) - } - } - return -} - -// UsesImport reports whether a given import is used. -func UsesImport(f *ast.File, path string) (used bool) { - spec := importSpec(f, path) - if spec == nil { - return - } - - name := spec.Name.String() - switch name { - case "": - // If the package name is not explicitly specified, - // make an educated guess. This is not guaranteed to be correct. - lastSlash := strings.LastIndex(path, "/") - if lastSlash == -1 { - name = path - } else { - name = path[lastSlash+1:] - } - case "_", ".": - // Not sure if this import is used - err on the side of caution. - return true - } - - ast.Walk(visitFn(func(n ast.Node) { - sel, ok := n.(*ast.SelectorExpr) - if ok && isTopName(sel.X, name) { - used = true - } - }), f) - - return -} - -type visitFn func(node ast.Node) - -func (fn visitFn) Visit(node ast.Node) ast.Visitor { - fn(node) - return fn -} - -// imports reports whether f has an import with the specified name and path. -func imports(f *ast.File, name, path string) bool { - for _, s := range f.Imports { - if importName(s) == name && importPath(s) == path { - return true - } - } - return false -} - -// importSpec returns the import spec if f imports path, -// or nil otherwise. -func importSpec(f *ast.File, path string) *ast.ImportSpec { - for _, s := range f.Imports { - if importPath(s) == path { - return s - } - } - return nil -} - -// importName returns the name of s, -// or "" if the import is not named. -func importName(s *ast.ImportSpec) string { - if s.Name == nil { - return "" - } - return s.Name.Name -} - -// importPath returns the unquoted import path of s, -// or "" if the path is not properly quoted. -func importPath(s *ast.ImportSpec) string { - t, err := strconv.Unquote(s.Path.Value) - if err != nil { - return "" - } - return t -} - -// declImports reports whether gen contains an import of path. -func declImports(gen *ast.GenDecl, path string) bool { - if gen.Tok != token.IMPORT { - return false - } - for _, spec := range gen.Specs { - impspec := spec.(*ast.ImportSpec) - if importPath(impspec) == path { - return true - } - } - return false -} - -// matchLen returns the length of the longest path segment prefix shared by x and y. -func matchLen(x, y string) int { - n := 0 - for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ { - if x[i] == '/' { - n++ - } - } - return n -} - -// isTopName returns true if n is a top-level unresolved identifier with the given name. -func isTopName(n ast.Expr, name string) bool { - id, ok := n.(*ast.Ident) - return ok && id.Name == name && id.Obj == nil -} - -// Imports returns the file imports grouped by paragraph. -func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec { - var groups [][]*ast.ImportSpec - - for _, decl := range f.Decls { - genDecl, ok := decl.(*ast.GenDecl) - if !ok || genDecl.Tok != token.IMPORT { - break - } - - group := []*ast.ImportSpec{} - - var lastLine int - for _, spec := range genDecl.Specs { - importSpec := spec.(*ast.ImportSpec) - pos := importSpec.Path.ValuePos - line := fset.Position(pos).Line - if lastLine > 0 && pos > 0 && line-lastLine > 1 { - groups = append(groups, group) - group = []*ast.ImportSpec{} - } - group = append(group, importSpec) - lastLine = line - } - groups = append(groups, group) - } - - return groups -} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go deleted file mode 100644 index 58934f76..00000000 --- a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go +++ /dev/null @@ -1,486 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package astutil - -import ( - "fmt" - "go/ast" - "reflect" - "sort" -) - -// An ApplyFunc is invoked by Apply for each node n, even if n is nil, -// before and/or after the node's children, using a Cursor describing -// the current node and providing operations on it. -// -// The return value of ApplyFunc controls the syntax tree traversal. -// See Apply for details. -type ApplyFunc func(*Cursor) bool - -// Apply traverses a syntax tree recursively, starting with root, -// and calling pre and post for each node as described below. -// Apply returns the syntax tree, possibly modified. -// -// If pre is not nil, it is called for each node before the node's -// children are traversed (pre-order). If pre returns false, no -// children are traversed, and post is not called for that node. -// -// If post is not nil, and a prior call of pre didn't return false, -// post is called for each node after its children are traversed -// (post-order). If post returns false, traversal is terminated and -// Apply returns immediately. -// -// Only fields that refer to AST nodes are considered children; -// i.e., token.Pos, Scopes, Objects, and fields of basic types -// (strings, etc.) are ignored. -// -// Children are traversed in the order in which they appear in the -// respective node's struct definition. A package's files are -// traversed in the filenames' alphabetical order. -func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) { - parent := &struct{ ast.Node }{root} - defer func() { - if r := recover(); r != nil && r != abort { - panic(r) - } - result = parent.Node - }() - a := &application{pre: pre, post: post} - a.apply(parent, "Node", nil, root) - return -} - -var abort = new(int) // singleton, to signal termination of Apply - -// A Cursor describes a node encountered during Apply. -// Information about the node and its parent is available -// from the Node, Parent, Name, and Index methods. -// -// If p is a variable of type and value of the current parent node -// c.Parent(), and f is the field identifier with name c.Name(), -// the following invariants hold: -// -// p.f == c.Node() if c.Index() < 0 -// p.f[c.Index()] == c.Node() if c.Index() >= 0 -// -// The methods Replace, Delete, InsertBefore, and InsertAfter -// can be used to change the AST without disrupting Apply. -type Cursor struct { - parent ast.Node - name string - iter *iterator // valid if non-nil - node ast.Node -} - -// Node returns the current Node. -func (c *Cursor) Node() ast.Node { return c.node } - -// Parent returns the parent of the current Node. -func (c *Cursor) Parent() ast.Node { return c.parent } - -// Name returns the name of the parent Node field that contains the current Node. -// If the parent is a *ast.Package and the current Node is a *ast.File, Name returns -// the filename for the current Node. -func (c *Cursor) Name() string { return c.name } - -// Index reports the index >= 0 of the current Node in the slice of Nodes that -// contains it, or a value < 0 if the current Node is not part of a slice. -// The index of the current node changes if InsertBefore is called while -// processing the current node. -func (c *Cursor) Index() int { - if c.iter != nil { - return c.iter.index - } - return -1 -} - -// field returns the current node's parent field value. -func (c *Cursor) field() reflect.Value { - return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name) -} - -// Replace replaces the current Node with n. -// The replacement node is not walked by Apply. -func (c *Cursor) Replace(n ast.Node) { - if _, ok := c.node.(*ast.File); ok { - file, ok := n.(*ast.File) - if !ok { - panic("attempt to replace *ast.File with non-*ast.File") - } - c.parent.(*ast.Package).Files[c.name] = file - return - } - - v := c.field() - if i := c.Index(); i >= 0 { - v = v.Index(i) - } - v.Set(reflect.ValueOf(n)) -} - -// Delete deletes the current Node from its containing slice. -// If the current Node is not part of a slice, Delete panics. -// As a special case, if the current node is a package file, -// Delete removes it from the package's Files map. -func (c *Cursor) Delete() { - if _, ok := c.node.(*ast.File); ok { - delete(c.parent.(*ast.Package).Files, c.name) - return - } - - i := c.Index() - if i < 0 { - panic("Delete node not contained in slice") - } - v := c.field() - l := v.Len() - reflect.Copy(v.Slice(i, l), v.Slice(i+1, l)) - v.Index(l - 1).Set(reflect.Zero(v.Type().Elem())) - v.SetLen(l - 1) - c.iter.step-- -} - -// InsertAfter inserts n after the current Node in its containing slice. -// If the current Node is not part of a slice, InsertAfter panics. -// Apply does not walk n. -func (c *Cursor) InsertAfter(n ast.Node) { - i := c.Index() - if i < 0 { - panic("InsertAfter node not contained in slice") - } - v := c.field() - v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) - l := v.Len() - reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l)) - v.Index(i + 1).Set(reflect.ValueOf(n)) - c.iter.step++ -} - -// InsertBefore inserts n before the current Node in its containing slice. -// If the current Node is not part of a slice, InsertBefore panics. -// Apply will not walk n. -func (c *Cursor) InsertBefore(n ast.Node) { - i := c.Index() - if i < 0 { - panic("InsertBefore node not contained in slice") - } - v := c.field() - v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) - l := v.Len() - reflect.Copy(v.Slice(i+1, l), v.Slice(i, l)) - v.Index(i).Set(reflect.ValueOf(n)) - c.iter.index++ -} - -// application carries all the shared data so we can pass it around cheaply. -type application struct { - pre, post ApplyFunc - cursor Cursor - iter iterator -} - -func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) { - // convert typed nil into untyped nil - if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() { - n = nil - } - - // avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead - saved := a.cursor - a.cursor.parent = parent - a.cursor.name = name - a.cursor.iter = iter - a.cursor.node = n - - if a.pre != nil && !a.pre(&a.cursor) { - a.cursor = saved - return - } - - // walk children - // (the order of the cases matches the order of the corresponding node types in go/ast) - switch n := n.(type) { - case nil: - // nothing to do - - // Comments and fields - case *ast.Comment: - // nothing to do - - case *ast.CommentGroup: - if n != nil { - a.applyList(n, "List") - } - - case *ast.Field: - a.apply(n, "Doc", nil, n.Doc) - a.applyList(n, "Names") - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Tag", nil, n.Tag) - a.apply(n, "Comment", nil, n.Comment) - - case *ast.FieldList: - a.applyList(n, "List") - - // Expressions - case *ast.BadExpr, *ast.Ident, *ast.BasicLit: - // nothing to do - - case *ast.Ellipsis: - a.apply(n, "Elt", nil, n.Elt) - - case *ast.FuncLit: - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Body", nil, n.Body) - - case *ast.CompositeLit: - a.apply(n, "Type", nil, n.Type) - a.applyList(n, "Elts") - - case *ast.ParenExpr: - a.apply(n, "X", nil, n.X) - - case *ast.SelectorExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Sel", nil, n.Sel) - - case *ast.IndexExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Index", nil, n.Index) - - case *ast.IndexListExpr: - a.apply(n, "X", nil, n.X) - a.applyList(n, "Indices") - - case *ast.SliceExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Low", nil, n.Low) - a.apply(n, "High", nil, n.High) - a.apply(n, "Max", nil, n.Max) - - case *ast.TypeAssertExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Type", nil, n.Type) - - case *ast.CallExpr: - a.apply(n, "Fun", nil, n.Fun) - a.applyList(n, "Args") - - case *ast.StarExpr: - a.apply(n, "X", nil, n.X) - - case *ast.UnaryExpr: - a.apply(n, "X", nil, n.X) - - case *ast.BinaryExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Y", nil, n.Y) - - case *ast.KeyValueExpr: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - - // Types - case *ast.ArrayType: - a.apply(n, "Len", nil, n.Len) - a.apply(n, "Elt", nil, n.Elt) - - case *ast.StructType: - a.apply(n, "Fields", nil, n.Fields) - - case *ast.FuncType: - if tparams := n.TypeParams; tparams != nil { - a.apply(n, "TypeParams", nil, tparams) - } - a.apply(n, "Params", nil, n.Params) - a.apply(n, "Results", nil, n.Results) - - case *ast.InterfaceType: - a.apply(n, "Methods", nil, n.Methods) - - case *ast.MapType: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - - case *ast.ChanType: - a.apply(n, "Value", nil, n.Value) - - // Statements - case *ast.BadStmt: - // nothing to do - - case *ast.DeclStmt: - a.apply(n, "Decl", nil, n.Decl) - - case *ast.EmptyStmt: - // nothing to do - - case *ast.LabeledStmt: - a.apply(n, "Label", nil, n.Label) - a.apply(n, "Stmt", nil, n.Stmt) - - case *ast.ExprStmt: - a.apply(n, "X", nil, n.X) - - case *ast.SendStmt: - a.apply(n, "Chan", nil, n.Chan) - a.apply(n, "Value", nil, n.Value) - - case *ast.IncDecStmt: - a.apply(n, "X", nil, n.X) - - case *ast.AssignStmt: - a.applyList(n, "Lhs") - a.applyList(n, "Rhs") - - case *ast.GoStmt: - a.apply(n, "Call", nil, n.Call) - - case *ast.DeferStmt: - a.apply(n, "Call", nil, n.Call) - - case *ast.ReturnStmt: - a.applyList(n, "Results") - - case *ast.BranchStmt: - a.apply(n, "Label", nil, n.Label) - - case *ast.BlockStmt: - a.applyList(n, "List") - - case *ast.IfStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Cond", nil, n.Cond) - a.apply(n, "Body", nil, n.Body) - a.apply(n, "Else", nil, n.Else) - - case *ast.CaseClause: - a.applyList(n, "List") - a.applyList(n, "Body") - - case *ast.SwitchStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Tag", nil, n.Tag) - a.apply(n, "Body", nil, n.Body) - - case *ast.TypeSwitchStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Assign", nil, n.Assign) - a.apply(n, "Body", nil, n.Body) - - case *ast.CommClause: - a.apply(n, "Comm", nil, n.Comm) - a.applyList(n, "Body") - - case *ast.SelectStmt: - a.apply(n, "Body", nil, n.Body) - - case *ast.ForStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Cond", nil, n.Cond) - a.apply(n, "Post", nil, n.Post) - a.apply(n, "Body", nil, n.Body) - - case *ast.RangeStmt: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - a.apply(n, "X", nil, n.X) - a.apply(n, "Body", nil, n.Body) - - // Declarations - case *ast.ImportSpec: - a.apply(n, "Doc", nil, n.Doc) - a.apply(n, "Name", nil, n.Name) - a.apply(n, "Path", nil, n.Path) - a.apply(n, "Comment", nil, n.Comment) - - case *ast.ValueSpec: - a.apply(n, "Doc", nil, n.Doc) - a.applyList(n, "Names") - a.apply(n, "Type", nil, n.Type) - a.applyList(n, "Values") - a.apply(n, "Comment", nil, n.Comment) - - case *ast.TypeSpec: - a.apply(n, "Doc", nil, n.Doc) - a.apply(n, "Name", nil, n.Name) - if tparams := n.TypeParams; tparams != nil { - a.apply(n, "TypeParams", nil, tparams) - } - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Comment", nil, n.Comment) - - case *ast.BadDecl: - // nothing to do - - case *ast.GenDecl: - a.apply(n, "Doc", nil, n.Doc) - a.applyList(n, "Specs") - - case *ast.FuncDecl: - a.apply(n, "Doc", nil, n.Doc) - a.apply(n, "Recv", nil, n.Recv) - a.apply(n, "Name", nil, n.Name) - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Body", nil, n.Body) - - // Files and packages - case *ast.File: - a.apply(n, "Doc", nil, n.Doc) - a.apply(n, "Name", nil, n.Name) - a.applyList(n, "Decls") - // Don't walk n.Comments; they have either been walked already if - // they are Doc comments, or they can be easily walked explicitly. - - case *ast.Package: - // collect and sort names for reproducible behavior - var names []string - for name := range n.Files { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { - a.apply(n, name, nil, n.Files[name]) - } - - default: - panic(fmt.Sprintf("Apply: unexpected node type %T", n)) - } - - if a.post != nil && !a.post(&a.cursor) { - panic(abort) - } - - a.cursor = saved -} - -// An iterator controls iteration over a slice of nodes. -type iterator struct { - index, step int -} - -func (a *application) applyList(parent ast.Node, name string) { - // avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead - saved := a.iter - a.iter.index = 0 - for { - // must reload parent.name each time, since cursor modifications might change it - v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name) - if a.iter.index >= v.Len() { - break - } - - // element x may be nil in a bad AST - be cautious - var x ast.Node - if e := v.Index(a.iter.index); e.IsValid() { - x = e.Interface().(ast.Node) - } - - a.iter.step = 1 - a.apply(parent, name, &a.iter, x) - a.iter.index += a.iter.step - } - a.iter = saved -} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/util.go b/vendor/golang.org/x/tools/go/ast/astutil/util.go deleted file mode 100644 index 919d5305..00000000 --- a/vendor/golang.org/x/tools/go/ast/astutil/util.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package astutil - -import "go/ast" - -// Unparen returns e with any enclosing parentheses stripped. -func Unparen(e ast.Expr) ast.Expr { - for { - p, ok := e.(*ast.ParenExpr) - if !ok { - return e - } - e = p.X - } -} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go deleted file mode 100644 index 03543bd4..00000000 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gcexportdata provides functions for locating, reading, and -// writing export data files containing type information produced by the -// gc compiler. This package supports go1.7 export data format and all -// later versions. -// -// Although it might seem convenient for this package to live alongside -// go/types in the standard library, this would cause version skew -// problems for developer tools that use it, since they must be able to -// consume the outputs of the gc compiler both before and after a Go -// update such as from Go 1.7 to Go 1.8. Because this package lives in -// golang.org/x/tools, sites can update their version of this repo some -// time before the Go 1.8 release and rebuild and redeploy their -// developer tools, which will then be able to consume both Go 1.7 and -// Go 1.8 export data files, so they will work before and after the -// Go update. (See discussion at https://golang.org/issue/15651.) -package gcexportdata // import "golang.org/x/tools/go/gcexportdata" - -import ( - "bufio" - "bytes" - "encoding/json" - "fmt" - "go/token" - "go/types" - "io" - "os/exec" - - "golang.org/x/tools/internal/gcimporter" -) - -// Find returns the name of an object (.o) or archive (.a) file -// containing type information for the specified import path, -// using the go command. -// If no file was found, an empty filename is returned. -// -// A relative srcDir is interpreted relative to the current working directory. -// -// Find also returns the package's resolved (canonical) import path, -// reflecting the effects of srcDir and vendoring on importPath. -// -// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, -// which is more efficient. -func Find(importPath, srcDir string) (filename, path string) { - cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) - cmd.Dir = srcDir - out, err := cmd.CombinedOutput() - if err != nil { - return "", "" - } - var data struct { - ImportPath string - Export string - } - json.Unmarshal(out, &data) - return data.Export, data.ImportPath -} - -// NewReader returns a reader for the export data section of an object -// (.o) or archive (.a) file read from r. The new reader may provide -// additional trailing data beyond the end of the export data. -func NewReader(r io.Reader) (io.Reader, error) { - buf := bufio.NewReader(r) - _, size, err := gcimporter.FindExportData(buf) - if err != nil { - return nil, err - } - - if size >= 0 { - // We were given an archive and found the __.PKGDEF in it. - // This tells us the size of the export data, and we don't - // need to return the entire file. - return &io.LimitedReader{ - R: buf, - N: size, - }, nil - } else { - // We were given an object file. As such, we don't know how large - // the export data is and must return the entire file. - return buf, nil - } -} - -// readAll works the same way as io.ReadAll, but avoids allocations and copies -// by preallocating a byte slice of the necessary size if the size is known up -// front. This is always possible when the input is an archive. In that case, -// NewReader will return the known size using an io.LimitedReader. -func readAll(r io.Reader) ([]byte, error) { - if lr, ok := r.(*io.LimitedReader); ok { - data := make([]byte, lr.N) - _, err := io.ReadFull(lr, data) - return data, err - } - return io.ReadAll(r) -} - -// Read reads export data from in, decodes it, and returns type -// information for the package. -// -// The package path (effectively its linker symbol prefix) is -// specified by path, since unlike the package name, this information -// may not be recorded in the export data. -// -// File position information is added to fset. -// -// Read may inspect and add to the imports map to ensure that references -// within the export data to other packages are consistent. The caller -// must ensure that imports[path] does not exist, or exists but is -// incomplete (see types.Package.Complete), and Read inserts the -// resulting package into this map entry. -// -// On return, the state of the reader is undefined. -func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { - data, err := readAll(in) - if err != nil { - return nil, fmt.Errorf("reading export data for %q: %v", path, err) - } - - if bytes.HasPrefix(data, []byte("!")) { - return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) - } - - // The indexed export format starts with an 'i'; the older - // binary export format starts with a 'c', 'd', or 'v' - // (from "version"). Select appropriate importer. - if len(data) > 0 { - switch data[0] { - case 'v', 'c', 'd': // binary, till go1.10 - return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0]) - - case 'i': // indexed, till go1.19 - _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) - return pkg, err - - case 'u': // unified, from go1.20 - _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) - return pkg, err - - default: - l := len(data) - if l > 10 { - l = 10 - } - return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) - } - } - return nil, fmt.Errorf("empty export data for %s", path) -} - -// Write writes encoded type information for the specified package to out. -// The FileSet provides file position information for named objects. -func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { - if _, err := io.WriteString(out, "i"); err != nil { - return err - } - return gcimporter.IExportData(out, fset, pkg) -} - -// ReadBundle reads an export bundle from in, decodes it, and returns type -// information for the packages. -// File position information is added to fset. -// -// ReadBundle may inspect and add to the imports map to ensure that references -// within the export bundle to other packages are consistent. -// -// On return, the state of the reader is undefined. -// -// Experimental: This API is experimental and may change in the future. -func ReadBundle(in io.Reader, fset *token.FileSet, imports map[string]*types.Package) ([]*types.Package, error) { - data, err := readAll(in) - if err != nil { - return nil, fmt.Errorf("reading export bundle: %v", err) - } - return gcimporter.IImportBundle(fset, imports, data) -} - -// WriteBundle writes encoded type information for the specified packages to out. -// The FileSet provides file position information for named objects. -// -// Experimental: This API is experimental and may change in the future. -func WriteBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { - return gcimporter.IExportBundle(out, fset, pkgs) -} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go deleted file mode 100644 index 37a7247e..00000000 --- a/vendor/golang.org/x/tools/go/gcexportdata/importer.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gcexportdata - -import ( - "fmt" - "go/token" - "go/types" - "os" -) - -// NewImporter returns a new instance of the types.Importer interface -// that reads type information from export data files written by gc. -// The Importer also satisfies types.ImporterFrom. -// -// Export data files are located using "go build" workspace conventions -// and the build.Default context. -// -// Use this importer instead of go/importer.For("gc", ...) to avoid the -// version-skew problems described in the documentation of this package, -// or to control the FileSet or access the imports map populated during -// package loading. -// -// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, -// which is more efficient. -func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { - return importer{fset, imports} -} - -type importer struct { - fset *token.FileSet - imports map[string]*types.Package -} - -func (imp importer) Import(importPath string) (*types.Package, error) { - return imp.ImportFrom(importPath, "", 0) -} - -func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { - filename, path := Find(importPath, srcDir) - if filename == "" { - if importPath == "unsafe" { - // Even for unsafe, call Find first in case - // the package was vendored. - return types.Unsafe, nil - } - return nil, fmt.Errorf("can't find import: %s", importPath) - } - - if pkg, ok := imp.imports[path]; ok && pkg.Complete() { - return pkg, nil // cache hit - } - - // open file - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer func() { - f.Close() - if err != nil { - // add file name to error - err = fmt.Errorf("reading export data: %s: %v", filename, err) - } - }() - - r, err := NewReader(f) - if err != nil { - return nil, err - } - - return Read(r, imp.fset, imp.imports, path) -} diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go deleted file mode 100644 index 333676b7..00000000 --- a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package packagesdriver fetches type sizes for go/packages and go/analysis. -package packagesdriver - -import ( - "context" - "fmt" - "strings" - - "golang.org/x/tools/internal/gocommand" -) - -func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) { - inv.Verb = "list" - inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} - stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) - var goarch, compiler string - if rawErr != nil { - rawErrMsg := rawErr.Error() - if strings.Contains(rawErrMsg, "cannot find main module") || - strings.Contains(rawErrMsg, "go.mod file not found") { - // User's running outside of a module. - // All bets are off. Get GOARCH and guess compiler is gc. - // TODO(matloob): Is this a problem in practice? - inv.Verb = "env" - inv.Args = []string{"GOARCH"} - envout, enverr := gocmdRunner.Run(ctx, inv) - if enverr != nil { - return "", "", enverr - } - goarch = strings.TrimSpace(envout.String()) - compiler = "gc" - } else if friendlyErr != nil { - return "", "", friendlyErr - } else { - // This should be unreachable, but be defensive - // in case RunRaw's error results are inconsistent. - return "", "", rawErr - } - } else { - fields := strings.Fields(stdout.String()) - if len(fields) < 2 { - return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", - stdout.String(), stderr.String()) - } - goarch = fields[0] - compiler = fields[1] - } - return compiler, goarch, nil -} diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go deleted file mode 100644 index b2a0b7c6..00000000 --- a/vendor/golang.org/x/tools/go/packages/doc.go +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package packages loads Go packages for inspection and analysis. - -The [Load] function takes as input a list of patterns and returns a -list of [Package] values describing individual packages matched by those -patterns. -A [Config] specifies configuration options, the most important of which is -the [LoadMode], which controls the amount of detail in the loaded packages. - -Load passes most patterns directly to the underlying build tool. -The default build tool is the go command. -Its supported patterns are described at -https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns. - -Load may be used in Go projects that use alternative build systems, by -installing an appropriate "driver" program for the build system and -specifying its location in the GOPACKAGESDRIVER environment variable. -For example, -https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration -explains how to use the driver for Bazel. -The driver program is responsible for interpreting patterns in its -preferred notation and reporting information about the packages that -they identify. -(See driverRequest and driverResponse types for the JSON -schema used by the protocol. -Though the protocol is supported, these types are currently unexported; -see #64608 for a proposal to publish them.) - -Regardless of driver, all patterns with the prefix "query=", where query is a -non-empty string of letters from [a-z], are reserved and may be -interpreted as query operators. - -Two query operators are currently supported: "file" and "pattern". - -The query "file=path/to/file.go" matches the package or packages enclosing -the Go source file path/to/file.go. For example "file=~/go/src/fmt/print.go" -might return the packages "fmt" and "fmt [fmt.test]". - -The query "pattern=string" causes "string" to be passed directly to -the underlying build tool. In most cases this is unnecessary, -but an application can use Load("pattern=" + x) as an escaping mechanism -to ensure that x is not interpreted as a query operator if it contains '='. - -All other query operators are reserved for future use and currently -cause Load to report an error. - -The Package struct provides basic information about the package, including - - - ID, a unique identifier for the package in the returned set; - - GoFiles, the names of the package's Go source files; - - Imports, a map from source import strings to the Packages they name; - - Types, the type information for the package's exported symbols; - - Syntax, the parsed syntax trees for the package's source code; and - - TypesInfo, the result of a complete type-check of the package syntax trees. - -(See the documentation for type Package for the complete list of fields -and more detailed descriptions.) - -For example, - - Load(nil, "bytes", "unicode...") - -returns four Package structs describing the standard library packages -bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern -can match multiple packages and that a package might be matched by -multiple patterns: in general it is not possible to determine which -packages correspond to which patterns. - -Note that the list returned by Load contains only the packages matched -by the patterns. Their dependencies can be found by walking the import -graph using the Imports fields. - -The Load function can be configured by passing a pointer to a Config as -the first argument. A nil Config is equivalent to the zero Config, which -causes Load to run in LoadFiles mode, collecting minimal information. -See the documentation for type Config for details. - -As noted earlier, the Config.Mode controls the amount of detail -reported about the loaded packages. See the documentation for type LoadMode -for details. - -Most tools should pass their command-line arguments (after any flags) -uninterpreted to [Load], so that it can interpret them -according to the conventions of the underlying build system. -See the Example function for typical usage. -*/ -package packages // import "golang.org/x/tools/go/packages" - -/* - -Motivation and design considerations - -The new package's design solves problems addressed by two existing -packages: go/build, which locates and describes packages, and -golang.org/x/tools/go/loader, which loads, parses and type-checks them. -The go/build.Package structure encodes too much of the 'go build' way -of organizing projects, leaving us in need of a data type that describes a -package of Go source code independent of the underlying build system. -We wanted something that works equally well with go build and vgo, and -also other build systems such as Bazel and Blaze, making it possible to -construct analysis tools that work in all these environments. -Tools such as errcheck and staticcheck were essentially unavailable to -the Go community at Google, and some of Google's internal tools for Go -are unavailable externally. -This new package provides a uniform way to obtain package metadata by -querying each of these build systems, optionally supporting their -preferred command-line notations for packages, so that tools integrate -neatly with users' build environments. The Metadata query function -executes an external query tool appropriate to the current workspace. - -Loading packages always returns the complete import graph "all the way down", -even if all you want is information about a single package, because the query -mechanisms of all the build systems we currently support ({go,vgo} list, and -blaze/bazel aspect-based query) cannot provide detailed information -about one package without visiting all its dependencies too, so there is -no additional asymptotic cost to providing transitive information. -(This property might not be true of a hypothetical 5th build system.) - -In calls to TypeCheck, all initial packages, and any package that -transitively depends on one of them, must be loaded from source. -Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from -source; D may be loaded from export data, and E may not be loaded at all -(though it's possible that D's export data mentions it, so a -types.Package may be created for it and exposed.) - -The old loader had a feature to suppress type-checking of function -bodies on a per-package basis, primarily intended to reduce the work of -obtaining type information for imported packages. Now that imports are -satisfied by export data, the optimization no longer seems necessary. - -Despite some early attempts, the old loader did not exploit export data, -instead always using the equivalent of WholeProgram mode. This was due -to the complexity of mixing source and export data packages (now -resolved by the upward traversal mentioned above), and because export data -files were nearly always missing or stale. Now that 'go build' supports -caching, all the underlying build systems can guarantee to produce -export data in a reasonable (amortized) time. - -Test "main" packages synthesized by the build system are now reported as -first-class packages, avoiding the need for clients (such as go/ssa) to -reinvent this generation logic. - -One way in which go/packages is simpler than the old loader is in its -treatment of in-package tests. In-package tests are packages that -consist of all the files of the library under test, plus the test files. -The old loader constructed in-package tests by a two-phase process of -mutation called "augmentation": first it would construct and type check -all the ordinary library packages and type-check the packages that -depend on them; then it would add more (test) files to the package and -type-check again. This two-phase approach had four major problems: -1) in processing the tests, the loader modified the library package, - leaving no way for a client application to see both the test - package and the library package; one would mutate into the other. -2) because test files can declare additional methods on types defined in - the library portion of the package, the dispatch of method calls in - the library portion was affected by the presence of the test files. - This should have been a clue that the packages were logically - different. -3) this model of "augmentation" assumed at most one in-package test - per library package, which is true of projects using 'go build', - but not other build systems. -4) because of the two-phase nature of test processing, all packages that - import the library package had to be processed before augmentation, - forcing a "one-shot" API and preventing the client from calling Load - in several times in sequence as is now possible in WholeProgram mode. - (TypeCheck mode has a similar one-shot restriction for a different reason.) - -Early drafts of this package supported "multi-shot" operation. -Although it allowed clients to make a sequence of calls (or concurrent -calls) to Load, building up the graph of Packages incrementally, -it was of marginal value: it complicated the API -(since it allowed some options to vary across calls but not others), -it complicated the implementation, -it cannot be made to work in Types mode, as explained above, -and it was less efficient than making one combined call (when this is possible). -Among the clients we have inspected, none made multiple calls to load -but could not be easily and satisfactorily modified to make only a single call. -However, applications changes may be required. -For example, the ssadump command loads the user-specified packages -and in addition the runtime package. It is tempting to simply append -"runtime" to the user-provided list, but that does not work if the user -specified an ad-hoc package such as [a.go b.go]. -Instead, ssadump no longer requests the runtime package, -but seeks it among the dependencies of the user-specified packages, -and emits an error if it is not found. - -Overlays: The Overlay field in the Config allows providing alternate contents -for Go source files, by providing a mapping from file path to contents. -go/packages will pull in new imports added in overlay files when go/packages -is run in LoadImports mode or greater. -Overlay support for the go list driver isn't complete yet: if the file doesn't -exist on disk, it will only be recognized in an overlay if it is a non-test file -and the package would be reported even without the overlay. - -Questions & Tasks - -- Add GOARCH/GOOS? - They are not portable concepts, but could be made portable. - Our goal has been to allow users to express themselves using the conventions - of the underlying build system: if the build system honors GOARCH - during a build and during a metadata query, then so should - applications built atop that query mechanism. - Conversely, if the target architecture of the build is determined by - command-line flags, the application can pass the relevant - flags through to the build system using a command such as: - myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin" - However, this approach is low-level, unwieldy, and non-portable. - GOOS and GOARCH seem important enough to warrant a dedicated option. - -- How should we handle partial failures such as a mixture of good and - malformed patterns, existing and non-existent packages, successful and - failed builds, import failures, import cycles, and so on, in a call to - Load? - -- Support bazel, blaze, and go1.10 list, not just go1.11 list. - -- Handle (and test) various partial success cases, e.g. - a mixture of good packages and: - invalid patterns - nonexistent packages - empty packages - packages with malformed package or import declarations - unreadable files - import cycles - other parse errors - type errors - Make sure we record errors at the correct place in the graph. - -- Missing packages among initial arguments are not reported. - Return bogus packages for them, like golist does. - -- "undeclared name" errors (for example) are reported out of source file - order. I suspect this is due to the breadth-first resolution now used - by go/types. Is that a bug? Discuss with gri. - -*/ diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go deleted file mode 100644 index 7db1d129..00000000 --- a/vendor/golang.org/x/tools/go/packages/external.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file enables an external tool to intercept package requests. -// If the tool is present then its results are used in preference to -// the go list command. - -package packages - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "os/exec" - "strings" -) - -// The Driver Protocol -// -// The driver, given the inputs to a call to Load, returns metadata about the packages specified. -// This allows for different build systems to support go/packages by telling go/packages how the -// packages' source is organized. -// The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in -// the path as gopackagesdriver. It's given the inputs to load in its argv. See the package -// documentation in doc.go for the full description of the patterns that need to be supported. -// A driver receives as a JSON-serialized driverRequest struct in standard input and will -// produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output. - -// driverRequest is used to provide the portion of Load's Config that is needed by a driver. -type driverRequest struct { - Mode LoadMode `json:"mode"` - // Env specifies the environment the underlying build system should be run in. - Env []string `json:"env"` - // BuildFlags are flags that should be passed to the underlying build system. - BuildFlags []string `json:"build_flags"` - // Tests specifies whether the patterns should also return test packages. - Tests bool `json:"tests"` - // Overlay maps file paths (relative to the driver's working directory) to the byte contents - // of overlay files. - Overlay map[string][]byte `json:"overlay"` -} - -// findExternalDriver returns the file path of a tool that supplies -// the build system package structure, or "" if not found." -// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its -// value, otherwise it searches for a binary named gopackagesdriver on the PATH. -func findExternalDriver(cfg *Config) driver { - const toolPrefix = "GOPACKAGESDRIVER=" - tool := "" - for _, env := range cfg.Env { - if val := strings.TrimPrefix(env, toolPrefix); val != env { - tool = val - } - } - if tool != "" && tool == "off" { - return nil - } - if tool == "" { - var err error - tool, err = exec.LookPath("gopackagesdriver") - if err != nil { - return nil - } - } - return func(cfg *Config, words ...string) (*driverResponse, error) { - req, err := json.Marshal(driverRequest{ - Mode: cfg.Mode, - Env: cfg.Env, - BuildFlags: cfg.BuildFlags, - Tests: cfg.Tests, - Overlay: cfg.Overlay, - }) - if err != nil { - return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) - } - - buf := new(bytes.Buffer) - stderr := new(bytes.Buffer) - cmd := exec.CommandContext(cfg.Context, tool, words...) - cmd.Dir = cfg.Dir - cmd.Env = cfg.Env - cmd.Stdin = bytes.NewReader(req) - cmd.Stdout = buf - cmd.Stderr = stderr - - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) - } - if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { - fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr) - } - - var response driverResponse - if err := json.Unmarshal(buf.Bytes(), &response); err != nil { - return nil, err - } - return &response, nil - } -} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go deleted file mode 100644 index cd375fbc..00000000 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ /dev/null @@ -1,1107 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package packages - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "log" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "unicode" - - "golang.org/x/tools/go/internal/packagesdriver" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/packagesinternal" -) - -// debug controls verbose logging. -var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG")) - -// A goTooOldError reports that the go command -// found by exec.LookPath is too old to use the new go list behavior. -type goTooOldError struct { - error -} - -// responseDeduper wraps a driverResponse, deduplicating its contents. -type responseDeduper struct { - seenRoots map[string]bool - seenPackages map[string]*Package - dr *driverResponse -} - -func newDeduper() *responseDeduper { - return &responseDeduper{ - dr: &driverResponse{}, - seenRoots: map[string]bool{}, - seenPackages: map[string]*Package{}, - } -} - -// addAll fills in r with a driverResponse. -func (r *responseDeduper) addAll(dr *driverResponse) { - for _, pkg := range dr.Packages { - r.addPackage(pkg) - } - for _, root := range dr.Roots { - r.addRoot(root) - } - r.dr.GoVersion = dr.GoVersion -} - -func (r *responseDeduper) addPackage(p *Package) { - if r.seenPackages[p.ID] != nil { - return - } - r.seenPackages[p.ID] = p - r.dr.Packages = append(r.dr.Packages, p) -} - -func (r *responseDeduper) addRoot(id string) { - if r.seenRoots[id] { - return - } - r.seenRoots[id] = true - r.dr.Roots = append(r.dr.Roots, id) -} - -type golistState struct { - cfg *Config - ctx context.Context - - envOnce sync.Once - goEnvError error - goEnv map[string]string - - rootsOnce sync.Once - rootDirsError error - rootDirs map[string]string - - goVersionOnce sync.Once - goVersionError error - goVersion int // The X in Go 1.X. - - // vendorDirs caches the (non)existence of vendor directories. - vendorDirs map[string]bool -} - -// getEnv returns Go environment variables. Only specific variables are -// populated -- computing all of them is slow. -func (state *golistState) getEnv() (map[string]string, error) { - state.envOnce.Do(func() { - var b *bytes.Buffer - b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH") - if state.goEnvError != nil { - return - } - - state.goEnv = make(map[string]string) - decoder := json.NewDecoder(b) - if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil { - return - } - }) - return state.goEnv, state.goEnvError -} - -// mustGetEnv is a convenience function that can be used if getEnv has already succeeded. -func (state *golistState) mustGetEnv() map[string]string { - env, err := state.getEnv() - if err != nil { - panic(fmt.Sprintf("mustGetEnv: %v", err)) - } - return env -} - -// goListDriver uses the go list command to interpret the patterns and produce -// the build system package structure. -// See driver for more details. -func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) { - // Make sure that any asynchronous go commands are killed when we return. - parentCtx := cfg.Context - if parentCtx == nil { - parentCtx = context.Background() - } - ctx, cancel := context.WithCancel(parentCtx) - defer cancel() - - response := newDeduper() - - state := &golistState{ - cfg: cfg, - ctx: ctx, - vendorDirs: map[string]bool{}, - } - - // Fill in response.Sizes asynchronously if necessary. - var sizeserr error - var sizeswg sync.WaitGroup - if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 { - sizeswg.Add(1) - go func() { - compiler, arch, err := packagesdriver.GetSizesForArgsGolist(ctx, state.cfgInvocation(), cfg.gocmdRunner) - sizeserr = err - response.dr.Compiler = compiler - response.dr.Arch = arch - sizeswg.Done() - }() - } - - // Determine files requested in contains patterns - var containFiles []string - restPatterns := make([]string, 0, len(patterns)) - // Extract file= and other [querytype]= patterns. Report an error if querytype - // doesn't exist. -extractQueries: - for _, pattern := range patterns { - eqidx := strings.Index(pattern, "=") - if eqidx < 0 { - restPatterns = append(restPatterns, pattern) - } else { - query, value := pattern[:eqidx], pattern[eqidx+len("="):] - switch query { - case "file": - containFiles = append(containFiles, value) - case "pattern": - restPatterns = append(restPatterns, value) - case "": // not a reserved query - restPatterns = append(restPatterns, pattern) - default: - for _, rune := range query { - if rune < 'a' || rune > 'z' { // not a reserved query - restPatterns = append(restPatterns, pattern) - continue extractQueries - } - } - // Reject all other patterns containing "=" - return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern) - } - } - } - - // See if we have any patterns to pass through to go list. Zero initial - // patterns also requires a go list call, since it's the equivalent of - // ".". - if len(restPatterns) > 0 || len(patterns) == 0 { - dr, err := state.createDriverResponse(restPatterns...) - if err != nil { - return nil, err - } - response.addAll(dr) - } - - if len(containFiles) != 0 { - if err := state.runContainsQueries(response, containFiles); err != nil { - return nil, err - } - } - - sizeswg.Wait() - if sizeserr != nil { - return nil, sizeserr - } - return response.dr, nil -} - -func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error { - for _, query := range queries { - // TODO(matloob): Do only one query per directory. - fdir := filepath.Dir(query) - // Pass absolute path of directory to go list so that it knows to treat it as a directory, - // not a package path. - pattern, err := filepath.Abs(fdir) - if err != nil { - return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err) - } - dirResponse, err := state.createDriverResponse(pattern) - - // If there was an error loading the package, or no packages are returned, - // or the package is returned with errors, try to load the file as an - // ad-hoc package. - // Usually the error will appear in a returned package, but may not if we're - // in module mode and the ad-hoc is located outside a module. - if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && - len(dirResponse.Packages[0].Errors) == 1 { - var queryErr error - if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { - return err // return the original error - } - } - isRoot := make(map[string]bool, len(dirResponse.Roots)) - for _, root := range dirResponse.Roots { - isRoot[root] = true - } - for _, pkg := range dirResponse.Packages { - // Add any new packages to the main set - // We don't bother to filter packages that will be dropped by the changes of roots, - // that will happen anyway during graph construction outside this function. - // Over-reporting packages is not a problem. - response.addPackage(pkg) - // if the package was not a root one, it cannot have the file - if !isRoot[pkg.ID] { - continue - } - for _, pkgFile := range pkg.GoFiles { - if filepath.Base(query) == filepath.Base(pkgFile) { - response.addRoot(pkg.ID) - break - } - } - } - } - return nil -} - -// adhocPackage attempts to load or construct an ad-hoc package for a given -// query, if the original call to the driver produced inadequate results. -func (state *golistState) adhocPackage(pattern, query string) (*driverResponse, error) { - response, err := state.createDriverResponse(query) - if err != nil { - return nil, err - } - // If we get nothing back from `go list`, - // try to make this file into its own ad-hoc package. - // TODO(rstambler): Should this check against the original response? - if len(response.Packages) == 0 { - response.Packages = append(response.Packages, &Package{ - ID: "command-line-arguments", - PkgPath: query, - GoFiles: []string{query}, - CompiledGoFiles: []string{query}, - Imports: make(map[string]*Package), - }) - response.Roots = append(response.Roots, "command-line-arguments") - } - // Handle special cases. - if len(response.Packages) == 1 { - // golang/go#33482: If this is a file= query for ad-hoc packages where - // the file only exists on an overlay, and exists outside of a module, - // add the file to the package and remove the errors. - if response.Packages[0].ID == "command-line-arguments" || - filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) { - if len(response.Packages[0].GoFiles) == 0 { - filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath - // TODO(matloob): check if the file is outside of a root dir? - for path := range state.cfg.Overlay { - if path == filename { - response.Packages[0].Errors = nil - response.Packages[0].GoFiles = []string{path} - response.Packages[0].CompiledGoFiles = []string{path} - } - } - } - } - } - return response, nil -} - -// Fields must match go list; -// see $GOROOT/src/cmd/go/internal/load/pkg.go. -type jsonPackage struct { - ImportPath string - Dir string - Name string - Export string - GoFiles []string - CompiledGoFiles []string - IgnoredGoFiles []string - IgnoredOtherFiles []string - EmbedPatterns []string - EmbedFiles []string - CFiles []string - CgoFiles []string - CXXFiles []string - MFiles []string - HFiles []string - FFiles []string - SFiles []string - SwigFiles []string - SwigCXXFiles []string - SysoFiles []string - Imports []string - ImportMap map[string]string - Deps []string - Module *Module - TestGoFiles []string - TestImports []string - XTestGoFiles []string - XTestImports []string - ForTest string // q in a "p [q.test]" package, else "" - DepOnly bool - - Error *packagesinternal.PackageError - DepsErrors []*packagesinternal.PackageError -} - -type jsonPackageError struct { - ImportStack []string - Pos string - Err string -} - -func otherFiles(p *jsonPackage) [][]string { - return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles} -} - -// createDriverResponse uses the "go list" command to expand the pattern -// words and return a response for the specified packages. -func (state *golistState) createDriverResponse(words ...string) (*driverResponse, error) { - // go list uses the following identifiers in ImportPath and Imports: - // - // "p" -- importable package or main (command) - // "q.test" -- q's test executable - // "p [q.test]" -- variant of p as built for q's test executable - // "q_test [q.test]" -- q's external test package - // - // The packages p that are built differently for a test q.test - // are q itself, plus any helpers used by the external test q_test, - // typically including "testing" and all its dependencies. - - // Run "go list" for complete - // information on the specified packages. - goVersion, err := state.getGoVersion() - if err != nil { - return nil, err - } - buf, err := state.invokeGo("list", golistargs(state.cfg, words, goVersion)...) - if err != nil { - return nil, err - } - - seen := make(map[string]*jsonPackage) - pkgs := make(map[string]*Package) - additionalErrors := make(map[string][]Error) - // Decode the JSON and convert it to Package form. - response := &driverResponse{ - GoVersion: goVersion, - } - for dec := json.NewDecoder(buf); dec.More(); { - p := new(jsonPackage) - if err := dec.Decode(p); err != nil { - return nil, fmt.Errorf("JSON decoding failed: %v", err) - } - - if p.ImportPath == "" { - // The documentation for go list says that “[e]rroneous packages will have - // a non-empty ImportPath”. If for some reason it comes back empty, we - // prefer to error out rather than silently discarding data or handing - // back a package without any way to refer to it. - if p.Error != nil { - return nil, Error{ - Pos: p.Error.Pos, - Msg: p.Error.Err, - } - } - return nil, fmt.Errorf("package missing import path: %+v", p) - } - - // Work around https://golang.org/issue/33157: - // go list -e, when given an absolute path, will find the package contained at - // that directory. But when no package exists there, it will return a fake package - // with an error and the ImportPath set to the absolute path provided to go list. - // Try to convert that absolute path to what its package path would be if it's - // contained in a known module or GOPATH entry. This will allow the package to be - // properly "reclaimed" when overlays are processed. - if filepath.IsAbs(p.ImportPath) && p.Error != nil { - pkgPath, ok, err := state.getPkgPath(p.ImportPath) - if err != nil { - return nil, err - } - if ok { - p.ImportPath = pkgPath - } - } - - if old, found := seen[p.ImportPath]; found { - // If one version of the package has an error, and the other doesn't, assume - // that this is a case where go list is reporting a fake dependency variant - // of the imported package: When a package tries to invalidly import another - // package, go list emits a variant of the imported package (with the same - // import path, but with an error on it, and the package will have a - // DepError set on it). An example of when this can happen is for imports of - // main packages: main packages can not be imported, but they may be - // separately matched and listed by another pattern. - // See golang.org/issue/36188 for more details. - - // The plan is that eventually, hopefully in Go 1.15, the error will be - // reported on the importing package rather than the duplicate "fake" - // version of the imported package. Once all supported versions of Go - // have the new behavior this logic can be deleted. - // TODO(matloob): delete the workaround logic once all supported versions of - // Go return the errors on the proper package. - - // There should be exactly one version of a package that doesn't have an - // error. - if old.Error == nil && p.Error == nil { - if !reflect.DeepEqual(p, old) { - return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath) - } - continue - } - - // Determine if this package's error needs to be bubbled up. - // This is a hack, and we expect for go list to eventually set the error - // on the package. - if old.Error != nil { - var errkind string - if strings.Contains(old.Error.Err, "not an importable package") { - errkind = "not an importable package" - } else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") { - errkind = "use of internal package not allowed" - } - if errkind != "" { - if len(old.Error.ImportStack) < 1 { - return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind) - } - importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1] - if importingPkg == old.ImportPath { - // Using an older version of Go which put this package itself on top of import - // stack, instead of the importer. Look for importer in second from top - // position. - if len(old.Error.ImportStack) < 2 { - return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind) - } - importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2] - } - additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{ - Pos: old.Error.Pos, - Msg: old.Error.Err, - Kind: ListError, - }) - } - } - - // Make sure that if there's a version of the package without an error, - // that's the one reported to the user. - if old.Error == nil { - continue - } - - // This package will replace the old one at the end of the loop. - } - seen[p.ImportPath] = p - - pkg := &Package{ - Name: p.Name, - ID: p.ImportPath, - GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), - CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles), - OtherFiles: absJoin(p.Dir, otherFiles(p)...), - EmbedFiles: absJoin(p.Dir, p.EmbedFiles), - EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns), - IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles), - forTest: p.ForTest, - depsErrors: p.DepsErrors, - Module: p.Module, - } - - if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 { - if len(p.CompiledGoFiles) > len(p.GoFiles) { - // We need the cgo definitions, which are in the first - // CompiledGoFile after the non-cgo ones. This is a hack but there - // isn't currently a better way to find it. We also need the pure - // Go files and unprocessed cgo files, all of which are already - // in pkg.GoFiles. - cgoTypes := p.CompiledGoFiles[len(p.GoFiles)] - pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...) - } else { - // golang/go#38990: go list silently fails to do cgo processing - pkg.CompiledGoFiles = nil - pkg.Errors = append(pkg.Errors, Error{ - Msg: "go list failed to return CompiledGoFiles. This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.", - Kind: ListError, - }) - } - } - - // Work around https://golang.org/issue/28749: - // cmd/go puts assembly, C, and C++ files in CompiledGoFiles. - // Remove files from CompiledGoFiles that are non-go files - // (or are not files that look like they are from the cache). - if len(pkg.CompiledGoFiles) > 0 { - out := pkg.CompiledGoFiles[:0] - for _, f := range pkg.CompiledGoFiles { - if ext := filepath.Ext(f); ext != ".go" && ext != "" { // ext == "" means the file is from the cache, so probably cgo-processed file - continue - } - out = append(out, f) - } - pkg.CompiledGoFiles = out - } - - // Extract the PkgPath from the package's ID. - if i := strings.IndexByte(pkg.ID, ' '); i >= 0 { - pkg.PkgPath = pkg.ID[:i] - } else { - pkg.PkgPath = pkg.ID - } - - if pkg.PkgPath == "unsafe" { - pkg.CompiledGoFiles = nil // ignore fake unsafe.go file (#59929) - } else if len(pkg.CompiledGoFiles) == 0 { - // Work around for pre-go.1.11 versions of go list. - // TODO(matloob): they should be handled by the fallback. - // Can we delete this? - pkg.CompiledGoFiles = pkg.GoFiles - } - - // Assume go list emits only absolute paths for Dir. - if p.Dir != "" && !filepath.IsAbs(p.Dir) { - log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir) - } - - if p.Export != "" && !filepath.IsAbs(p.Export) { - pkg.ExportFile = filepath.Join(p.Dir, p.Export) - } else { - pkg.ExportFile = p.Export - } - - // imports - // - // Imports contains the IDs of all imported packages. - // ImportsMap records (path, ID) only where they differ. - ids := make(map[string]bool) - for _, id := range p.Imports { - ids[id] = true - } - pkg.Imports = make(map[string]*Package) - for path, id := range p.ImportMap { - pkg.Imports[path] = &Package{ID: id} // non-identity import - delete(ids, id) - } - for id := range ids { - if id == "C" { - continue - } - - pkg.Imports[id] = &Package{ID: id} // identity import - } - if !p.DepOnly { - response.Roots = append(response.Roots, pkg.ID) - } - - // Temporary work-around for golang/go#39986. Parse filenames out of - // error messages. This happens if there are unrecoverable syntax - // errors in the source, so we can't match on a specific error message. - // - // TODO(rfindley): remove this heuristic, in favor of considering - // InvalidGoFiles from the list driver. - if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) { - addFilenameFromPos := func(pos string) bool { - split := strings.Split(pos, ":") - if len(split) < 1 { - return false - } - filename := strings.TrimSpace(split[0]) - if filename == "" { - return false - } - if !filepath.IsAbs(filename) { - filename = filepath.Join(state.cfg.Dir, filename) - } - info, _ := os.Stat(filename) - if info == nil { - return false - } - pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename) - pkg.GoFiles = append(pkg.GoFiles, filename) - return true - } - found := addFilenameFromPos(err.Pos) - // In some cases, go list only reports the error position in the - // error text, not the error position. One such case is when the - // file's package name is a keyword (see golang.org/issue/39763). - if !found { - addFilenameFromPos(err.Err) - } - } - - if p.Error != nil { - msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363. - // Address golang.org/issue/35964 by appending import stack to error message. - if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 { - msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack) - } - pkg.Errors = append(pkg.Errors, Error{ - Pos: p.Error.Pos, - Msg: msg, - Kind: ListError, - }) - } - - pkgs[pkg.ID] = pkg - } - - for id, errs := range additionalErrors { - if p, ok := pkgs[id]; ok { - p.Errors = append(p.Errors, errs...) - } - } - for _, pkg := range pkgs { - response.Packages = append(response.Packages, pkg) - } - sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID }) - - return response, nil -} - -func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool { - if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 { - return false - } - - goV, err := state.getGoVersion() - if err != nil { - return false - } - - // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty. - // The import stack behaves differently for these versions than newer Go versions. - if goV < 15 { - return len(p.Error.ImportStack) == 0 - } - - // On Go 1.15 and later, only parse filenames out of error if there's no import stack, - // or the current package is at the top of the import stack. This is not guaranteed - // to work perfectly, but should avoid some cases where files in errors don't belong to this - // package. - return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath -} - -// getGoVersion returns the effective minor version of the go command. -func (state *golistState) getGoVersion() (int, error) { - state.goVersionOnce.Do(func() { - state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.cfg.gocmdRunner) - }) - return state.goVersion, state.goVersionError -} - -// getPkgPath finds the package path of a directory if it's relative to a root -// directory. -func (state *golistState) getPkgPath(dir string) (string, bool, error) { - absDir, err := filepath.Abs(dir) - if err != nil { - return "", false, err - } - roots, err := state.determineRootDirs() - if err != nil { - return "", false, err - } - - for rdir, rpath := range roots { - // Make sure that the directory is in the module, - // to avoid creating a path relative to another module. - if !strings.HasPrefix(absDir, rdir) { - continue - } - // TODO(matloob): This doesn't properly handle symlinks. - r, err := filepath.Rel(rdir, dir) - if err != nil { - continue - } - if rpath != "" { - // We choose only one root even though the directory even it can belong in multiple modules - // or GOPATH entries. This is okay because we only need to work with absolute dirs when a - // file is missing from disk, for instance when gopls calls go/packages in an overlay. - // Once the file is saved, gopls, or the next invocation of the tool will get the correct - // result straight from golist. - // TODO(matloob): Implement module tiebreaking? - return path.Join(rpath, filepath.ToSlash(r)), true, nil - } - return filepath.ToSlash(r), true, nil - } - return "", false, nil -} - -// absJoin absolutizes and flattens the lists of files. -func absJoin(dir string, fileses ...[]string) (res []string) { - for _, files := range fileses { - for _, file := range files { - if !filepath.IsAbs(file) { - file = filepath.Join(dir, file) - } - res = append(res, file) - } - } - return res -} - -func jsonFlag(cfg *Config, goVersion int) string { - if goVersion < 19 { - return "-json" - } - var fields []string - added := make(map[string]bool) - addFields := func(fs ...string) { - for _, f := range fs { - if !added[f] { - added[f] = true - fields = append(fields, f) - } - } - } - addFields("Name", "ImportPath", "Error") // These fields are always needed - if cfg.Mode&NeedFiles != 0 || cfg.Mode&NeedTypes != 0 { - addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles", - "CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles", - "SwigFiles", "SwigCXXFiles", "SysoFiles") - if cfg.Tests { - addFields("TestGoFiles", "XTestGoFiles") - } - } - if cfg.Mode&NeedTypes != 0 { - // CompiledGoFiles seems to be required for the test case TestCgoNoSyntax, - // even when -compiled isn't passed in. - // TODO(#52435): Should we make the test ask for -compiled, or automatically - // request CompiledGoFiles in certain circumstances? - addFields("Dir", "CompiledGoFiles") - } - if cfg.Mode&NeedCompiledGoFiles != 0 { - addFields("Dir", "CompiledGoFiles", "Export") - } - if cfg.Mode&NeedImports != 0 { - // When imports are requested, DepOnly is used to distinguish between packages - // explicitly requested and transitive imports of those packages. - addFields("DepOnly", "Imports", "ImportMap") - if cfg.Tests { - addFields("TestImports", "XTestImports") - } - } - if cfg.Mode&NeedDeps != 0 { - addFields("DepOnly") - } - if usesExportData(cfg) { - // Request Dir in the unlikely case Export is not absolute. - addFields("Dir", "Export") - } - if cfg.Mode&needInternalForTest != 0 { - addFields("ForTest") - } - if cfg.Mode&needInternalDepsErrors != 0 { - addFields("DepsErrors") - } - if cfg.Mode&NeedModule != 0 { - addFields("Module") - } - if cfg.Mode&NeedEmbedFiles != 0 { - addFields("EmbedFiles") - } - if cfg.Mode&NeedEmbedPatterns != 0 { - addFields("EmbedPatterns") - } - return "-json=" + strings.Join(fields, ",") -} - -func golistargs(cfg *Config, words []string, goVersion int) []string { - const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo - fullargs := []string{ - "-e", jsonFlag(cfg, goVersion), - fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0), - fmt.Sprintf("-test=%t", cfg.Tests), - fmt.Sprintf("-export=%t", usesExportData(cfg)), - fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0), - // go list doesn't let you pass -test and -find together, - // probably because you'd just get the TestMain. - fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)), - } - - // golang/go#60456: with go1.21 and later, go list serves pgo variants, which - // can be costly to compute and may result in redundant processing for the - // caller. Disable these variants. If someone wants to add e.g. a NeedPGO - // mode flag, that should be a separate proposal. - if goVersion >= 21 { - fullargs = append(fullargs, "-pgo=off") - } - - fullargs = append(fullargs, cfg.BuildFlags...) - fullargs = append(fullargs, "--") - fullargs = append(fullargs, words...) - return fullargs -} - -// cfgInvocation returns an Invocation that reflects cfg's settings. -func (state *golistState) cfgInvocation() gocommand.Invocation { - cfg := state.cfg - return gocommand.Invocation{ - BuildFlags: cfg.BuildFlags, - ModFile: cfg.modFile, - ModFlag: cfg.modFlag, - CleanEnv: cfg.Env != nil, - Env: cfg.Env, - Logf: cfg.Logf, - WorkingDir: cfg.Dir, - } -} - -// invokeGo returns the stdout of a go command invocation. -func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) { - cfg := state.cfg - - inv := state.cfgInvocation() - - // For Go versions 1.16 and above, `go list` accepts overlays directly via - // the -overlay flag. Set it, if it's available. - // - // The check for "list" is not necessarily required, but we should avoid - // getting the go version if possible. - if verb == "list" { - goVersion, err := state.getGoVersion() - if err != nil { - return nil, err - } - if goVersion >= 16 { - filename, cleanup, err := state.writeOverlays() - if err != nil { - return nil, err - } - defer cleanup() - inv.Overlay = filename - } - } - inv.Verb = verb - inv.Args = args - gocmdRunner := cfg.gocmdRunner - if gocmdRunner == nil { - gocmdRunner = &gocommand.Runner{} - } - stdout, stderr, friendlyErr, err := gocmdRunner.RunRaw(cfg.Context, inv) - if err != nil { - // Check for 'go' executable not being found. - if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { - return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound) - } - - exitErr, ok := err.(*exec.ExitError) - if !ok { - // Catastrophic error: - // - context cancellation - return nil, fmt.Errorf("couldn't run 'go': %w", err) - } - - // Old go version? - if strings.Contains(stderr.String(), "flag provided but not defined") { - return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)} - } - - // Related to #24854 - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") { - return nil, friendlyErr - } - - // Is there an error running the C compiler in cgo? This will be reported in the "Error" field - // and should be suppressed by go list -e. - // - // This condition is not perfect yet because the error message can include other error messages than runtime/cgo. - isPkgPathRune := func(r rune) bool { - // From https://golang.org/ref/spec#Import_declarations: - // Implementation restriction: A compiler may restrict ImportPaths to non-empty strings - // using only characters belonging to Unicode's L, M, N, P, and S general categories - // (the Graphic characters without spaces) and may also exclude the - // characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD. - return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) && - !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) - } - // golang/go#36770: Handle case where cmd/go prints module download messages before the error. - msg := stderr.String() - for strings.HasPrefix(msg, "go: downloading") { - msg = msg[strings.IndexRune(msg, '\n')+1:] - } - if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") { - msg := msg[len("# "):] - if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") { - return stdout, nil - } - // Treat pkg-config errors as a special case (golang.org/issue/36770). - if strings.HasPrefix(msg, "pkg-config") { - return stdout, nil - } - } - - // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show - // the error in the Err section of stdout in case -e option is provided. - // This fix is provided for backwards compatibility. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Similar to the previous error, but currently lacks a fix in Go. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath. - // If the package doesn't exist, put the absolute path of the directory into the error message, - // as Go 1.13 list does. - const noSuchDirectory = "no such directory" - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) { - errstr := stderr.String() - abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):]) - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - abspath, strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist. - // Note that the error message we look for in this case is different that the one looked for above. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a - // directory outside any module. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") { - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - // TODO(matloob): command-line-arguments isn't correct here. - "command-line-arguments", strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Another variation of the previous error - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") { - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - // TODO(matloob): command-line-arguments isn't correct here. - "command-line-arguments", strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit - // status if there's a dependency on a package that doesn't exist. But it should return - // a zero exit status and set an error on that package. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") { - // Don't clobber stdout if `go list` actually returned something. - if len(stdout.String()) > 0 { - return stdout, nil - } - // try to extract package name from string - stderrStr := stderr.String() - var importPath string - colon := strings.Index(stderrStr, ":") - if colon > 0 && strings.HasPrefix(stderrStr, "go build ") { - importPath = stderrStr[len("go build "):colon] - } - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - importPath, strings.Trim(stderrStr, "\n")) - return bytes.NewBufferString(output), nil - } - - // Export mode entails a build. - // If that build fails, errors appear on stderr - // (despite the -e flag) and the Export field is blank. - // Do not fail in that case. - // The same is true if an ad-hoc package given to go list doesn't exist. - // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when - // packages don't exist or a build fails. - if !usesExportData(cfg) && !containsGoFile(args) { - return nil, friendlyErr - } - } - return stdout, nil -} - -// OverlayJSON is the format overlay files are expected to be in. -// The Replace map maps from overlaid paths to replacement paths: -// the Go command will forward all reads trying to open -// each overlaid path to its replacement path, or consider the overlaid -// path not to exist if the replacement path is empty. -// -// From golang/go#39958. -type OverlayJSON struct { - Replace map[string]string `json:"replace,omitempty"` -} - -// writeOverlays writes out files for go list's -overlay flag, as described -// above. -func (state *golistState) writeOverlays() (filename string, cleanup func(), err error) { - // Do nothing if there are no overlays in the config. - if len(state.cfg.Overlay) == 0 { - return "", func() {}, nil - } - dir, err := os.MkdirTemp("", "gopackages-*") - if err != nil { - return "", nil, err - } - // The caller must clean up this directory, unless this function returns an - // error. - cleanup = func() { - os.RemoveAll(dir) - } - defer func() { - if err != nil { - cleanup() - } - }() - overlays := map[string]string{} - for k, v := range state.cfg.Overlay { - // Create a unique filename for the overlaid files, to avoid - // creating nested directories. - noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "") - f, err := os.CreateTemp(dir, fmt.Sprintf("*-%s", noSeparator)) - if err != nil { - return "", func() {}, err - } - if _, err := f.Write(v); err != nil { - return "", func() {}, err - } - if err := f.Close(); err != nil { - return "", func() {}, err - } - overlays[k] = f.Name() - } - b, err := json.Marshal(OverlayJSON{Replace: overlays}) - if err != nil { - return "", func() {}, err - } - // Write out the overlay file that contains the filepath mappings. - filename = filepath.Join(dir, "overlay.json") - if err := os.WriteFile(filename, b, 0665); err != nil { - return "", func() {}, err - } - return filename, cleanup, nil -} - -func containsGoFile(s []string) bool { - for _, f := range s { - if strings.HasSuffix(f, ".go") { - return true - } - } - return false -} - -func cmdDebugStr(cmd *exec.Cmd) string { - env := make(map[string]string) - for _, kv := range cmd.Env { - split := strings.SplitN(kv, "=", 2) - k, v := split[0], split[1] - env[k] = v - } - - var args []string - for _, arg := range cmd.Args { - quoted := strconv.Quote(arg) - if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { - args = append(args, quoted) - } else { - args = append(args, arg) - } - } - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) -} diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go deleted file mode 100644 index d823c474..00000000 --- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package packages - -import ( - "encoding/json" - "path/filepath" - - "golang.org/x/tools/internal/gocommand" -) - -// determineRootDirs returns a mapping from absolute directories that could -// contain code to their corresponding import path prefixes. -func (state *golistState) determineRootDirs() (map[string]string, error) { - env, err := state.getEnv() - if err != nil { - return nil, err - } - if env["GOMOD"] != "" { - state.rootsOnce.Do(func() { - state.rootDirs, state.rootDirsError = state.determineRootDirsModules() - }) - } else { - state.rootsOnce.Do(func() { - state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH() - }) - } - return state.rootDirs, state.rootDirsError -} - -func (state *golistState) determineRootDirsModules() (map[string]string, error) { - // List all of the modules--the first will be the directory for the main - // module. Any replaced modules will also need to be treated as roots. - // Editing files in the module cache isn't a great idea, so we don't - // plan to ever support that. - out, err := state.invokeGo("list", "-m", "-json", "all") - if err != nil { - // 'go list all' will fail if we're outside of a module and - // GO111MODULE=on. Try falling back without 'all'. - var innerErr error - out, innerErr = state.invokeGo("list", "-m", "-json") - if innerErr != nil { - return nil, err - } - } - roots := map[string]string{} - modules := map[string]string{} - var i int - for dec := json.NewDecoder(out); dec.More(); { - mod := new(gocommand.ModuleJSON) - if err := dec.Decode(mod); err != nil { - return nil, err - } - if mod.Dir != "" && mod.Path != "" { - // This is a valid module; add it to the map. - absDir, err := filepath.Abs(mod.Dir) - if err != nil { - return nil, err - } - modules[absDir] = mod.Path - // The first result is the main module. - if i == 0 || mod.Replace != nil && mod.Replace.Path != "" { - roots[absDir] = mod.Path - } - } - i++ - } - return roots, nil -} - -func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { - m := map[string]string{} - for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) { - absDir, err := filepath.Abs(dir) - if err != nil { - return nil, err - } - m[filepath.Join(absDir, "src")] = "" - } - return m, nil -} diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go deleted file mode 100644 index 5c080d21..00000000 --- a/vendor/golang.org/x/tools/go/packages/loadmode_string.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package packages - -import ( - "fmt" - "strings" -) - -var allModes = []LoadMode{ - NeedName, - NeedFiles, - NeedCompiledGoFiles, - NeedImports, - NeedDeps, - NeedExportFile, - NeedTypes, - NeedSyntax, - NeedTypesInfo, - NeedTypesSizes, -} - -var modeStrings = []string{ - "NeedName", - "NeedFiles", - "NeedCompiledGoFiles", - "NeedImports", - "NeedDeps", - "NeedExportFile", - "NeedTypes", - "NeedSyntax", - "NeedTypesInfo", - "NeedTypesSizes", -} - -func (mod LoadMode) String() string { - m := mod - if m == 0 { - return "LoadMode(0)" - } - var out []string - for i, x := range allModes { - if x > m { - break - } - if (m & x) != 0 { - out = append(out, modeStrings[i]) - m = m ^ x - } - } - if m != 0 { - out = append(out, "Unknown") - } - return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|")) -} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go deleted file mode 100644 index 81e9e6a7..00000000 --- a/vendor/golang.org/x/tools/go/packages/packages.go +++ /dev/null @@ -1,1347 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package packages - -// See doc.go for package documentation and implementation notes. - -import ( - "context" - "encoding/json" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "io" - "log" - "os" - "path/filepath" - "runtime" - "strings" - "sync" - "time" - - "golang.org/x/tools/go/gcexportdata" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/packagesinternal" - "golang.org/x/tools/internal/typesinternal" - "golang.org/x/tools/internal/versions" -) - -// A LoadMode controls the amount of detail to return when loading. -// The bits below can be combined to specify which fields should be -// filled in the result packages. -// The zero value is a special case, equivalent to combining -// the NeedName, NeedFiles, and NeedCompiledGoFiles bits. -// ID and Errors (if present) will always be filled. -// Load may return more information than requested. -type LoadMode int - -const ( - // NeedName adds Name and PkgPath. - NeedName LoadMode = 1 << iota - - // NeedFiles adds GoFiles and OtherFiles. - NeedFiles - - // NeedCompiledGoFiles adds CompiledGoFiles. - NeedCompiledGoFiles - - // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain - // "placeholder" Packages with only the ID set. - NeedImports - - // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. - NeedDeps - - // NeedExportFile adds ExportFile. - NeedExportFile - - // NeedTypes adds Types, Fset, and IllTyped. - NeedTypes - - // NeedSyntax adds Syntax. - NeedSyntax - - // NeedTypesInfo adds TypesInfo. - NeedTypesInfo - - // NeedTypesSizes adds TypesSizes. - NeedTypesSizes - - // needInternalDepsErrors adds the internal deps errors field for use by gopls. - needInternalDepsErrors - - // needInternalForTest adds the internal forTest field. - // Tests must also be set on the context for this field to be populated. - needInternalForTest - - // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. - // Modifies CompiledGoFiles and Types, and has no effect on its own. - typecheckCgo - - // NeedModule adds Module. - NeedModule - - // NeedEmbedFiles adds EmbedFiles. - NeedEmbedFiles - - // NeedEmbedPatterns adds EmbedPatterns. - NeedEmbedPatterns -) - -const ( - // Deprecated: LoadFiles exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles - - // Deprecated: LoadImports exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadImports = LoadFiles | NeedImports - - // Deprecated: LoadTypes exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadTypes = LoadImports | NeedTypes | NeedTypesSizes - - // Deprecated: LoadSyntax exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo - - // Deprecated: LoadAllSyntax exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadAllSyntax = LoadSyntax | NeedDeps - - // Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile. - NeedExportsFile = NeedExportFile -) - -// A Config specifies details about how packages should be loaded. -// The zero value is a valid configuration. -// Calls to Load do not modify this struct. -type Config struct { - // Mode controls the level of information returned for each package. - Mode LoadMode - - // Context specifies the context for the load operation. - // If the context is cancelled, the loader may stop early - // and return an ErrCancelled error. - // If Context is nil, the load cannot be cancelled. - Context context.Context - - // Logf is the logger for the config. - // If the user provides a logger, debug logging is enabled. - // If the GOPACKAGESDEBUG environment variable is set to true, - // but the logger is nil, default to log.Printf. - Logf func(format string, args ...interface{}) - - // Dir is the directory in which to run the build system's query tool - // that provides information about the packages. - // If Dir is empty, the tool is run in the current directory. - Dir string - - // Env is the environment to use when invoking the build system's query tool. - // If Env is nil, the current environment is used. - // As in os/exec's Cmd, only the last value in the slice for - // each environment key is used. To specify the setting of only - // a few variables, append to the current environment, as in: - // - // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386") - // - Env []string - - // gocmdRunner guards go command calls from concurrency errors. - gocmdRunner *gocommand.Runner - - // BuildFlags is a list of command-line flags to be passed through to - // the build system's query tool. - BuildFlags []string - - // modFile will be used for -modfile in go command invocations. - modFile string - - // modFlag will be used for -modfile in go command invocations. - modFlag string - - // Fset provides source position information for syntax trees and types. - // If Fset is nil, Load will use a new fileset, but preserve Fset's value. - Fset *token.FileSet - - // ParseFile is called to read and parse each file - // when preparing a package's type-checked syntax tree. - // It must be safe to call ParseFile simultaneously from multiple goroutines. - // If ParseFile is nil, the loader will uses parser.ParseFile. - // - // ParseFile should parse the source from src and use filename only for - // recording position information. - // - // An application may supply a custom implementation of ParseFile - // to change the effective file contents or the behavior of the parser, - // or to modify the syntax tree. For example, selectively eliminating - // unwanted function bodies can significantly accelerate type checking. - ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) - - // If Tests is set, the loader includes not just the packages - // matching a particular pattern but also any related test packages, - // including test-only variants of the package and the test executable. - // - // For example, when using the go command, loading "fmt" with Tests=true - // returns four packages, with IDs "fmt" (the standard package), - // "fmt [fmt.test]" (the package as compiled for the test), - // "fmt_test" (the test functions from source files in package fmt_test), - // and "fmt.test" (the test binary). - // - // In build systems with explicit names for tests, - // setting Tests may have no effect. - Tests bool - - // Overlay provides a mapping of absolute file paths to file contents. - // If the file with the given path already exists, the parser will use the - // alternative file contents provided by the map. - // - // Overlays provide incomplete support for when a given file doesn't - // already exist on disk. See the package doc above for more details. - Overlay map[string][]byte -} - -// driver is the type for functions that query the build system for the -// packages named by the patterns. -type driver func(cfg *Config, patterns ...string) (*driverResponse, error) - -// driverResponse contains the results for a driver query. -type driverResponse struct { - // NotHandled is returned if the request can't be handled by the current - // driver. If an external driver returns a response with NotHandled, the - // rest of the driverResponse is ignored, and go/packages will fallback - // to the next driver. If go/packages is extended in the future to support - // lists of multiple drivers, go/packages will fall back to the next driver. - NotHandled bool - - // Compiler and Arch are the arguments pass of types.SizesFor - // to get a types.Sizes to use when type checking. - Compiler string - Arch string - - // Roots is the set of package IDs that make up the root packages. - // We have to encode this separately because when we encode a single package - // we cannot know if it is one of the roots as that requires knowledge of the - // graph it is part of. - Roots []string `json:",omitempty"` - - // Packages is the full set of packages in the graph. - // The packages are not connected into a graph. - // The Imports if populated will be stubs that only have their ID set. - // Imports will be connected and then type and syntax information added in a - // later pass (see refine). - Packages []*Package - - // GoVersion is the minor version number used by the driver - // (e.g. the go command on the PATH) when selecting .go files. - // Zero means unknown. - GoVersion int -} - -// Load loads and returns the Go packages named by the given patterns. -// -// Config specifies loading options; -// nil behaves the same as an empty Config. -// -// Load returns an error if any of the patterns was invalid -// as defined by the underlying build system. -// It may return an empty list of packages without an error, -// for instance for an empty expansion of a valid wildcard. -// Errors associated with a particular package are recorded in the -// corresponding Package's Errors list, and do not cause Load to -// return an error. Clients may need to handle such errors before -// proceeding with further analysis. The PrintErrors function is -// provided for convenient display of all errors. -func Load(cfg *Config, patterns ...string) ([]*Package, error) { - ld := newLoader(cfg) - response, external, err := defaultDriver(&ld.Config, patterns...) - if err != nil { - return nil, err - } - - ld.sizes = types.SizesFor(response.Compiler, response.Arch) - if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 { - // Type size information is needed but unavailable. - if external { - // An external driver may fail to populate the Compiler/GOARCH fields, - // especially since they are relatively new (see #63700). - // Provide a sensible fallback in this case. - ld.sizes = types.SizesFor("gc", runtime.GOARCH) - if ld.sizes == nil { // gccgo-only arch - ld.sizes = types.SizesFor("gc", "amd64") - } - } else { - // Go list should never fail to deliver accurate size information. - // Reject the whole Load since the error is the same for every package. - return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q", - response.Compiler, response.Arch) - } - } - - return ld.refine(response) -} - -// defaultDriver is a driver that implements go/packages' fallback behavior. -// It will try to request to an external driver, if one exists. If there's -// no external driver, or the driver returns a response with NotHandled set, -// defaultDriver will fall back to the go list driver. -// The boolean result indicates that an external driver handled the request. -func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, bool, error) { - if driver := findExternalDriver(cfg); driver != nil { - response, err := driver(cfg, patterns...) - if err != nil { - return nil, false, err - } else if !response.NotHandled { - return response, true, nil - } - // (fall through) - } - - response, err := goListDriver(cfg, patterns...) - return response, false, err -} - -// A Package describes a loaded Go package. -type Package struct { - // ID is a unique identifier for a package, - // in a syntax provided by the underlying build system. - // - // Because the syntax varies based on the build system, - // clients should treat IDs as opaque and not attempt to - // interpret them. - ID string - - // Name is the package name as it appears in the package source code. - Name string - - // PkgPath is the package path as used by the go/types package. - PkgPath string - - // Errors contains any errors encountered querying the metadata - // of the package, or while parsing or type-checking its files. - Errors []Error - - // TypeErrors contains the subset of errors produced during type checking. - TypeErrors []types.Error - - // GoFiles lists the absolute file paths of the package's Go source files. - // It may include files that should not be compiled, for example because - // they contain non-matching build tags, are documentary pseudo-files such as - // unsafe/unsafe.go or builtin/builtin.go, or are subject to cgo preprocessing. - GoFiles []string - - // CompiledGoFiles lists the absolute file paths of the package's source - // files that are suitable for type checking. - // This may differ from GoFiles if files are processed before compilation. - CompiledGoFiles []string - - // OtherFiles lists the absolute file paths of the package's non-Go source files, - // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. - OtherFiles []string - - // EmbedFiles lists the absolute file paths of the package's files - // embedded with go:embed. - EmbedFiles []string - - // EmbedPatterns lists the absolute file patterns of the package's - // files embedded with go:embed. - EmbedPatterns []string - - // IgnoredFiles lists source files that are not part of the package - // using the current build configuration but that might be part of - // the package using other build configurations. - IgnoredFiles []string - - // ExportFile is the absolute path to a file containing type - // information for the package as provided by the build system. - ExportFile string - - // Imports maps import paths appearing in the package's Go source files - // to corresponding loaded Packages. - Imports map[string]*Package - - // Types provides type information for the package. - // The NeedTypes LoadMode bit sets this field for packages matching the - // patterns; type information for dependencies may be missing or incomplete, - // unless NeedDeps and NeedImports are also set. - Types *types.Package - - // Fset provides position information for Types, TypesInfo, and Syntax. - // It is set only when Types is set. - Fset *token.FileSet - - // IllTyped indicates whether the package or any dependency contains errors. - // It is set only when Types is set. - IllTyped bool - - // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. - // - // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. - // If NeedDeps and NeedImports are also set, this field will also be populated - // for dependencies. - // - // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are - // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles. - Syntax []*ast.File - - // TypesInfo provides type information about the package's syntax trees. - // It is set only when Syntax is set. - TypesInfo *types.Info - - // TypesSizes provides the effective size function for types in TypesInfo. - TypesSizes types.Sizes - - // forTest is the package under test, if any. - forTest string - - // depsErrors is the DepsErrors field from the go list response, if any. - depsErrors []*packagesinternal.PackageError - - // module is the module information for the package if it exists. - Module *Module -} - -// Module provides module information for a package. -type Module struct { - Path string // module path - Version string // module version - Replace *Module // replaced by this module - Time *time.Time // time version was created - Main bool // is this the main module? - Indirect bool // is this module only an indirect dependency of main module? - Dir string // directory holding files for this module, if any - GoMod string // path to go.mod file used when loading this module, if any - GoVersion string // go version used in module - Error *ModuleError // error loading module -} - -// ModuleError holds errors loading a module. -type ModuleError struct { - Err string // the error itself -} - -func init() { - packagesinternal.GetForTest = func(p interface{}) string { - return p.(*Package).forTest - } - packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError { - return p.(*Package).depsErrors - } - packagesinternal.SetModFile = func(config interface{}, value string) { - config.(*Config).modFile = value - } - packagesinternal.SetModFlag = func(config interface{}, value string) { - config.(*Config).modFlag = value - } - packagesinternal.TypecheckCgo = int(typecheckCgo) - packagesinternal.DepsErrors = int(needInternalDepsErrors) - packagesinternal.ForTest = int(needInternalForTest) -} - -// An Error describes a problem with a package's metadata, syntax, or types. -type Error struct { - Pos string // "file:line:col" or "file:line" or "" or "-" - Msg string - Kind ErrorKind -} - -// ErrorKind describes the source of the error, allowing the user to -// differentiate between errors generated by the driver, the parser, or the -// type-checker. -type ErrorKind int - -const ( - UnknownError ErrorKind = iota - ListError - ParseError - TypeError -) - -func (err Error) Error() string { - pos := err.Pos - if pos == "" { - pos = "-" // like token.Position{}.String() - } - return pos + ": " + err.Msg -} - -// flatPackage is the JSON form of Package -// It drops all the type and syntax fields, and transforms the Imports -// -// TODO(adonovan): identify this struct with Package, effectively -// publishing the JSON protocol. -type flatPackage struct { - ID string - Name string `json:",omitempty"` - PkgPath string `json:",omitempty"` - Errors []Error `json:",omitempty"` - GoFiles []string `json:",omitempty"` - CompiledGoFiles []string `json:",omitempty"` - OtherFiles []string `json:",omitempty"` - EmbedFiles []string `json:",omitempty"` - EmbedPatterns []string `json:",omitempty"` - IgnoredFiles []string `json:",omitempty"` - ExportFile string `json:",omitempty"` - Imports map[string]string `json:",omitempty"` -} - -// MarshalJSON returns the Package in its JSON form. -// For the most part, the structure fields are written out unmodified, and -// the type and syntax fields are skipped. -// The imports are written out as just a map of path to package id. -// The errors are written using a custom type that tries to preserve the -// structure of error types we know about. -// -// This method exists to enable support for additional build systems. It is -// not intended for use by clients of the API and we may change the format. -func (p *Package) MarshalJSON() ([]byte, error) { - flat := &flatPackage{ - ID: p.ID, - Name: p.Name, - PkgPath: p.PkgPath, - Errors: p.Errors, - GoFiles: p.GoFiles, - CompiledGoFiles: p.CompiledGoFiles, - OtherFiles: p.OtherFiles, - EmbedFiles: p.EmbedFiles, - EmbedPatterns: p.EmbedPatterns, - IgnoredFiles: p.IgnoredFiles, - ExportFile: p.ExportFile, - } - if len(p.Imports) > 0 { - flat.Imports = make(map[string]string, len(p.Imports)) - for path, ipkg := range p.Imports { - flat.Imports[path] = ipkg.ID - } - } - return json.Marshal(flat) -} - -// UnmarshalJSON reads in a Package from its JSON format. -// See MarshalJSON for details about the format accepted. -func (p *Package) UnmarshalJSON(b []byte) error { - flat := &flatPackage{} - if err := json.Unmarshal(b, &flat); err != nil { - return err - } - *p = Package{ - ID: flat.ID, - Name: flat.Name, - PkgPath: flat.PkgPath, - Errors: flat.Errors, - GoFiles: flat.GoFiles, - CompiledGoFiles: flat.CompiledGoFiles, - OtherFiles: flat.OtherFiles, - EmbedFiles: flat.EmbedFiles, - EmbedPatterns: flat.EmbedPatterns, - ExportFile: flat.ExportFile, - } - if len(flat.Imports) > 0 { - p.Imports = make(map[string]*Package, len(flat.Imports)) - for path, id := range flat.Imports { - p.Imports[path] = &Package{ID: id} - } - } - return nil -} - -func (p *Package) String() string { return p.ID } - -// loaderPackage augments Package with state used during the loading phase -type loaderPackage struct { - *Package - importErrors map[string]error // maps each bad import to its error - loadOnce sync.Once - color uint8 // for cycle detection - needsrc bool // load from source (Mode >= LoadTypes) - needtypes bool // type information is either requested or depended on - initial bool // package was matched by a pattern - goVersion int // minor version number of go command on PATH -} - -// loader holds the working state of a single call to load. -type loader struct { - pkgs map[string]*loaderPackage - Config - sizes types.Sizes // non-nil if needed by mode - parseCache map[string]*parseValue - parseCacheMu sync.Mutex - exportMu sync.Mutex // enforces mutual exclusion of exportdata operations - - // Config.Mode contains the implied mode (see impliedLoadMode). - // Implied mode contains all the fields we need the data for. - // In requestedMode there are the actually requested fields. - // We'll zero them out before returning packages to the user. - // This makes it easier for us to get the conditions where - // we need certain modes right. - requestedMode LoadMode -} - -type parseValue struct { - f *ast.File - err error - ready chan struct{} -} - -func newLoader(cfg *Config) *loader { - ld := &loader{ - parseCache: map[string]*parseValue{}, - } - if cfg != nil { - ld.Config = *cfg - // If the user has provided a logger, use it. - ld.Config.Logf = cfg.Logf - } - if ld.Config.Logf == nil { - // If the GOPACKAGESDEBUG environment variable is set to true, - // but the user has not provided a logger, default to log.Printf. - if debug { - ld.Config.Logf = log.Printf - } else { - ld.Config.Logf = func(format string, args ...interface{}) {} - } - } - if ld.Config.Mode == 0 { - ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility. - } - if ld.Config.Env == nil { - ld.Config.Env = os.Environ() - } - if ld.Config.gocmdRunner == nil { - ld.Config.gocmdRunner = &gocommand.Runner{} - } - if ld.Context == nil { - ld.Context = context.Background() - } - if ld.Dir == "" { - if dir, err := os.Getwd(); err == nil { - ld.Dir = dir - } - } - - // Save the actually requested fields. We'll zero them out before returning packages to the user. - ld.requestedMode = ld.Mode - ld.Mode = impliedLoadMode(ld.Mode) - - if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { - if ld.Fset == nil { - ld.Fset = token.NewFileSet() - } - - // ParseFile is required even in LoadTypes mode - // because we load source if export data is missing. - if ld.ParseFile == nil { - ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { - const mode = parser.AllErrors | parser.ParseComments - return parser.ParseFile(fset, filename, src, mode) - } - } - } - - return ld -} - -// refine connects the supplied packages into a graph and then adds type -// and syntax information as requested by the LoadMode. -func (ld *loader) refine(response *driverResponse) ([]*Package, error) { - roots := response.Roots - rootMap := make(map[string]int, len(roots)) - for i, root := range roots { - rootMap[root] = i - } - ld.pkgs = make(map[string]*loaderPackage) - // first pass, fixup and build the map and roots - var initial = make([]*loaderPackage, len(roots)) - for _, pkg := range response.Packages { - rootIndex := -1 - if i, found := rootMap[pkg.ID]; found { - rootIndex = i - } - - // Overlays can invalidate export data. - // TODO(matloob): make this check fine-grained based on dependencies on overlaid files - exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe" - // This package needs type information if the caller requested types and the package is - // either a root, or it's a non-root and the user requested dependencies ... - needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) - // This package needs source if the call requested source (or types info, which implies source) - // and the package is either a root, or itas a non- root and the user requested dependencies... - needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || - // ... or if we need types and the exportData is invalid. We fall back to (incompletely) - // typechecking packages from source if they fail to compile. - (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" - lpkg := &loaderPackage{ - Package: pkg, - needtypes: needtypes, - needsrc: needsrc, - goVersion: response.GoVersion, - } - ld.pkgs[lpkg.ID] = lpkg - if rootIndex >= 0 { - initial[rootIndex] = lpkg - lpkg.initial = true - } - } - for i, root := range roots { - if initial[i] == nil { - return nil, fmt.Errorf("root package %v is missing", root) - } - } - - if ld.Mode&NeedImports != 0 { - // Materialize the import graph. - - const ( - white = 0 // new - grey = 1 // in progress - black = 2 // complete - ) - - // visit traverses the import graph, depth-first, - // and materializes the graph as Packages.Imports. - // - // Valid imports are saved in the Packages.Import map. - // Invalid imports (cycles and missing nodes) are saved in the importErrors map. - // Thus, even in the presence of both kinds of errors, - // the Import graph remains a DAG. - // - // visit returns whether the package needs src or has a transitive - // dependency on a package that does. These are the only packages - // for which we load source code. - var stack []*loaderPackage - var visit func(lpkg *loaderPackage) bool - visit = func(lpkg *loaderPackage) bool { - switch lpkg.color { - case black: - return lpkg.needsrc - case grey: - panic("internal error: grey node") - } - lpkg.color = grey - stack = append(stack, lpkg) // push - stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports - lpkg.Imports = make(map[string]*Package, len(stubs)) - for importPath, ipkg := range stubs { - var importErr error - imp := ld.pkgs[ipkg.ID] - if imp == nil { - // (includes package "C" when DisableCgo) - importErr = fmt.Errorf("missing package: %q", ipkg.ID) - } else if imp.color == grey { - importErr = fmt.Errorf("import cycle: %s", stack) - } - if importErr != nil { - if lpkg.importErrors == nil { - lpkg.importErrors = make(map[string]error) - } - lpkg.importErrors[importPath] = importErr - continue - } - - if visit(imp) { - lpkg.needsrc = true - } - lpkg.Imports[importPath] = imp.Package - } - - // Complete type information is required for the - // immediate dependencies of each source package. - if lpkg.needsrc && ld.Mode&NeedTypes != 0 { - for _, ipkg := range lpkg.Imports { - ld.pkgs[ipkg.ID].needtypes = true - } - } - - // NeedTypeSizes causes TypeSizes to be set even - // on packages for which types aren't needed. - if ld.Mode&NeedTypesSizes != 0 { - lpkg.TypesSizes = ld.sizes - } - stack = stack[:len(stack)-1] // pop - lpkg.color = black - - return lpkg.needsrc - } - - // For each initial package, create its import DAG. - for _, lpkg := range initial { - visit(lpkg) - } - - } else { - // !NeedImports: drop the stub (ID-only) import packages - // that we are not even going to try to resolve. - for _, lpkg := range initial { - lpkg.Imports = nil - } - } - - // Load type data and syntax if needed, starting at - // the initial packages (roots of the import DAG). - if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { - var wg sync.WaitGroup - for _, lpkg := range initial { - wg.Add(1) - go func(lpkg *loaderPackage) { - ld.loadRecursive(lpkg) - wg.Done() - }(lpkg) - } - wg.Wait() - } - - result := make([]*Package, len(initial)) - for i, lpkg := range initial { - result[i] = lpkg.Package - } - for i := range ld.pkgs { - // Clear all unrequested fields, - // to catch programs that use more than they request. - if ld.requestedMode&NeedName == 0 { - ld.pkgs[i].Name = "" - ld.pkgs[i].PkgPath = "" - } - if ld.requestedMode&NeedFiles == 0 { - ld.pkgs[i].GoFiles = nil - ld.pkgs[i].OtherFiles = nil - ld.pkgs[i].IgnoredFiles = nil - } - if ld.requestedMode&NeedEmbedFiles == 0 { - ld.pkgs[i].EmbedFiles = nil - } - if ld.requestedMode&NeedEmbedPatterns == 0 { - ld.pkgs[i].EmbedPatterns = nil - } - if ld.requestedMode&NeedCompiledGoFiles == 0 { - ld.pkgs[i].CompiledGoFiles = nil - } - if ld.requestedMode&NeedImports == 0 { - ld.pkgs[i].Imports = nil - } - if ld.requestedMode&NeedExportFile == 0 { - ld.pkgs[i].ExportFile = "" - } - if ld.requestedMode&NeedTypes == 0 { - ld.pkgs[i].Types = nil - ld.pkgs[i].Fset = nil - ld.pkgs[i].IllTyped = false - } - if ld.requestedMode&NeedSyntax == 0 { - ld.pkgs[i].Syntax = nil - } - if ld.requestedMode&NeedTypesInfo == 0 { - ld.pkgs[i].TypesInfo = nil - } - if ld.requestedMode&NeedTypesSizes == 0 { - ld.pkgs[i].TypesSizes = nil - } - if ld.requestedMode&NeedModule == 0 { - ld.pkgs[i].Module = nil - } - } - - return result, nil -} - -// loadRecursive loads the specified package and its dependencies, -// recursively, in parallel, in topological order. -// It is atomic and idempotent. -// Precondition: ld.Mode&NeedTypes. -func (ld *loader) loadRecursive(lpkg *loaderPackage) { - lpkg.loadOnce.Do(func() { - // Load the direct dependencies, in parallel. - var wg sync.WaitGroup - for _, ipkg := range lpkg.Imports { - imp := ld.pkgs[ipkg.ID] - wg.Add(1) - go func(imp *loaderPackage) { - ld.loadRecursive(imp) - wg.Done() - }(imp) - } - wg.Wait() - ld.loadPackage(lpkg) - }) -} - -// loadPackage loads the specified package. -// It must be called only once per Package, -// after immediate dependencies are loaded. -// Precondition: ld.Mode & NeedTypes. -func (ld *loader) loadPackage(lpkg *loaderPackage) { - if lpkg.PkgPath == "unsafe" { - // Fill in the blanks to avoid surprises. - lpkg.Types = types.Unsafe - lpkg.Fset = ld.Fset - lpkg.Syntax = []*ast.File{} - lpkg.TypesInfo = new(types.Info) - lpkg.TypesSizes = ld.sizes - return - } - - // Call NewPackage directly with explicit name. - // This avoids skew between golist and go/types when the files' - // package declarations are inconsistent. - lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) - lpkg.Fset = ld.Fset - - // Subtle: we populate all Types fields with an empty Package - // before loading export data so that export data processing - // never has to create a types.Package for an indirect dependency, - // which would then require that such created packages be explicitly - // inserted back into the Import graph as a final step after export data loading. - // (Hence this return is after the Types assignment.) - // The Diamond test exercises this case. - if !lpkg.needtypes && !lpkg.needsrc { - return - } - if !lpkg.needsrc { - if err := ld.loadFromExportData(lpkg); err != nil { - lpkg.Errors = append(lpkg.Errors, Error{ - Pos: "-", - Msg: err.Error(), - Kind: UnknownError, // e.g. can't find/open/parse export data - }) - } - return // not a source package, don't get syntax trees - } - - appendError := func(err error) { - // Convert various error types into the one true Error. - var errs []Error - switch err := err.(type) { - case Error: - // from driver - errs = append(errs, err) - - case *os.PathError: - // from parser - errs = append(errs, Error{ - Pos: err.Path + ":1", - Msg: err.Err.Error(), - Kind: ParseError, - }) - - case scanner.ErrorList: - // from parser - for _, err := range err { - errs = append(errs, Error{ - Pos: err.Pos.String(), - Msg: err.Msg, - Kind: ParseError, - }) - } - - case types.Error: - // from type checker - lpkg.TypeErrors = append(lpkg.TypeErrors, err) - errs = append(errs, Error{ - Pos: err.Fset.Position(err.Pos).String(), - Msg: err.Msg, - Kind: TypeError, - }) - - default: - // unexpected impoverished error from parser? - errs = append(errs, Error{ - Pos: "-", - Msg: err.Error(), - Kind: UnknownError, - }) - - // If you see this error message, please file a bug. - log.Printf("internal error: error %q (%T) without position", err, err) - } - - lpkg.Errors = append(lpkg.Errors, errs...) - } - - // If the go command on the PATH is newer than the runtime, - // then the go/{scanner,ast,parser,types} packages from the - // standard library may be unable to process the files - // selected by go list. - // - // There is currently no way to downgrade the effective - // version of the go command (see issue 52078), so we proceed - // with the newer go command but, in case of parse or type - // errors, we emit an additional diagnostic. - // - // See: - // - golang.org/issue/52078 (flag to set release tags) - // - golang.org/issue/50825 (gopls legacy version support) - // - golang.org/issue/55883 (go/packages confusing error) - // - // Should we assert a hard minimum of (currently) go1.16 here? - var runtimeVersion int - if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion { - defer func() { - if len(lpkg.Errors) > 0 { - appendError(Error{ - Pos: "-", - Msg: fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion), - Kind: UnknownError, - }) - } - }() - } - - if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { - // The config requested loading sources and types, but sources are missing. - // Add an error to the package and fall back to loading from export data. - appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) - _ = ld.loadFromExportData(lpkg) // ignore any secondary errors - - return // can't get syntax trees for this package - } - - files, errs := ld.parseFiles(lpkg.CompiledGoFiles) - for _, err := range errs { - appendError(err) - } - - lpkg.Syntax = files - if ld.Config.Mode&NeedTypes == 0 { - return - } - - lpkg.TypesInfo = &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Instances: make(map[*ast.Ident]types.Instance), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - } - versions.InitFileVersions(lpkg.TypesInfo) - lpkg.TypesSizes = ld.sizes - - importer := importerFunc(func(path string) (*types.Package, error) { - if path == "unsafe" { - return types.Unsafe, nil - } - - // The imports map is keyed by import path. - ipkg := lpkg.Imports[path] - if ipkg == nil { - if err := lpkg.importErrors[path]; err != nil { - return nil, err - } - // There was skew between the metadata and the - // import declarations, likely due to an edit - // race, or because the ParseFile feature was - // used to supply alternative file contents. - return nil, fmt.Errorf("no metadata for %s", path) - } - - if ipkg.Types != nil && ipkg.Types.Complete() { - return ipkg.Types, nil - } - log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg) - panic("unreachable") - }) - - // type-check - tc := &types.Config{ - Importer: importer, - - // Type-check bodies of functions only in initial packages. - // Example: for import graph A->B->C and initial packages {A,C}, - // we can ignore function bodies in B. - IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, - - Error: appendError, - Sizes: ld.sizes, // may be nil - } - if lpkg.Module != nil && lpkg.Module.GoVersion != "" { - typesinternal.SetGoVersion(tc, "go"+lpkg.Module.GoVersion) - } - if (ld.Mode & typecheckCgo) != 0 { - if !typesinternal.SetUsesCgo(tc) { - appendError(Error{ - Msg: "typecheckCgo requires Go 1.15+", - Kind: ListError, - }) - return - } - } - types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) - - lpkg.importErrors = nil // no longer needed - - // If !Cgo, the type-checker uses FakeImportC mode, so - // it doesn't invoke the importer for import "C", - // nor report an error for the import, - // or for any undefined C.f reference. - // We must detect this explicitly and correctly - // mark the package as IllTyped (by reporting an error). - // TODO(adonovan): if these errors are annoying, - // we could just set IllTyped quietly. - if tc.FakeImportC { - outer: - for _, f := range lpkg.Syntax { - for _, imp := range f.Imports { - if imp.Path.Value == `"C"` { - err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`} - appendError(err) - break outer - } - } - } - } - - // Record accumulated errors. - illTyped := len(lpkg.Errors) > 0 - if !illTyped { - for _, imp := range lpkg.Imports { - if imp.IllTyped { - illTyped = true - break - } - } - } - lpkg.IllTyped = illTyped -} - -// An importFunc is an implementation of the single-method -// types.Importer interface based on a function value. -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } - -// We use a counting semaphore to limit -// the number of parallel I/O calls per process. -var ioLimit = make(chan bool, 20) - -func (ld *loader) parseFile(filename string) (*ast.File, error) { - ld.parseCacheMu.Lock() - v, ok := ld.parseCache[filename] - if ok { - // cache hit - ld.parseCacheMu.Unlock() - <-v.ready - } else { - // cache miss - v = &parseValue{ready: make(chan struct{})} - ld.parseCache[filename] = v - ld.parseCacheMu.Unlock() - - var src []byte - for f, contents := range ld.Config.Overlay { - if sameFile(f, filename) { - src = contents - } - } - var err error - if src == nil { - ioLimit <- true // wait - src, err = os.ReadFile(filename) - <-ioLimit // signal - } - if err != nil { - v.err = err - } else { - v.f, v.err = ld.ParseFile(ld.Fset, filename, src) - } - - close(v.ready) - } - return v.f, v.err -} - -// parseFiles reads and parses the Go source files and returns the ASTs -// of the ones that could be at least partially parsed, along with a -// list of I/O and parse errors encountered. -// -// Because files are scanned in parallel, the token.Pos -// positions of the resulting ast.Files are not ordered. -func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { - var wg sync.WaitGroup - n := len(filenames) - parsed := make([]*ast.File, n) - errors := make([]error, n) - for i, file := range filenames { - if ld.Config.Context.Err() != nil { - parsed[i] = nil - errors[i] = ld.Config.Context.Err() - continue - } - wg.Add(1) - go func(i int, filename string) { - parsed[i], errors[i] = ld.parseFile(filename) - wg.Done() - }(i, file) - } - wg.Wait() - - // Eliminate nils, preserving order. - var o int - for _, f := range parsed { - if f != nil { - parsed[o] = f - o++ - } - } - parsed = parsed[:o] - - o = 0 - for _, err := range errors { - if err != nil { - errors[o] = err - o++ - } - } - errors = errors[:o] - - return parsed, errors -} - -// sameFile returns true if x and y have the same basename and denote -// the same file. -func sameFile(x, y string) bool { - if x == y { - // It could be the case that y doesn't exist. - // For instance, it may be an overlay file that - // hasn't been written to disk. To handle that case - // let x == y through. (We added the exact absolute path - // string to the CompiledGoFiles list, so the unwritten - // overlay case implies x==y.) - return true - } - if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation) - if xi, err := os.Stat(x); err == nil { - if yi, err := os.Stat(y); err == nil { - return os.SameFile(xi, yi) - } - } - } - return false -} - -// loadFromExportData ensures that type information is present for the specified -// package, loading it from an export data file on the first request. -// On success it sets lpkg.Types to a new Package. -func (ld *loader) loadFromExportData(lpkg *loaderPackage) error { - if lpkg.PkgPath == "" { - log.Fatalf("internal error: Package %s has no PkgPath", lpkg) - } - - // Because gcexportdata.Read has the potential to create or - // modify the types.Package for each node in the transitive - // closure of dependencies of lpkg, all exportdata operations - // must be sequential. (Finer-grained locking would require - // changes to the gcexportdata API.) - // - // The exportMu lock guards the lpkg.Types field and the - // types.Package it points to, for each loaderPackage in the graph. - // - // Not all accesses to Package.Pkg need to be protected by exportMu: - // graph ordering ensures that direct dependencies of source - // packages are fully loaded before the importer reads their Pkg field. - ld.exportMu.Lock() - defer ld.exportMu.Unlock() - - if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { - return nil // cache hit - } - - lpkg.IllTyped = true // fail safe - - if lpkg.ExportFile == "" { - // Errors while building export data will have been printed to stderr. - return fmt.Errorf("no export data file") - } - f, err := os.Open(lpkg.ExportFile) - if err != nil { - return err - } - defer f.Close() - - // Read gc export data. - // - // We don't currently support gccgo export data because all - // underlying workspaces use the gc toolchain. (Even build - // systems that support gccgo don't use it for workspace - // queries.) - r, err := gcexportdata.NewReader(f) - if err != nil { - return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) - } - - // Build the view. - // - // The gcexportdata machinery has no concept of package ID. - // It identifies packages by their PkgPath, which although not - // globally unique is unique within the scope of one invocation - // of the linker, type-checker, or gcexportdata. - // - // So, we must build a PkgPath-keyed view of the global - // (conceptually ID-keyed) cache of packages and pass it to - // gcexportdata. The view must contain every existing - // package that might possibly be mentioned by the - // current package---its transitive closure. - // - // In loadPackage, we unconditionally create a types.Package for - // each dependency so that export data loading does not - // create new ones. - // - // TODO(adonovan): it would be simpler and more efficient - // if the export data machinery invoked a callback to - // get-or-create a package instead of a map. - // - view := make(map[string]*types.Package) // view seen by gcexportdata - seen := make(map[*loaderPackage]bool) // all visited packages - var visit func(pkgs map[string]*Package) - visit = func(pkgs map[string]*Package) { - for _, p := range pkgs { - lpkg := ld.pkgs[p.ID] - if !seen[lpkg] { - seen[lpkg] = true - view[lpkg.PkgPath] = lpkg.Types - visit(lpkg.Imports) - } - } - } - visit(lpkg.Imports) - - viewLen := len(view) + 1 // adding the self package - // Parse the export data. - // (May modify incomplete packages in view but not create new ones.) - tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) - if err != nil { - return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) - } - if _, ok := view["go.shape"]; ok { - // Account for the pseudopackage "go.shape" that gets - // created by generic code. - viewLen++ - } - if viewLen != len(view) { - log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath) - } - - lpkg.Types = tpkg - lpkg.IllTyped = false - return nil -} - -// impliedLoadMode returns loadMode with its dependencies. -func impliedLoadMode(loadMode LoadMode) LoadMode { - if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 { - // All these things require knowing the import graph. - loadMode |= NeedImports - } - - return loadMode -} - -func usesExportData(cfg *Config) bool { - return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 -} - -var _ interface{} = io.Discard // assert build toolchain is go1.16 or later diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go deleted file mode 100644 index a1dcc40b..00000000 --- a/vendor/golang.org/x/tools/go/packages/visit.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package packages - -import ( - "fmt" - "os" - "sort" -) - -// Visit visits all the packages in the import graph whose roots are -// pkgs, calling the optional pre function the first time each package -// is encountered (preorder), and the optional post function after a -// package's dependencies have been visited (postorder). -// The boolean result of pre(pkg) determines whether -// the imports of package pkg are visited. -func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { - seen := make(map[*Package]bool) - var visit func(*Package) - visit = func(pkg *Package) { - if !seen[pkg] { - seen[pkg] = true - - if pre == nil || pre(pkg) { - paths := make([]string, 0, len(pkg.Imports)) - for path := range pkg.Imports { - paths = append(paths, path) - } - sort.Strings(paths) // Imports is a map, this makes visit stable - for _, path := range paths { - visit(pkg.Imports[path]) - } - } - - if post != nil { - post(pkg) - } - } - } - for _, pkg := range pkgs { - visit(pkg) - } -} - -// PrintErrors prints to os.Stderr the accumulated errors of all -// packages in the import graph rooted at pkgs, dependencies first. -// PrintErrors returns the number of errors printed. -func PrintErrors(pkgs []*Package) int { - var n int - Visit(pkgs, nil, func(pkg *Package) { - for _, err := range pkg.Errors { - fmt.Fprintln(os.Stderr, err) - n++ - } - }) - return n -} diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go deleted file mode 100644 index 11d5c8c3..00000000 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ /dev/null @@ -1,752 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package objectpath defines a naming scheme for types.Objects -// (that is, named entities in Go programs) relative to their enclosing -// package. -// -// Type-checker objects are canonical, so they are usually identified by -// their address in memory (a pointer), but a pointer has meaning only -// within one address space. By contrast, objectpath names allow the -// identity of an object to be sent from one program to another, -// establishing a correspondence between types.Object variables that are -// distinct but logically equivalent. -// -// A single object may have multiple paths. In this example, -// -// type A struct{ X int } -// type B A -// -// the field X has two paths due to its membership of both A and B. -// The For(obj) function always returns one of these paths, arbitrarily -// but consistently. -package objectpath - -import ( - "fmt" - "go/types" - "strconv" - "strings" - - "golang.org/x/tools/internal/typeparams" -) - -// A Path is an opaque name that identifies a types.Object -// relative to its package. Conceptually, the name consists of a -// sequence of destructuring operations applied to the package scope -// to obtain the original object. -// The name does not include the package itself. -type Path string - -// Encoding -// -// An object path is a textual and (with training) human-readable encoding -// of a sequence of destructuring operators, starting from a types.Package. -// The sequences represent a path through the package/object/type graph. -// We classify these operators by their type: -// -// PO package->object Package.Scope.Lookup -// OT object->type Object.Type -// TT type->type Type.{Elem,Key,Params,Results,Underlying} [EKPRU] -// TO type->object Type.{At,Field,Method,Obj} [AFMO] -// -// All valid paths start with a package and end at an object -// and thus may be defined by the regular language: -// -// objectpath = PO (OT TT* TO)* -// -// The concrete encoding follows directly: -// - The only PO operator is Package.Scope.Lookup, which requires an identifier. -// - The only OT operator is Object.Type, -// which we encode as '.' because dot cannot appear in an identifier. -// - The TT operators are encoded as [EKPRUTC]; -// one of these (TypeParam) requires an integer operand, -// which is encoded as a string of decimal digits. -// - The TO operators are encoded as [AFMO]; -// three of these (At,Field,Method) require an integer operand, -// which is encoded as a string of decimal digits. -// These indices are stable across different representations -// of the same package, even source and export data. -// The indices used are implementation specific and may not correspond to -// the argument to the go/types function. -// -// In the example below, -// -// package p -// -// type T interface { -// f() (a string, b struct{ X int }) -// } -// -// field X has the path "T.UM0.RA1.F0", -// representing the following sequence of operations: -// -// p.Lookup("T") T -// .Type().Underlying().Method(0). f -// .Type().Results().At(1) b -// .Type().Field(0) X -// -// The encoding is not maximally compact---every R or P is -// followed by an A, for example---but this simplifies the -// encoder and decoder. -const ( - // object->type operators - opType = '.' // .Type() (Object) - - // type->type operators - opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map) - opKey = 'K' // .Key() (Map) - opParams = 'P' // .Params() (Signature) - opResults = 'R' // .Results() (Signature) - opUnderlying = 'U' // .Underlying() (Named) - opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature) - opConstraint = 'C' // .Constraint() (TypeParam) - - // type->object operators - opAt = 'A' // .At(i) (Tuple) - opField = 'F' // .Field(i) (Struct) - opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored) - opObj = 'O' // .Obj() (Named, TypeParam) -) - -// For is equivalent to new(Encoder).For(obj). -// -// It may be more efficient to reuse a single Encoder across several calls. -func For(obj types.Object) (Path, error) { - return new(Encoder).For(obj) -} - -// An Encoder amortizes the cost of encoding the paths of multiple objects. -// The zero value of an Encoder is ready to use. -type Encoder struct { - scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects -} - -// For returns the path to an object relative to its package, -// or an error if the object is not accessible from the package's Scope. -// -// The For function guarantees to return a path only for the following objects: -// - package-level types -// - exported package-level non-types -// - methods -// - parameter and result variables -// - struct fields -// These objects are sufficient to define the API of their package. -// The objects described by a package's export data are drawn from this set. -// -// The set of objects accessible from a package's Scope depends on -// whether the package was produced by type-checking syntax, or -// reading export data; the latter may have a smaller Scope since -// export data trims objects that are not reachable from an exported -// declaration. For example, the For function will return a path for -// an exported method of an unexported type that is not reachable -// from any public declaration; this path will cause the Object -// function to fail if called on a package loaded from export data. -// TODO(adonovan): is this a bug or feature? Should this package -// compute accessibility in the same way? -// -// For does not return a path for predeclared names, imported package -// names, local names, and unexported package-level names (except -// types). -// -// Example: given this definition, -// -// package p -// -// type T interface { -// f() (a string, b struct{ X int }) -// } -// -// For(X) would return a path that denotes the following sequence of operations: -// -// p.Scope().Lookup("T") (TypeName T) -// .Type().Underlying().Method(0). (method Func f) -// .Type().Results().At(1) (field Var b) -// .Type().Field(0) (field Var X) -// -// where p is the package (*types.Package) to which X belongs. -func (enc *Encoder) For(obj types.Object) (Path, error) { - pkg := obj.Pkg() - - // This table lists the cases of interest. - // - // Object Action - // ------ ------ - // nil reject - // builtin reject - // pkgname reject - // label reject - // var - // package-level accept - // func param/result accept - // local reject - // struct field accept - // const - // package-level accept - // local reject - // func - // package-level accept - // init functions reject - // concrete method accept - // interface method accept - // type - // package-level accept - // local reject - // - // The only accessible package-level objects are members of pkg itself. - // - // The cases are handled in four steps: - // - // 1. reject nil and builtin - // 2. accept package-level objects - // 3. reject obviously invalid objects - // 4. search the API for the path to the param/result/field/method. - - // 1. reference to nil or builtin? - if pkg == nil { - return "", fmt.Errorf("predeclared %s has no path", obj) - } - scope := pkg.Scope() - - // 2. package-level object? - if scope.Lookup(obj.Name()) == obj { - // Only exported objects (and non-exported types) have a path. - // Non-exported types may be referenced by other objects. - if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() { - return "", fmt.Errorf("no path for non-exported %v", obj) - } - return Path(obj.Name()), nil - } - - // 3. Not a package-level object. - // Reject obviously non-viable cases. - switch obj := obj.(type) { - case *types.TypeName: - if _, ok := obj.Type().(*types.TypeParam); !ok { - // With the exception of type parameters, only package-level type names - // have a path. - return "", fmt.Errorf("no path for %v", obj) - } - case *types.Const, // Only package-level constants have a path. - *types.Label, // Labels are function-local. - *types.PkgName: // PkgNames are file-local. - return "", fmt.Errorf("no path for %v", obj) - - case *types.Var: - // Could be: - // - a field (obj.IsField()) - // - a func parameter or result - // - a local var. - // Sadly there is no way to distinguish - // a param/result from a local - // so we must proceed to the find. - - case *types.Func: - // A func, if not package-level, must be a method. - if recv := obj.Type().(*types.Signature).Recv(); recv == nil { - return "", fmt.Errorf("func is not a method: %v", obj) - } - - if path, ok := enc.concreteMethod(obj); ok { - // Fast path for concrete methods that avoids looping over scope. - return path, nil - } - - default: - panic(obj) - } - - // 4. Search the API for the path to the var (field/param/result) or method. - - // First inspect package-level named types. - // In the presence of path aliases, these give - // the best paths because non-types may - // refer to types, but not the reverse. - empty := make([]byte, 0, 48) // initial space - objs := enc.scopeObjects(scope) - for _, o := range objs { - tname, ok := o.(*types.TypeName) - if !ok { - continue // handle non-types in second pass - } - - path := append(empty, o.Name()...) - path = append(path, opType) - - T := o.Type() - - if tname.IsAlias() { - // type alias - if r := find(obj, T, path, nil); r != nil { - return Path(r), nil - } - } else { - if named, _ := T.(*types.Named); named != nil { - if r := findTypeParam(obj, named.TypeParams(), path, nil); r != nil { - // generic named type - return Path(r), nil - } - } - // defined (named) type - if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); r != nil { - return Path(r), nil - } - } - } - - // Then inspect everything else: - // non-types, and declared methods of defined types. - for _, o := range objs { - path := append(empty, o.Name()...) - if _, ok := o.(*types.TypeName); !ok { - if o.Exported() { - // exported non-type (const, var, func) - if r := find(obj, o.Type(), append(path, opType), nil); r != nil { - return Path(r), nil - } - } - continue - } - - // Inspect declared methods of defined types. - if T, ok := o.Type().(*types.Named); ok { - path = append(path, opType) - // The method index here is always with respect - // to the underlying go/types data structures, - // which ultimately derives from source order - // and must be preserved by export data. - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - path2 := appendOpArg(path, opMethod, i) - if m == obj { - return Path(path2), nil // found declared method - } - if r := find(obj, m.Type(), append(path2, opType), nil); r != nil { - return Path(r), nil - } - } - } - } - - return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path()) -} - -func appendOpArg(path []byte, op byte, arg int) []byte { - path = append(path, op) - path = strconv.AppendInt(path, int64(arg), 10) - return path -} - -// concreteMethod returns the path for meth, which must have a non-nil receiver. -// The second return value indicates success and may be false if the method is -// an interface method or if it is an instantiated method. -// -// This function is just an optimization that avoids the general scope walking -// approach. You are expected to fall back to the general approach if this -// function fails. -func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) { - // Concrete methods can only be declared on package-scoped named types. For - // that reason we can skip the expensive walk over the package scope: the - // path will always be package -> named type -> method. We can trivially get - // the type name from the receiver, and only have to look over the type's - // methods to find the method index. - // - // Methods on generic types require special consideration, however. Consider - // the following package: - // - // L1: type S[T any] struct{} - // L2: func (recv S[A]) Foo() { recv.Bar() } - // L3: func (recv S[B]) Bar() { } - // L4: type Alias = S[int] - // L5: func _[T any]() { var s S[int]; s.Foo() } - // - // The receivers of methods on generic types are instantiations. L2 and L3 - // instantiate S with the type-parameters A and B, which are scoped to the - // respective methods. L4 and L5 each instantiate S with int. Each of these - // instantiations has its own method set, full of methods (and thus objects) - // with receivers whose types are the respective instantiations. In other - // words, we have - // - // S[A].Foo, S[A].Bar - // S[B].Foo, S[B].Bar - // S[int].Foo, S[int].Bar - // - // We may thus be trying to produce object paths for any of these objects. - // - // S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo - // and S.Bar, which are the paths that this function naturally produces. - // - // S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that - // don't correspond to the origin methods. For S[int], this is significant. - // The most precise object path for S[int].Foo, for example, is Alias.Foo, - // not S.Foo. Our function, however, would produce S.Foo, which would - // resolve to a different object. - // - // For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are - // still the correct paths, since only the origin methods have meaningful - // paths. But this is likely only true for trivial cases and has edge cases. - // Since this function is only an optimization, we err on the side of giving - // up, deferring to the slower but definitely correct algorithm. Most users - // of objectpath will only be giving us origin methods, anyway, as referring - // to instantiated methods is usually not useful. - - if typeparams.OriginMethod(meth) != meth { - return "", false - } - - recvT := meth.Type().(*types.Signature).Recv().Type() - if ptr, ok := recvT.(*types.Pointer); ok { - recvT = ptr.Elem() - } - - named, ok := recvT.(*types.Named) - if !ok { - return "", false - } - - if types.IsInterface(named) { - // Named interfaces don't have to be package-scoped - // - // TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface - // methods, too, I think. - return "", false - } - - // Preallocate space for the name, opType, opMethod, and some digits. - name := named.Obj().Name() - path := make([]byte, 0, len(name)+8) - path = append(path, name...) - path = append(path, opType) - - // Method indices are w.r.t. the go/types data structures, - // ultimately deriving from source order, - // which is preserved by export data. - for i := 0; i < named.NumMethods(); i++ { - if named.Method(i) == meth { - path = appendOpArg(path, opMethod, i) - return Path(path), true - } - } - - // Due to golang/go#59944, go/types fails to associate the receiver with - // certain methods on cgo types. - // - // TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go - // versions gopls supports. - return "", false - // panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named))) -} - -// find finds obj within type T, returning the path to it, or nil if not found. -// -// The seen map is used to short circuit cycles through type parameters. If -// nil, it will be allocated as necessary. -func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte { - switch T := T.(type) { - case *types.Basic, *types.Named: - // Named types belonging to pkg were handled already, - // so T must belong to another package. No path. - return nil - case *types.Pointer: - return find(obj, T.Elem(), append(path, opElem), seen) - case *types.Slice: - return find(obj, T.Elem(), append(path, opElem), seen) - case *types.Array: - return find(obj, T.Elem(), append(path, opElem), seen) - case *types.Chan: - return find(obj, T.Elem(), append(path, opElem), seen) - case *types.Map: - if r := find(obj, T.Key(), append(path, opKey), seen); r != nil { - return r - } - return find(obj, T.Elem(), append(path, opElem), seen) - case *types.Signature: - if r := findTypeParam(obj, T.TypeParams(), path, seen); r != nil { - return r - } - if r := find(obj, T.Params(), append(path, opParams), seen); r != nil { - return r - } - return find(obj, T.Results(), append(path, opResults), seen) - case *types.Struct: - for i := 0; i < T.NumFields(); i++ { - fld := T.Field(i) - path2 := appendOpArg(path, opField, i) - if fld == obj { - return path2 // found field var - } - if r := find(obj, fld.Type(), append(path2, opType), seen); r != nil { - return r - } - } - return nil - case *types.Tuple: - for i := 0; i < T.Len(); i++ { - v := T.At(i) - path2 := appendOpArg(path, opAt, i) - if v == obj { - return path2 // found param/result var - } - if r := find(obj, v.Type(), append(path2, opType), seen); r != nil { - return r - } - } - return nil - case *types.Interface: - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - path2 := appendOpArg(path, opMethod, i) - if m == obj { - return path2 // found interface method - } - if r := find(obj, m.Type(), append(path2, opType), seen); r != nil { - return r - } - } - return nil - case *types.TypeParam: - name := T.Obj() - if name == obj { - return append(path, opObj) - } - if seen[name] { - return nil - } - if seen == nil { - seen = make(map[*types.TypeName]bool) - } - seen[name] = true - if r := find(obj, T.Constraint(), append(path, opConstraint), seen); r != nil { - return r - } - return nil - } - panic(T) -} - -func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte { - for i := 0; i < list.Len(); i++ { - tparam := list.At(i) - path2 := appendOpArg(path, opTypeParam, i) - if r := find(obj, tparam, path2, seen); r != nil { - return r - } - } - return nil -} - -// Object returns the object denoted by path p within the package pkg. -func Object(pkg *types.Package, p Path) (types.Object, error) { - pathstr := string(p) - if pathstr == "" { - return nil, fmt.Errorf("empty path") - } - - var pkgobj, suffix string - if dot := strings.IndexByte(pathstr, opType); dot < 0 { - pkgobj = pathstr - } else { - pkgobj = pathstr[:dot] - suffix = pathstr[dot:] // suffix starts with "." - } - - obj := pkg.Scope().Lookup(pkgobj) - if obj == nil { - return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj) - } - - // abstraction of *types.{Pointer,Slice,Array,Chan,Map} - type hasElem interface { - Elem() types.Type - } - // abstraction of *types.{Named,Signature} - type hasTypeParams interface { - TypeParams() *types.TypeParamList - } - // abstraction of *types.{Named,TypeParam} - type hasObj interface { - Obj() *types.TypeName - } - - // The loop state is the pair (t, obj), - // exactly one of which is non-nil, initially obj. - // All suffixes start with '.' (the only object->type operation), - // followed by optional type->type operations, - // then a type->object operation. - // The cycle then repeats. - var t types.Type - for suffix != "" { - code := suffix[0] - suffix = suffix[1:] - - // Codes [AFM] have an integer operand. - var index int - switch code { - case opAt, opField, opMethod, opTypeParam: - rest := strings.TrimLeft(suffix, "0123456789") - numerals := suffix[:len(suffix)-len(rest)] - suffix = rest - i, err := strconv.Atoi(numerals) - if err != nil { - return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code) - } - index = int(i) - case opObj: - // no operand - default: - // The suffix must end with a type->object operation. - if suffix == "" { - return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code) - } - } - - if code == opType { - if t != nil { - return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType) - } - t = obj.Type() - obj = nil - continue - } - - if t == nil { - return nil, fmt.Errorf("invalid path: code %q in object context", code) - } - - // Inv: t != nil, obj == nil - - switch code { - case opElem: - hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t) - } - t = hasElem.Elem() - - case opKey: - mapType, ok := t.(*types.Map) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t) - } - t = mapType.Key() - - case opParams: - sig, ok := t.(*types.Signature) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - t = sig.Params() - - case opResults: - sig, ok := t.(*types.Signature) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - t = sig.Results() - - case opUnderlying: - named, ok := t.(*types.Named) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named)", code, t, t) - } - t = named.Underlying() - - case opTypeParam: - hasTypeParams, ok := t.(hasTypeParams) // Named, Signature - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t) - } - tparams := hasTypeParams.TypeParams() - if n := tparams.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - t = tparams.At(index) - - case opConstraint: - tparam, ok := t.(*types.TypeParam) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t) - } - t = tparam.Constraint() - - case opAt: - tuple, ok := t.(*types.Tuple) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want tuple)", code, t, t) - } - if n := tuple.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - obj = tuple.At(index) - t = nil - - case opField: - structType, ok := t.(*types.Struct) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t) - } - if n := structType.NumFields(); index >= n { - return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n) - } - obj = structType.Field(index) - t = nil - - case opMethod: - switch t := t.(type) { - case *types.Interface: - if index >= t.NumMethods() { - return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) - } - obj = t.Method(index) // Id-ordered - - case *types.Named: - if index >= t.NumMethods() { - return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) - } - obj = t.Method(index) - - default: - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t) - } - t = nil - - case opObj: - hasObj, ok := t.(hasObj) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t) - } - obj = hasObj.Obj() - t = nil - - default: - return nil, fmt.Errorf("invalid path: unknown code %q", code) - } - } - - if obj.Pkg() != pkg { - return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj) - } - - return obj, nil // success -} - -// scopeObjects is a memoization of scope objects. -// Callers must not modify the result. -func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object { - m := enc.scopeMemo - if m == nil { - m = make(map[*types.Scope][]types.Object) - enc.scopeMemo = m - } - objs, ok := m[scope] - if !ok { - names := scope.Names() // allocates and sorts - objs = make([]types.Object, len(names)) - for i, name := range names { - objs[i] = scope.Lookup(name) - } - m[scope] = objs - } - return objs -} diff --git a/vendor/golang.org/x/tools/imports/forward.go b/vendor/golang.org/x/tools/imports/forward.go deleted file mode 100644 index cb6db889..00000000 --- a/vendor/golang.org/x/tools/imports/forward.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package imports implements a Go pretty-printer (like package "go/format") -// that also adds or removes import statements as necessary. -package imports // import "golang.org/x/tools/imports" - -import ( - "log" - "os" - - "golang.org/x/tools/internal/gocommand" - intimp "golang.org/x/tools/internal/imports" -) - -// Options specifies options for processing files. -type Options struct { - Fragment bool // Accept fragment of a source file (no package statement) - AllErrors bool // Report all errors (not just the first 10 on different lines) - - Comments bool // Print comments (true if nil *Options provided) - TabIndent bool // Use tabs for indent (true if nil *Options provided) - TabWidth int // Tab width (8 if nil *Options provided) - - FormatOnly bool // Disable the insertion and deletion of imports -} - -// Debug controls verbose logging. -var Debug = false - -// LocalPrefix is a comma-separated string of import path prefixes, which, if -// set, instructs Process to sort the import paths with the given prefixes -// into another group after 3rd-party packages. -var LocalPrefix string - -// Process formats and adjusts imports for the provided file. -// If opt is nil the defaults are used, and if src is nil the source -// is read from the filesystem. -// -// Note that filename's directory influences which imports can be chosen, -// so it is important that filename be accurate. -// To process data “as if” it were in filename, pass the data as a non-nil src. -func Process(filename string, src []byte, opt *Options) ([]byte, error) { - var err error - if src == nil { - src, err = os.ReadFile(filename) - if err != nil { - return nil, err - } - } - if opt == nil { - opt = &Options{Comments: true, TabIndent: true, TabWidth: 8} - } - intopt := &intimp.Options{ - Env: &intimp.ProcessEnv{ - GocmdRunner: &gocommand.Runner{}, - }, - LocalPrefix: LocalPrefix, - AllErrors: opt.AllErrors, - Comments: opt.Comments, - FormatOnly: opt.FormatOnly, - Fragment: opt.Fragment, - TabIndent: opt.TabIndent, - TabWidth: opt.TabWidth, - } - if Debug { - intopt.Env.Logf = log.Printf - } - return intimp.Process(filename, src, intopt) -} - -// VendorlessPath returns the devendorized version of the import path ipath. -// For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b". -func VendorlessPath(ipath string) string { - return intimp.VendorlessPath(ipath) -} diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go deleted file mode 100644 index a6cf0e64..00000000 --- a/vendor/golang.org/x/tools/internal/event/core/event.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package core provides support for event based telemetry. -package core - -import ( - "fmt" - "time" - - "golang.org/x/tools/internal/event/label" -) - -// Event holds the information about an event of note that occurred. -type Event struct { - at time.Time - - // As events are often on the stack, storing the first few labels directly - // in the event can avoid an allocation at all for the very common cases of - // simple events. - // The length needs to be large enough to cope with the majority of events - // but no so large as to cause undue stack pressure. - // A log message with two values will use 3 labels (one for each value and - // one for the message itself). - - static [3]label.Label // inline storage for the first few labels - dynamic []label.Label // dynamically sized storage for remaining labels -} - -// eventLabelMap implements label.Map for a the labels of an Event. -type eventLabelMap struct { - event Event -} - -func (ev Event) At() time.Time { return ev.at } - -func (ev Event) Format(f fmt.State, r rune) { - if !ev.at.IsZero() { - fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 ")) - } - for index := 0; ev.Valid(index); index++ { - if l := ev.Label(index); l.Valid() { - fmt.Fprintf(f, "\n\t%v", l) - } - } -} - -func (ev Event) Valid(index int) bool { - return index >= 0 && index < len(ev.static)+len(ev.dynamic) -} - -func (ev Event) Label(index int) label.Label { - if index < len(ev.static) { - return ev.static[index] - } - return ev.dynamic[index-len(ev.static)] -} - -func (ev Event) Find(key label.Key) label.Label { - for _, l := range ev.static { - if l.Key() == key { - return l - } - } - for _, l := range ev.dynamic { - if l.Key() == key { - return l - } - } - return label.Label{} -} - -func MakeEvent(static [3]label.Label, labels []label.Label) Event { - return Event{ - static: static, - dynamic: labels, - } -} - -// CloneEvent event returns a copy of the event with the time adjusted to at. -func CloneEvent(ev Event, at time.Time) Event { - ev.at = at - return ev -} diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go deleted file mode 100644 index 05f3a9a5..00000000 --- a/vendor/golang.org/x/tools/internal/event/core/export.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package core - -import ( - "context" - "sync/atomic" - "time" - "unsafe" - - "golang.org/x/tools/internal/event/label" -) - -// Exporter is a function that handles events. -// It may return a modified context and event. -type Exporter func(context.Context, Event, label.Map) context.Context - -var ( - exporter unsafe.Pointer -) - -// SetExporter sets the global exporter function that handles all events. -// The exporter is called synchronously from the event call site, so it should -// return quickly so as not to hold up user code. -func SetExporter(e Exporter) { - p := unsafe.Pointer(&e) - if e == nil { - // &e is always valid, and so p is always valid, but for the early abort - // of ProcessEvent to be efficient it needs to make the nil check on the - // pointer without having to dereference it, so we make the nil function - // also a nil pointer - p = nil - } - atomic.StorePointer(&exporter, p) -} - -// deliver is called to deliver an event to the supplied exporter. -// it will fill in the time. -func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context { - // add the current time to the event - ev.at = time.Now() - // hand the event off to the current exporter - return exporter(ctx, ev, ev) -} - -// Export is called to deliver an event to the global exporter if set. -func Export(ctx context.Context, ev Event) context.Context { - // get the global exporter and abort early if there is not one - exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) - if exporterPtr == nil { - return ctx - } - return deliver(ctx, *exporterPtr, ev) -} - -// ExportPair is called to deliver a start event to the supplied exporter. -// It also returns a function that will deliver the end event to the same -// exporter. -// It will fill in the time. -func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) { - // get the global exporter and abort early if there is not one - exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) - if exporterPtr == nil { - return ctx, func() {} - } - ctx = deliver(ctx, *exporterPtr, begin) - return ctx, func() { deliver(ctx, *exporterPtr, end) } -} diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go deleted file mode 100644 index 06c1d461..00000000 --- a/vendor/golang.org/x/tools/internal/event/core/fast.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package core - -import ( - "context" - - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" -) - -// Log1 takes a message and one label delivers a log event to the exporter. -// It is a customized version of Print that is faster and does no allocation. -func Log1(ctx context.Context, message string, t1 label.Label) { - Export(ctx, MakeEvent([3]label.Label{ - keys.Msg.Of(message), - t1, - }, nil)) -} - -// Log2 takes a message and two labels and delivers a log event to the exporter. -// It is a customized version of Print that is faster and does no allocation. -func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) { - Export(ctx, MakeEvent([3]label.Label{ - keys.Msg.Of(message), - t1, - t2, - }, nil)) -} - -// Metric1 sends a label event to the exporter with the supplied labels. -func Metric1(ctx context.Context, t1 label.Label) context.Context { - return Export(ctx, MakeEvent([3]label.Label{ - keys.Metric.New(), - t1, - }, nil)) -} - -// Metric2 sends a label event to the exporter with the supplied labels. -func Metric2(ctx context.Context, t1, t2 label.Label) context.Context { - return Export(ctx, MakeEvent([3]label.Label{ - keys.Metric.New(), - t1, - t2, - }, nil)) -} - -// Start1 sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) { - return ExportPair(ctx, - MakeEvent([3]label.Label{ - keys.Start.Of(name), - t1, - }, nil), - MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} - -// Start2 sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) { - return ExportPair(ctx, - MakeEvent([3]label.Label{ - keys.Start.Of(name), - t1, - t2, - }, nil), - MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go deleted file mode 100644 index 5dc6e6ba..00000000 --- a/vendor/golang.org/x/tools/internal/event/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package event provides a set of packages that cover the main -// concepts of telemetry in an implementation agnostic way. -package event diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go deleted file mode 100644 index 4d55e577..00000000 --- a/vendor/golang.org/x/tools/internal/event/event.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package event - -import ( - "context" - - "golang.org/x/tools/internal/event/core" - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" -) - -// Exporter is a function that handles events. -// It may return a modified context and event. -type Exporter func(context.Context, core.Event, label.Map) context.Context - -// SetExporter sets the global exporter function that handles all events. -// The exporter is called synchronously from the event call site, so it should -// return quickly so as not to hold up user code. -func SetExporter(e Exporter) { - core.SetExporter(core.Exporter(e)) -} - -// Log takes a message and a label list and combines them into a single event -// before delivering them to the exporter. -func Log(ctx context.Context, message string, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Msg.Of(message), - }, labels)) -} - -// IsLog returns true if the event was built by the Log function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsLog(ev core.Event) bool { - return ev.Label(0).Key() == keys.Msg -} - -// Error takes a message and a label list and combines them into a single event -// before delivering them to the exporter. It captures the error in the -// delivered event. -func Error(ctx context.Context, message string, err error, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Msg.Of(message), - keys.Err.Of(err), - }, labels)) -} - -// IsError returns true if the event was built by the Error function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsError(ev core.Event) bool { - return ev.Label(0).Key() == keys.Msg && - ev.Label(1).Key() == keys.Err -} - -// Metric sends a label event to the exporter with the supplied labels. -func Metric(ctx context.Context, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Metric.New(), - }, labels)) -} - -// IsMetric returns true if the event was built by the Metric function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsMetric(ev core.Event) bool { - return ev.Label(0).Key() == keys.Metric -} - -// Label sends a label event to the exporter with the supplied labels. -func Label(ctx context.Context, labels ...label.Label) context.Context { - return core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Label.New(), - }, labels)) -} - -// IsLabel returns true if the event was built by the Label function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsLabel(ev core.Event) bool { - return ev.Label(0).Key() == keys.Label -} - -// Start sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) { - return core.ExportPair(ctx, - core.MakeEvent([3]label.Label{ - keys.Start.Of(name), - }, labels), - core.MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} - -// IsStart returns true if the event was built by the Start function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsStart(ev core.Event) bool { - return ev.Label(0).Key() == keys.Start -} - -// IsEnd returns true if the event was built by the End function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsEnd(ev core.Event) bool { - return ev.Label(0).Key() == keys.End -} - -// Detach returns a context without an associated span. -// This allows the creation of spans that are not children of the current span. -func Detach(ctx context.Context) context.Context { - return core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Detach.New(), - }, nil)) -} - -// IsDetach returns true if the event was built by the Detach function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsDetach(ev core.Event) bool { - return ev.Label(0).Key() == keys.Detach -} diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go deleted file mode 100644 index a02206e3..00000000 --- a/vendor/golang.org/x/tools/internal/event/keys/keys.go +++ /dev/null @@ -1,564 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package keys - -import ( - "fmt" - "io" - "math" - "strconv" - - "golang.org/x/tools/internal/event/label" -) - -// Value represents a key for untyped values. -type Value struct { - name string - description string -} - -// New creates a new Key for untyped values. -func New(name, description string) *Value { - return &Value{name: name, description: description} -} - -func (k *Value) Name() string { return k.name } -func (k *Value) Description() string { return k.description } - -func (k *Value) Format(w io.Writer, buf []byte, l label.Label) { - fmt.Fprint(w, k.From(l)) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Value) Get(lm label.Map) interface{} { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return nil -} - -// From can be used to get a value from a Label. -func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() } - -// Of creates a new Label with this key and the supplied value. -func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) } - -// Tag represents a key for tagging labels that have no value. -// These are used when the existence of the label is the entire information it -// carries, such as marking events to be of a specific kind, or from a specific -// package. -type Tag struct { - name string - description string -} - -// NewTag creates a new Key for tagging labels. -func NewTag(name, description string) *Tag { - return &Tag{name: name, description: description} -} - -func (k *Tag) Name() string { return k.name } -func (k *Tag) Description() string { return k.description } - -func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {} - -// New creates a new Label with this key. -func (k *Tag) New() label.Label { return label.OfValue(k, nil) } - -// Int represents a key -type Int struct { - name string - description string -} - -// NewInt creates a new Key for int values. -func NewInt(name, description string) *Int { - return &Int{name: name, description: description} -} - -func (k *Int) Name() string { return k.name } -func (k *Int) Description() string { return k.description } - -func (k *Int) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int) Get(lm label.Map) int { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int) From(t label.Label) int { return int(t.Unpack64()) } - -// Int8 represents a key -type Int8 struct { - name string - description string -} - -// NewInt8 creates a new Key for int8 values. -func NewInt8(name, description string) *Int8 { - return &Int8{name: name, description: description} -} - -func (k *Int8) Name() string { return k.name } -func (k *Int8) Description() string { return k.description } - -func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int8) Get(lm label.Map) int8 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) } - -// Int16 represents a key -type Int16 struct { - name string - description string -} - -// NewInt16 creates a new Key for int16 values. -func NewInt16(name, description string) *Int16 { - return &Int16{name: name, description: description} -} - -func (k *Int16) Name() string { return k.name } -func (k *Int16) Description() string { return k.description } - -func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int16) Get(lm label.Map) int16 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) } - -// Int32 represents a key -type Int32 struct { - name string - description string -} - -// NewInt32 creates a new Key for int32 values. -func NewInt32(name, description string) *Int32 { - return &Int32{name: name, description: description} -} - -func (k *Int32) Name() string { return k.name } -func (k *Int32) Description() string { return k.description } - -func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int32) Get(lm label.Map) int32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) } - -// Int64 represents a key -type Int64 struct { - name string - description string -} - -// NewInt64 creates a new Key for int64 values. -func NewInt64(name, description string) *Int64 { - return &Int64{name: name, description: description} -} - -func (k *Int64) Name() string { return k.name } -func (k *Int64) Description() string { return k.description } - -func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, k.From(l), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int64) Get(lm label.Map) int64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) } - -// UInt represents a key -type UInt struct { - name string - description string -} - -// NewUInt creates a new Key for uint values. -func NewUInt(name, description string) *UInt { - return &UInt{name: name, description: description} -} - -func (k *UInt) Name() string { return k.name } -func (k *UInt) Description() string { return k.description } - -func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt) Get(lm label.Map) uint { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) } - -// UInt8 represents a key -type UInt8 struct { - name string - description string -} - -// NewUInt8 creates a new Key for uint8 values. -func NewUInt8(name, description string) *UInt8 { - return &UInt8{name: name, description: description} -} - -func (k *UInt8) Name() string { return k.name } -func (k *UInt8) Description() string { return k.description } - -func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt8) Get(lm label.Map) uint8 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) } - -// UInt16 represents a key -type UInt16 struct { - name string - description string -} - -// NewUInt16 creates a new Key for uint16 values. -func NewUInt16(name, description string) *UInt16 { - return &UInt16{name: name, description: description} -} - -func (k *UInt16) Name() string { return k.name } -func (k *UInt16) Description() string { return k.description } - -func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt16) Get(lm label.Map) uint16 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) } - -// UInt32 represents a key -type UInt32 struct { - name string - description string -} - -// NewUInt32 creates a new Key for uint32 values. -func NewUInt32(name, description string) *UInt32 { - return &UInt32{name: name, description: description} -} - -func (k *UInt32) Name() string { return k.name } -func (k *UInt32) Description() string { return k.description } - -func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt32) Get(lm label.Map) uint32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) } - -// UInt64 represents a key -type UInt64 struct { - name string - description string -} - -// NewUInt64 creates a new Key for uint64 values. -func NewUInt64(name, description string) *UInt64 { - return &UInt64{name: name, description: description} -} - -func (k *UInt64) Name() string { return k.name } -func (k *UInt64) Description() string { return k.description } - -func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, k.From(l), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt64) Get(lm label.Map) uint64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() } - -// Float32 represents a key -type Float32 struct { - name string - description string -} - -// NewFloat32 creates a new Key for float32 values. -func NewFloat32(name, description string) *Float32 { - return &Float32{name: name, description: description} -} - -func (k *Float32) Name() string { return k.name } -func (k *Float32) Description() string { return k.description } - -func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Float32) Of(v float32) label.Label { - return label.Of64(k, uint64(math.Float32bits(v))) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Float32) Get(lm label.Map) float32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Float32) From(t label.Label) float32 { - return math.Float32frombits(uint32(t.Unpack64())) -} - -// Float64 represents a key -type Float64 struct { - name string - description string -} - -// NewFloat64 creates a new Key for int64 values. -func NewFloat64(name, description string) *Float64 { - return &Float64{name: name, description: description} -} - -func (k *Float64) Name() string { return k.name } -func (k *Float64) Description() string { return k.description } - -func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Float64) Of(v float64) label.Label { - return label.Of64(k, math.Float64bits(v)) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Float64) Get(lm label.Map) float64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Float64) From(t label.Label) float64 { - return math.Float64frombits(t.Unpack64()) -} - -// String represents a key -type String struct { - name string - description string -} - -// NewString creates a new Key for int64 values. -func NewString(name, description string) *String { - return &String{name: name, description: description} -} - -func (k *String) Name() string { return k.name } -func (k *String) Description() string { return k.description } - -func (k *String) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendQuote(buf, k.From(l))) -} - -// Of creates a new Label with this key and the supplied value. -func (k *String) Of(v string) label.Label { return label.OfString(k, v) } - -// Get can be used to get a label for the key from a label.Map. -func (k *String) Get(lm label.Map) string { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return "" -} - -// From can be used to get a value from a Label. -func (k *String) From(t label.Label) string { return t.UnpackString() } - -// Boolean represents a key -type Boolean struct { - name string - description string -} - -// NewBoolean creates a new Key for bool values. -func NewBoolean(name, description string) *Boolean { - return &Boolean{name: name, description: description} -} - -func (k *Boolean) Name() string { return k.name } -func (k *Boolean) Description() string { return k.description } - -func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendBool(buf, k.From(l))) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Boolean) Of(v bool) label.Label { - if v { - return label.Of64(k, 1) - } - return label.Of64(k, 0) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Boolean) Get(lm label.Map) bool { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return false -} - -// From can be used to get a value from a Label. -func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 } - -// Error represents a key -type Error struct { - name string - description string -} - -// NewError creates a new Key for int64 values. -func NewError(name, description string) *Error { - return &Error{name: name, description: description} -} - -func (k *Error) Name() string { return k.name } -func (k *Error) Description() string { return k.description } - -func (k *Error) Format(w io.Writer, buf []byte, l label.Label) { - io.WriteString(w, k.From(l).Error()) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Error) Get(lm label.Map) error { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return nil -} - -// From can be used to get a value from a Label. -func (k *Error) From(t label.Label) error { - err, _ := t.UnpackValue().(error) - return err -} diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go deleted file mode 100644 index 7e958665..00000000 --- a/vendor/golang.org/x/tools/internal/event/keys/standard.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package keys - -var ( - // Msg is a key used to add message strings to label lists. - Msg = NewString("message", "a readable message") - // Label is a key used to indicate an event adds labels to the context. - Label = NewTag("label", "a label context marker") - // Start is used for things like traces that have a name. - Start = NewString("start", "span start") - // Metric is a key used to indicate an event records metrics. - End = NewTag("end", "a span end marker") - // Metric is a key used to indicate an event records metrics. - Detach = NewTag("detach", "a span detach marker") - // Err is a key used to add error values to label lists. - Err = NewError("error", "an error that occurred") - // Metric is a key used to indicate an event records metrics. - Metric = NewTag("metric", "a metric event marker") -) diff --git a/vendor/golang.org/x/tools/internal/event/keys/util.go b/vendor/golang.org/x/tools/internal/event/keys/util.go deleted file mode 100644 index c0e8e731..00000000 --- a/vendor/golang.org/x/tools/internal/event/keys/util.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package keys - -import ( - "sort" - "strings" -) - -// Join returns a canonical join of the keys in S: -// a sorted comma-separated string list. -func Join[S ~[]T, T ~string](s S) string { - strs := make([]string, 0, len(s)) - for _, v := range s { - strs = append(strs, string(v)) - } - sort.Strings(strs) - return strings.Join(strs, ",") -} diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go deleted file mode 100644 index 0f526e1f..00000000 --- a/vendor/golang.org/x/tools/internal/event/label/label.go +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package label - -import ( - "fmt" - "io" - "reflect" - "unsafe" -) - -// Key is used as the identity of a Label. -// Keys are intended to be compared by pointer only, the name should be unique -// for communicating with external systems, but it is not required or enforced. -type Key interface { - // Name returns the key name. - Name() string - // Description returns a string that can be used to describe the value. - Description() string - - // Format is used in formatting to append the value of the label to the - // supplied buffer. - // The formatter may use the supplied buf as a scratch area to avoid - // allocations. - Format(w io.Writer, buf []byte, l Label) -} - -// Label holds a key and value pair. -// It is normally used when passing around lists of labels. -type Label struct { - key Key - packed uint64 - untyped interface{} -} - -// Map is the interface to a collection of Labels indexed by key. -type Map interface { - // Find returns the label that matches the supplied key. - Find(key Key) Label -} - -// List is the interface to something that provides an iterable -// list of labels. -// Iteration should start from 0 and continue until Valid returns false. -type List interface { - // Valid returns true if the index is within range for the list. - // It does not imply the label at that index will itself be valid. - Valid(index int) bool - // Label returns the label at the given index. - Label(index int) Label -} - -// list implements LabelList for a list of Labels. -type list struct { - labels []Label -} - -// filter wraps a LabelList filtering out specific labels. -type filter struct { - keys []Key - underlying List -} - -// listMap implements LabelMap for a simple list of labels. -type listMap struct { - labels []Label -} - -// mapChain implements LabelMap for a list of underlying LabelMap. -type mapChain struct { - maps []Map -} - -// OfValue creates a new label from the key and value. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} } - -// UnpackValue assumes the label was built using LabelOfValue and returns the value -// that was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) UnpackValue() interface{} { return t.untyped } - -// Of64 creates a new label from a key and a uint64. This is often -// used for non uint64 values that can be packed into a uint64. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} } - -// Unpack64 assumes the label was built using LabelOf64 and returns the value that -// was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) Unpack64() uint64 { return t.packed } - -type stringptr unsafe.Pointer - -// OfString creates a new label from a key and a string. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func OfString(k Key, v string) Label { - hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) - return Label{ - key: k, - packed: uint64(hdr.Len), - untyped: stringptr(hdr.Data), - } -} - -// UnpackString assumes the label was built using LabelOfString and returns the -// value that was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) UnpackString() string { - var v string - hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) - hdr.Data = uintptr(t.untyped.(stringptr)) - hdr.Len = int(t.packed) - return v -} - -// Valid returns true if the Label is a valid one (it has a key). -func (t Label) Valid() bool { return t.key != nil } - -// Key returns the key of this Label. -func (t Label) Key() Key { return t.key } - -// Format is used for debug printing of labels. -func (t Label) Format(f fmt.State, r rune) { - if !t.Valid() { - io.WriteString(f, `nil`) - return - } - io.WriteString(f, t.Key().Name()) - io.WriteString(f, "=") - var buf [128]byte - t.Key().Format(f, buf[:0], t) -} - -func (l *list) Valid(index int) bool { - return index >= 0 && index < len(l.labels) -} - -func (l *list) Label(index int) Label { - return l.labels[index] -} - -func (f *filter) Valid(index int) bool { - return f.underlying.Valid(index) -} - -func (f *filter) Label(index int) Label { - l := f.underlying.Label(index) - for _, f := range f.keys { - if l.Key() == f { - return Label{} - } - } - return l -} - -func (lm listMap) Find(key Key) Label { - for _, l := range lm.labels { - if l.Key() == key { - return l - } - } - return Label{} -} - -func (c mapChain) Find(key Key) Label { - for _, src := range c.maps { - l := src.Find(key) - if l.Valid() { - return l - } - } - return Label{} -} - -var emptyList = &list{} - -func NewList(labels ...Label) List { - if len(labels) == 0 { - return emptyList - } - return &list{labels: labels} -} - -func Filter(l List, keys ...Key) List { - if len(keys) == 0 { - return l - } - return &filter{keys: keys, underlying: l} -} - -func NewMap(labels ...Label) Map { - return listMap{labels: labels} -} - -func MergeMaps(srcs ...Map) Map { - var nonNil []Map - for _, src := range srcs { - if src != nil { - nonNil = append(nonNil, src) - } - } - if len(nonNil) == 1 { - return nonNil[0] - } - return mapChain{maps: nonNil} -} diff --git a/vendor/golang.org/x/tools/internal/event/tag/tag.go b/vendor/golang.org/x/tools/internal/event/tag/tag.go deleted file mode 100644 index 581b26c2..00000000 --- a/vendor/golang.org/x/tools/internal/event/tag/tag.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package tag provides the labels used for telemetry throughout gopls. -package tag - -import ( - "golang.org/x/tools/internal/event/keys" -) - -var ( - // create the label keys we use - Method = keys.NewString("method", "") - StatusCode = keys.NewString("status.code", "") - StatusMessage = keys.NewString("status.message", "") - RPCID = keys.NewString("id", "") - RPCDirection = keys.NewString("direction", "") - File = keys.NewString("file", "") - Directory = keys.New("directory", "") - URI = keys.New("URI", "") - Package = keys.NewString("package", "") // sorted comma-separated list of Package IDs - PackagePath = keys.NewString("package_path", "") - Query = keys.New("query", "") - Snapshot = keys.NewUInt64("snapshot", "") - Operation = keys.NewString("operation", "") - - Position = keys.New("position", "") - Category = keys.NewString("category", "") - PackageCount = keys.NewInt("packages", "") - Files = keys.New("files", "") - Port = keys.NewInt("port", "") - Type = keys.New("type", "") - HoverKind = keys.NewString("hoverkind", "") - - NewServer = keys.NewString("new_server", "A new server was added") - EndServer = keys.NewString("end_server", "A server was shut down") - - ServerID = keys.NewString("server", "The server ID an event is related to") - Logfile = keys.NewString("logfile", "") - DebugAddress = keys.NewString("debug_address", "") - GoplsPath = keys.NewString("gopls_path", "") - ClientID = keys.NewString("client_id", "") - - Level = keys.NewInt("level", "The logging level") -) - -var ( - // create the stats we measure - Started = keys.NewInt64("started", "Count of started RPCs.") - ReceivedBytes = keys.NewInt64("received_bytes", "Bytes received.") //, unit.Bytes) - SentBytes = keys.NewInt64("sent_bytes", "Bytes sent.") //, unit.Bytes) - Latency = keys.NewFloat64("latency_ms", "Elapsed time in milliseconds") //, unit.Milliseconds) -) - -const ( - Inbound = "in" - Outbound = "out" -) diff --git a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go deleted file mode 100644 index d98b0db2..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file contains the remaining vestiges of -// $GOROOT/src/go/internal/gcimporter/bimport.go. - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" - "sync" -) - -func errorf(format string, args ...interface{}) { - panic(fmt.Sprintf(format, args...)) -} - -const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go - -// Synthesize a token.Pos -type fakeFileSet struct { - fset *token.FileSet - files map[string]*fileInfo -} - -type fileInfo struct { - file *token.File - lastline int -} - -const maxlines = 64 * 1024 - -func (s *fakeFileSet) pos(file string, line, column int) token.Pos { - // TODO(mdempsky): Make use of column. - - // Since we don't know the set of needed file positions, we reserve maxlines - // positions per file. We delay calling token.File.SetLines until all - // positions have been calculated (by way of fakeFileSet.setLines), so that - // we can avoid setting unnecessary lines. See also golang/go#46586. - f := s.files[file] - if f == nil { - f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} - s.files[file] = f - } - if line > maxlines { - line = 1 - } - if line > f.lastline { - f.lastline = line - } - - // Return a fake position assuming that f.file consists only of newlines. - return token.Pos(f.file.Base() + line - 1) -} - -func (s *fakeFileSet) setLines() { - fakeLinesOnce.Do(func() { - fakeLines = make([]int, maxlines) - for i := range fakeLines { - fakeLines[i] = i - } - }) - for _, f := range s.files { - f.file.SetLines(fakeLines[:f.lastline]) - } -} - -var ( - fakeLines []int - fakeLinesOnce sync.Once -) - -func chanDir(d int) types.ChanDir { - // tag values must match the constants in cmd/compile/internal/gc/go.go - switch d { - case 1 /* Crecv */ : - return types.RecvOnly - case 2 /* Csend */ : - return types.SendOnly - case 3 /* Cboth */ : - return types.SendRecv - default: - errorf("unexpected channel dir %d", d) - return 0 - } -} - -var predeclOnce sync.Once -var predecl []types.Type // initialized lazily - -func predeclared() []types.Type { - predeclOnce.Do(func() { - // initialize lazily to be sure that all - // elements have been initialized before - predecl = []types.Type{ // basic types - types.Typ[types.Bool], - types.Typ[types.Int], - types.Typ[types.Int8], - types.Typ[types.Int16], - types.Typ[types.Int32], - types.Typ[types.Int64], - types.Typ[types.Uint], - types.Typ[types.Uint8], - types.Typ[types.Uint16], - types.Typ[types.Uint32], - types.Typ[types.Uint64], - types.Typ[types.Uintptr], - types.Typ[types.Float32], - types.Typ[types.Float64], - types.Typ[types.Complex64], - types.Typ[types.Complex128], - types.Typ[types.String], - - // basic type aliases - types.Universe.Lookup("byte").Type(), - types.Universe.Lookup("rune").Type(), - - // error - types.Universe.Lookup("error").Type(), - - // untyped types - types.Typ[types.UntypedBool], - types.Typ[types.UntypedInt], - types.Typ[types.UntypedRune], - types.Typ[types.UntypedFloat], - types.Typ[types.UntypedComplex], - types.Typ[types.UntypedString], - types.Typ[types.UntypedNil], - - // package unsafe - types.Typ[types.UnsafePointer], - - // invalid type - types.Typ[types.Invalid], // only appears in packages with errors - - // used internally by gc; never used by this package or in .a files - anyType{}, - } - predecl = append(predecl, additionalPredeclared()...) - }) - return predecl -} - -type anyType struct{} - -func (t anyType) Underlying() types.Type { return t } -func (t anyType) String() string { return "any" } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go deleted file mode 100644 index f6437feb..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go. - -// This file implements FindExportData. - -package gcimporter - -import ( - "bufio" - "fmt" - "io" - "strconv" - "strings" -) - -func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) { - // See $GOROOT/include/ar.h. - hdr := make([]byte, 16+12+6+6+8+10+2) - _, err = io.ReadFull(r, hdr) - if err != nil { - return - } - // leave for debugging - if false { - fmt.Printf("header: %s", hdr) - } - s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) - length, err := strconv.Atoi(s) - size = int64(length) - if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { - err = fmt.Errorf("invalid archive header") - return - } - name = strings.TrimSpace(string(hdr[:16])) - return -} - -// FindExportData positions the reader r at the beginning of the -// export data section of an underlying GC-created object/archive -// file by reading from it. The reader must be positioned at the -// start of the file before calling this function. The hdr result -// is the string before the export data, either "$$" or "$$B". -// The size result is the length of the export data in bytes, or -1 if not known. -func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) { - // Read first line to make sure this is an object file. - line, err := r.ReadSlice('\n') - if err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - - if string(line) == "!\n" { - // Archive file. Scan to __.PKGDEF. - var name string - if name, size, err = readGopackHeader(r); err != nil { - return - } - - // First entry should be __.PKGDEF. - if name != "__.PKGDEF" { - err = fmt.Errorf("go archive is missing __.PKGDEF") - return - } - - // Read first line of __.PKGDEF data, so that line - // is once again the first line of the input. - if line, err = r.ReadSlice('\n'); err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - size -= int64(len(line)) - } - - // Now at __.PKGDEF in archive or still at beginning of file. - // Either way, line should begin with "go object ". - if !strings.HasPrefix(string(line), "go object ") { - err = fmt.Errorf("not a Go object file") - return - } - - // Skip over object header to export data. - // Begins after first line starting with $$. - for line[0] != '$' { - if line, err = r.ReadSlice('\n'); err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - size -= int64(len(line)) - } - hdr = string(line) - if size < 0 { - size = -1 - } - - return -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go deleted file mode 100644 index 2d078ccb..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file is a reduced copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go. - -// Package gcimporter provides various functions for reading -// gc-generated object files that can be used to implement the -// Importer interface defined by the Go 1.5 standard library package. -// -// The encoding is deterministic: if the encoder is applied twice to -// the same types.Package data structure, both encodings are equal. -// This property may be important to avoid spurious changes in -// applications such as build systems. -// -// However, the encoder is not necessarily idempotent. Importing an -// exported package may yield a types.Package that, while it -// represents the same set of Go types as the original, may differ in -// the details of its internal representation. Because of these -// differences, re-encoding the imported package may yield a -// different, but equally valid, encoding of the package. -package gcimporter // import "golang.org/x/tools/internal/gcimporter" - -import ( - "bufio" - "bytes" - "fmt" - "go/build" - "go/token" - "go/types" - "io" - "os" - "os/exec" - "path/filepath" - "strings" - "sync" -) - -const ( - // Enable debug during development: it adds some additional checks, and - // prevents errors from being recovered. - debug = false - - // If trace is set, debugging output is printed to std out. - trace = false -) - -var exportMap sync.Map // package dir → func() (string, bool) - -// lookupGorootExport returns the location of the export data -// (normally found in the build cache, but located in GOROOT/pkg -// in prior Go releases) for the package located in pkgDir. -// -// (We use the package's directory instead of its import path -// mainly to simplify handling of the packages in src/vendor -// and cmd/vendor.) -func lookupGorootExport(pkgDir string) (string, bool) { - f, ok := exportMap.Load(pkgDir) - if !ok { - var ( - listOnce sync.Once - exportPath string - ) - f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) { - listOnce.Do(func() { - cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir) - cmd.Dir = build.Default.GOROOT - var output []byte - output, err := cmd.Output() - if err != nil { - return - } - - exports := strings.Split(string(bytes.TrimSpace(output)), "\n") - if len(exports) != 1 { - return - } - - exportPath = exports[0] - }) - - return exportPath, exportPath != "" - }) - } - - return f.(func() (string, bool))() -} - -var pkgExts = [...]string{".a", ".o"} - -// FindPkg returns the filename and unique package id for an import -// path based on package information provided by build.Import (using -// the build.Default build.Context). A relative srcDir is interpreted -// relative to the current working directory. -// If no file was found, an empty filename is returned. -func FindPkg(path, srcDir string) (filename, id string) { - if path == "" { - return - } - - var noext string - switch { - default: - // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" - // Don't require the source files to be present. - if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 - srcDir = abs - } - bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary) - if bp.PkgObj == "" { - var ok bool - if bp.Goroot && bp.Dir != "" { - filename, ok = lookupGorootExport(bp.Dir) - } - if !ok { - id = path // make sure we have an id to print in error message - return - } - } else { - noext = strings.TrimSuffix(bp.PkgObj, ".a") - id = bp.ImportPath - } - - case build.IsLocalImport(path): - // "./x" -> "/this/directory/x.ext", "/this/directory/x" - noext = filepath.Join(srcDir, path) - id = noext - - case filepath.IsAbs(path): - // for completeness only - go/build.Import - // does not support absolute imports - // "/x" -> "/x.ext", "/x" - noext = path - id = path - } - - if false { // for debugging - if path != id { - fmt.Printf("%s -> %s\n", path, id) - } - } - - if filename != "" { - if f, err := os.Stat(filename); err == nil && !f.IsDir() { - return - } - } - - // try extensions - for _, ext := range pkgExts { - filename = noext + ext - if f, err := os.Stat(filename); err == nil && !f.IsDir() { - return - } - } - - filename = "" // not found - return -} - -// Import imports a gc-generated package given its import path and srcDir, adds -// the corresponding package object to the packages map, and returns the object. -// The packages map must contain all packages already imported. -func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) { - var rc io.ReadCloser - var filename, id string - if lookup != nil { - // With custom lookup specified, assume that caller has - // converted path to a canonical import path for use in the map. - if path == "unsafe" { - return types.Unsafe, nil - } - id = path - - // No need to re-import if the package was imported completely before. - if pkg = packages[id]; pkg != nil && pkg.Complete() { - return - } - f, err := lookup(path) - if err != nil { - return nil, err - } - rc = f - } else { - filename, id = FindPkg(path, srcDir) - if filename == "" { - if path == "unsafe" { - return types.Unsafe, nil - } - return nil, fmt.Errorf("can't find import: %q", id) - } - - // no need to re-import if the package was imported completely before - if pkg = packages[id]; pkg != nil && pkg.Complete() { - return - } - - // open file - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - // add file name to error - err = fmt.Errorf("%s: %v", filename, err) - } - }() - rc = f - } - defer rc.Close() - - var hdr string - var size int64 - buf := bufio.NewReader(rc) - if hdr, size, err = FindExportData(buf); err != nil { - return - } - - switch hdr { - case "$$B\n": - var data []byte - data, err = io.ReadAll(buf) - if err != nil { - break - } - - // TODO(gri): allow clients of go/importer to provide a FileSet. - // Or, define a new standard go/types/gcexportdata package. - fset := token.NewFileSet() - - // Select appropriate importer. - if len(data) > 0 { - switch data[0] { - case 'v', 'c', 'd': // binary, till go1.10 - return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0]) - - case 'i': // indexed, till go1.19 - _, pkg, err := IImportData(fset, packages, data[1:], id) - return pkg, err - - case 'u': // unified, from go1.20 - _, pkg, err := UImportData(fset, packages, data[1:size], id) - return pkg, err - - default: - l := len(data) - if l > 10 { - l = 10 - } - return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id) - } - } - - default: - err = fmt.Errorf("unknown export data header: %q", hdr) - } - - return -} - -func deref(typ types.Type) types.Type { - if p, _ := typ.(*types.Pointer); p != nil { - return p.Elem() - } - return typ -} - -type byPath []*types.Package - -func (a byPath) Len() int { return len(a) } -func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go deleted file mode 100644 index 2ee8c701..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go +++ /dev/null @@ -1,1321 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Indexed binary package export. -// This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go; -// see that file for specification of the format. - -package gcimporter - -import ( - "bytes" - "encoding/binary" - "fmt" - "go/constant" - "go/token" - "go/types" - "io" - "math/big" - "reflect" - "sort" - "strconv" - "strings" - - "golang.org/x/tools/go/types/objectpath" - "golang.org/x/tools/internal/tokeninternal" -) - -// IExportShallow encodes "shallow" export data for the specified package. -// -// No promises are made about the encoding other than that it can be decoded by -// the same version of IIExportShallow. If you plan to save export data in the -// file system, be sure to include a cryptographic digest of the executable in -// the key to avoid version skew. -// -// If the provided reportf func is non-nil, it will be used for reporting bugs -// encountered during export. -// TODO(rfindley): remove reportf when we are confident enough in the new -// objectpath encoding. -func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) { - // In principle this operation can only fail if out.Write fails, - // but that's impossible for bytes.Buffer---and as a matter of - // fact iexportCommon doesn't even check for I/O errors. - // TODO(adonovan): handle I/O errors properly. - // TODO(adonovan): use byte slices throughout, avoiding copying. - const bundle, shallow = false, true - var out bytes.Buffer - err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}) - return out.Bytes(), err -} - -// IImportShallow decodes "shallow" types.Package data encoded by -// IExportShallow in the same executable. This function cannot import data from -// cmd/compile or gcexportdata.Write. -// -// The importer calls getPackages to obtain package symbols for all -// packages mentioned in the export data, including the one being -// decoded. -// -// If the provided reportf func is non-nil, it will be used for reporting bugs -// encountered during import. -// TODO(rfindley): remove reportf when we are confident enough in the new -// objectpath encoding. -func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, reportf ReportFunc) (*types.Package, error) { - const bundle = false - const shallow = true - pkgs, err := iimportCommon(fset, getPackages, data, bundle, path, shallow, reportf) - if err != nil { - return nil, err - } - return pkgs[0], nil -} - -// ReportFunc is the type of a function used to report formatted bugs. -type ReportFunc = func(string, ...interface{}) - -// Current bundled export format version. Increase with each format change. -// 0: initial implementation -const bundleVersion = 0 - -// IExportData writes indexed export data for pkg to out. -// -// If no file set is provided, position info will be missing. -// The package path of the top-level package will not be recorded, -// so that calls to IImportData can override with a provided package path. -func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error { - const bundle, shallow = false, false - return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}) -} - -// IExportBundle writes an indexed export bundle for pkgs to out. -func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { - const bundle, shallow = true, false - return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs) -} - -func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package) (err error) { - if !debug { - defer func() { - if e := recover(); e != nil { - if ierr, ok := e.(internalError); ok { - err = ierr - return - } - // Not an internal error; panic again. - panic(e) - } - }() - } - - p := iexporter{ - fset: fset, - version: version, - shallow: shallow, - allPkgs: map[*types.Package]bool{}, - stringIndex: map[string]uint64{}, - declIndex: map[types.Object]uint64{}, - tparamNames: map[types.Object]string{}, - typIndex: map[types.Type]uint64{}, - } - if !bundle { - p.localpkg = pkgs[0] - } - - for i, pt := range predeclared() { - p.typIndex[pt] = uint64(i) - } - if len(p.typIndex) > predeclReserved { - panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)) - } - - // Initialize work queue with exported declarations. - for _, pkg := range pkgs { - scope := pkg.Scope() - for _, name := range scope.Names() { - if token.IsExported(name) { - p.pushDecl(scope.Lookup(name)) - } - } - - if bundle { - // Ensure pkg and its imports are included in the index. - p.allPkgs[pkg] = true - for _, imp := range pkg.Imports() { - p.allPkgs[imp] = true - } - } - } - - // Loop until no more work. - for !p.declTodo.empty() { - p.doDecl(p.declTodo.popHead()) - } - - // Produce index of offset of each file record in files. - var files intWriter - var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i - if p.shallow { - fileOffset = make([]uint64, len(p.fileInfos)) - for i, info := range p.fileInfos { - fileOffset[i] = uint64(files.Len()) - p.encodeFile(&files, info.file, info.needed) - } - } - - // Append indices to data0 section. - dataLen := uint64(p.data0.Len()) - w := p.newWriter() - w.writeIndex(p.declIndex) - - if bundle { - w.uint64(uint64(len(pkgs))) - for _, pkg := range pkgs { - w.pkg(pkg) - imps := pkg.Imports() - w.uint64(uint64(len(imps))) - for _, imp := range imps { - w.pkg(imp) - } - } - } - w.flush() - - // Assemble header. - var hdr intWriter - if bundle { - hdr.uint64(bundleVersion) - } - hdr.uint64(uint64(p.version)) - hdr.uint64(uint64(p.strings.Len())) - if p.shallow { - hdr.uint64(uint64(files.Len())) - hdr.uint64(uint64(len(fileOffset))) - for _, offset := range fileOffset { - hdr.uint64(offset) - } - } - hdr.uint64(dataLen) - - // Flush output. - io.Copy(out, &hdr) - io.Copy(out, &p.strings) - if p.shallow { - io.Copy(out, &files) - } - io.Copy(out, &p.data0) - - return nil -} - -// encodeFile writes to w a representation of the file sufficient to -// faithfully restore position information about all needed offsets. -// Mutates the needed array. -func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) { - _ = needed[0] // precondition: needed is non-empty - - w.uint64(p.stringOff(file.Name())) - - size := uint64(file.Size()) - w.uint64(size) - - // Sort the set of needed offsets. Duplicates are harmless. - sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] }) - - lines := tokeninternal.GetLines(file) // byte offset of each line start - w.uint64(uint64(len(lines))) - - // Rather than record the entire array of line start offsets, - // we save only a sparse list of (index, offset) pairs for - // the start of each line that contains a needed position. - var sparse [][2]int // (index, offset) pairs -outer: - for i, lineStart := range lines { - lineEnd := size - if i < len(lines)-1 { - lineEnd = uint64(lines[i+1]) - } - // Does this line contains a needed offset? - if needed[0] < lineEnd { - sparse = append(sparse, [2]int{i, lineStart}) - for needed[0] < lineEnd { - needed = needed[1:] - if len(needed) == 0 { - break outer - } - } - } - } - - // Delta-encode the columns. - w.uint64(uint64(len(sparse))) - var prev [2]int - for _, pair := range sparse { - w.uint64(uint64(pair[0] - prev[0])) - w.uint64(uint64(pair[1] - prev[1])) - prev = pair - } -} - -// writeIndex writes out an object index. mainIndex indicates whether -// we're writing out the main index, which is also read by -// non-compiler tools and includes a complete package description -// (i.e., name and height). -func (w *exportWriter) writeIndex(index map[types.Object]uint64) { - type pkgObj struct { - obj types.Object - name string // qualified name; differs from obj.Name for type params - } - // Build a map from packages to objects from that package. - pkgObjs := map[*types.Package][]pkgObj{} - - // For the main index, make sure to include every package that - // we reference, even if we're not exporting (or reexporting) - // any symbols from it. - if w.p.localpkg != nil { - pkgObjs[w.p.localpkg] = nil - } - for pkg := range w.p.allPkgs { - pkgObjs[pkg] = nil - } - - for obj := range index { - name := w.p.exportName(obj) - pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name}) - } - - var pkgs []*types.Package - for pkg, objs := range pkgObjs { - pkgs = append(pkgs, pkg) - - sort.Slice(objs, func(i, j int) bool { - return objs[i].name < objs[j].name - }) - } - - sort.Slice(pkgs, func(i, j int) bool { - return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j]) - }) - - w.uint64(uint64(len(pkgs))) - for _, pkg := range pkgs { - w.string(w.exportPath(pkg)) - w.string(pkg.Name()) - w.uint64(uint64(0)) // package height is not needed for go/types - - objs := pkgObjs[pkg] - w.uint64(uint64(len(objs))) - for _, obj := range objs { - w.string(obj.name) - w.uint64(index[obj.obj]) - } - } -} - -// exportName returns the 'exported' name of an object. It differs from -// obj.Name() only for type parameters (see tparamExportName for details). -func (p *iexporter) exportName(obj types.Object) (res string) { - if name := p.tparamNames[obj]; name != "" { - return name - } - return obj.Name() -} - -type iexporter struct { - fset *token.FileSet - out *bytes.Buffer - version int - - shallow bool // don't put types from other packages in the index - objEncoder *objectpath.Encoder // encodes objects from other packages in shallow mode; lazily allocated - localpkg *types.Package // (nil in bundle mode) - - // allPkgs tracks all packages that have been referenced by - // the export data, so we can ensure to include them in the - // main index. - allPkgs map[*types.Package]bool - - declTodo objQueue - - strings intWriter - stringIndex map[string]uint64 - - // In shallow mode, object positions are encoded as (file, offset). - // Each file is recorded as a line-number table. - // Only the lines of needed positions are saved faithfully. - fileInfo map[*token.File]uint64 // value is index in fileInfos - fileInfos []*filePositions - - data0 intWriter - declIndex map[types.Object]uint64 - tparamNames map[types.Object]string // typeparam->exported name - typIndex map[types.Type]uint64 - - indent int // for tracing support -} - -type filePositions struct { - file *token.File - needed []uint64 // unordered list of needed file offsets -} - -func (p *iexporter) trace(format string, args ...interface{}) { - if !trace { - // Call sites should also be guarded, but having this check here allows - // easily enabling/disabling debug trace statements. - return - } - fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) -} - -// objectpathEncoder returns the lazily allocated objectpath.Encoder to use -// when encoding objects in other packages during shallow export. -// -// Using a shared Encoder amortizes some of cost of objectpath search. -func (p *iexporter) objectpathEncoder() *objectpath.Encoder { - if p.objEncoder == nil { - p.objEncoder = new(objectpath.Encoder) - } - return p.objEncoder -} - -// stringOff returns the offset of s within the string section. -// If not already present, it's added to the end. -func (p *iexporter) stringOff(s string) uint64 { - off, ok := p.stringIndex[s] - if !ok { - off = uint64(p.strings.Len()) - p.stringIndex[s] = off - - p.strings.uint64(uint64(len(s))) - p.strings.WriteString(s) - } - return off -} - -// fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it. -func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) { - index, ok := p.fileInfo[file] - if !ok { - index = uint64(len(p.fileInfo)) - p.fileInfos = append(p.fileInfos, &filePositions{file: file}) - if p.fileInfo == nil { - p.fileInfo = make(map[*token.File]uint64) - } - p.fileInfo[file] = index - } - // Record each needed offset. - info := p.fileInfos[index] - offset := uint64(file.Offset(pos)) - info.needed = append(info.needed, offset) - - return index, offset -} - -// pushDecl adds n to the declaration work queue, if not already present. -func (p *iexporter) pushDecl(obj types.Object) { - // Package unsafe is known to the compiler and predeclared. - // Caller should not ask us to do export it. - if obj.Pkg() == types.Unsafe { - panic("cannot export package unsafe") - } - - // Shallow export data: don't index decls from other packages. - if p.shallow && obj.Pkg() != p.localpkg { - return - } - - if _, ok := p.declIndex[obj]; ok { - return - } - - p.declIndex[obj] = ^uint64(0) // mark obj present in work queue - p.declTodo.pushTail(obj) -} - -// exportWriter handles writing out individual data section chunks. -type exportWriter struct { - p *iexporter - - data intWriter - prevFile string - prevLine int64 - prevColumn int64 -} - -func (w *exportWriter) exportPath(pkg *types.Package) string { - if pkg == w.p.localpkg { - return "" - } - return pkg.Path() -} - -func (p *iexporter) doDecl(obj types.Object) { - if trace { - p.trace("exporting decl %v (%T)", obj, obj) - p.indent++ - defer func() { - p.indent-- - p.trace("=> %s", obj) - }() - } - w := p.newWriter() - - switch obj := obj.(type) { - case *types.Var: - w.tag('V') - w.pos(obj.Pos()) - w.typ(obj.Type(), obj.Pkg()) - - case *types.Func: - sig, _ := obj.Type().(*types.Signature) - if sig.Recv() != nil { - // We shouldn't see methods in the package scope, - // but the type checker may repair "func () F() {}" - // to "func (Invalid) F()" and then treat it like "func F()", - // so allow that. See golang/go#57729. - if sig.Recv().Type() != types.Typ[types.Invalid] { - panic(internalErrorf("unexpected method: %v", sig)) - } - } - - // Function. - if sig.TypeParams().Len() == 0 { - w.tag('F') - } else { - w.tag('G') - } - w.pos(obj.Pos()) - // The tparam list of the function type is the declaration of the type - // params. So, write out the type params right now. Then those type params - // will be referenced via their type offset (via typOff) in all other - // places in the signature and function where they are used. - // - // While importing the type parameters, tparamList computes and records - // their export name, so that it can be later used when writing the index. - if tparams := sig.TypeParams(); tparams.Len() > 0 { - w.tparamList(obj.Name(), tparams, obj.Pkg()) - } - w.signature(sig) - - case *types.Const: - w.tag('C') - w.pos(obj.Pos()) - w.value(obj.Type(), obj.Val()) - - case *types.TypeName: - t := obj.Type() - - if tparam, ok := t.(*types.TypeParam); ok { - w.tag('P') - w.pos(obj.Pos()) - constraint := tparam.Constraint() - if p.version >= iexportVersionGo1_18 { - implicit := false - if iface, _ := constraint.(*types.Interface); iface != nil { - implicit = iface.IsImplicit() - } - w.bool(implicit) - } - w.typ(constraint, obj.Pkg()) - break - } - - if obj.IsAlias() { - w.tag('A') - w.pos(obj.Pos()) - w.typ(t, obj.Pkg()) - break - } - - // Defined type. - named, ok := t.(*types.Named) - if !ok { - panic(internalErrorf("%s is not a defined type", t)) - } - - if named.TypeParams().Len() == 0 { - w.tag('T') - } else { - w.tag('U') - } - w.pos(obj.Pos()) - - if named.TypeParams().Len() > 0 { - // While importing the type parameters, tparamList computes and records - // their export name, so that it can be later used when writing the index. - w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg()) - } - - underlying := obj.Type().Underlying() - w.typ(underlying, obj.Pkg()) - - if types.IsInterface(t) { - break - } - - n := named.NumMethods() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - m := named.Method(i) - w.pos(m.Pos()) - w.string(m.Name()) - sig, _ := m.Type().(*types.Signature) - - // Receiver type parameters are type arguments of the receiver type, so - // their name must be qualified before exporting recv. - if rparams := sig.RecvTypeParams(); rparams.Len() > 0 { - prefix := obj.Name() + "." + m.Name() - for i := 0; i < rparams.Len(); i++ { - rparam := rparams.At(i) - name := tparamExportName(prefix, rparam) - w.p.tparamNames[rparam.Obj()] = name - } - } - w.param(sig.Recv()) - w.signature(sig) - } - - default: - panic(internalErrorf("unexpected object: %v", obj)) - } - - p.declIndex[obj] = w.flush() -} - -func (w *exportWriter) tag(tag byte) { - w.data.WriteByte(tag) -} - -func (w *exportWriter) pos(pos token.Pos) { - if w.p.shallow { - w.posV2(pos) - } else if w.p.version >= iexportVersionPosCol { - w.posV1(pos) - } else { - w.posV0(pos) - } -} - -// posV2 encoding (used only in shallow mode) records positions as -// (file, offset), where file is the index in the token.File table -// (which records the file name and newline offsets) and offset is a -// byte offset. It effectively ignores //line directives. -func (w *exportWriter) posV2(pos token.Pos) { - if pos == token.NoPos { - w.uint64(0) - return - } - file := w.p.fset.File(pos) // fset must be non-nil - index, offset := w.p.fileIndexAndOffset(file, pos) - w.uint64(1 + index) - w.uint64(offset) -} - -func (w *exportWriter) posV1(pos token.Pos) { - if w.p.fset == nil { - w.int64(0) - return - } - - p := w.p.fset.Position(pos) - file := p.Filename - line := int64(p.Line) - column := int64(p.Column) - - deltaColumn := (column - w.prevColumn) << 1 - deltaLine := (line - w.prevLine) << 1 - - if file != w.prevFile { - deltaLine |= 1 - } - if deltaLine != 0 { - deltaColumn |= 1 - } - - w.int64(deltaColumn) - if deltaColumn&1 != 0 { - w.int64(deltaLine) - if deltaLine&1 != 0 { - w.string(file) - } - } - - w.prevFile = file - w.prevLine = line - w.prevColumn = column -} - -func (w *exportWriter) posV0(pos token.Pos) { - if w.p.fset == nil { - w.int64(0) - return - } - - p := w.p.fset.Position(pos) - file := p.Filename - line := int64(p.Line) - - // When file is the same as the last position (common case), - // we can save a few bytes by delta encoding just the line - // number. - // - // Note: Because data objects may be read out of order (or not - // at all), we can only apply delta encoding within a single - // object. This is handled implicitly by tracking prevFile and - // prevLine as fields of exportWriter. - - if file == w.prevFile { - delta := line - w.prevLine - w.int64(delta) - if delta == deltaNewFile { - w.int64(-1) - } - } else { - w.int64(deltaNewFile) - w.int64(line) // line >= 0 - w.string(file) - w.prevFile = file - } - w.prevLine = line -} - -func (w *exportWriter) pkg(pkg *types.Package) { - // Ensure any referenced packages are declared in the main index. - w.p.allPkgs[pkg] = true - - w.string(w.exportPath(pkg)) -} - -func (w *exportWriter) qualifiedType(obj *types.TypeName) { - name := w.p.exportName(obj) - - // Ensure any referenced declarations are written out too. - w.p.pushDecl(obj) - w.string(name) - w.pkg(obj.Pkg()) -} - -// TODO(rfindley): what does 'pkg' even mean here? It would be better to pass -// it in explicitly into signatures and structs that may use it for -// constructing fields. -func (w *exportWriter) typ(t types.Type, pkg *types.Package) { - w.data.uint64(w.p.typOff(t, pkg)) -} - -func (p *iexporter) newWriter() *exportWriter { - return &exportWriter{p: p} -} - -func (w *exportWriter) flush() uint64 { - off := uint64(w.p.data0.Len()) - io.Copy(&w.p.data0, &w.data) - return off -} - -func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 { - off, ok := p.typIndex[t] - if !ok { - w := p.newWriter() - w.doTyp(t, pkg) - off = predeclReserved + w.flush() - p.typIndex[t] = off - } - return off -} - -func (w *exportWriter) startType(k itag) { - w.data.uint64(uint64(k)) -} - -func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { - if trace { - w.p.trace("exporting type %s (%T)", t, t) - w.p.indent++ - defer func() { - w.p.indent-- - w.p.trace("=> %s", t) - }() - } - switch t := t.(type) { - case *types.Named: - if targs := t.TypeArgs(); targs.Len() > 0 { - w.startType(instanceType) - // TODO(rfindley): investigate if this position is correct, and if it - // matters. - w.pos(t.Obj().Pos()) - w.typeList(targs, pkg) - w.typ(t.Origin(), pkg) - return - } - w.startType(definedType) - w.qualifiedType(t.Obj()) - - case *types.TypeParam: - w.startType(typeParamType) - w.qualifiedType(t.Obj()) - - case *types.Pointer: - w.startType(pointerType) - w.typ(t.Elem(), pkg) - - case *types.Slice: - w.startType(sliceType) - w.typ(t.Elem(), pkg) - - case *types.Array: - w.startType(arrayType) - w.uint64(uint64(t.Len())) - w.typ(t.Elem(), pkg) - - case *types.Chan: - w.startType(chanType) - // 1 RecvOnly; 2 SendOnly; 3 SendRecv - var dir uint64 - switch t.Dir() { - case types.RecvOnly: - dir = 1 - case types.SendOnly: - dir = 2 - case types.SendRecv: - dir = 3 - } - w.uint64(dir) - w.typ(t.Elem(), pkg) - - case *types.Map: - w.startType(mapType) - w.typ(t.Key(), pkg) - w.typ(t.Elem(), pkg) - - case *types.Signature: - w.startType(signatureType) - w.pkg(pkg) - w.signature(t) - - case *types.Struct: - w.startType(structType) - n := t.NumFields() - // Even for struct{} we must emit some qualifying package, because that's - // what the compiler does, and thus that's what the importer expects. - fieldPkg := pkg - if n > 0 { - fieldPkg = t.Field(0).Pkg() - } - if fieldPkg == nil { - // TODO(rfindley): improve this very hacky logic. - // - // The importer expects a package to be set for all struct types, even - // those with no fields. A better encoding might be to set NumFields - // before pkg. setPkg panics with a nil package, which may be possible - // to reach with invalid packages (and perhaps valid packages, too?), so - // (arbitrarily) set the localpkg if available. - // - // Alternatively, we may be able to simply guarantee that pkg != nil, by - // reconsidering the encoding of constant values. - if w.p.shallow { - fieldPkg = w.p.localpkg - } else { - panic(internalErrorf("no package to set for empty struct")) - } - } - w.pkg(fieldPkg) - w.uint64(uint64(n)) - - for i := 0; i < n; i++ { - f := t.Field(i) - if w.p.shallow { - w.objectPath(f) - } - w.pos(f.Pos()) - w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg - w.typ(f.Type(), fieldPkg) - w.bool(f.Anonymous()) - w.string(t.Tag(i)) // note (or tag) - } - - case *types.Interface: - w.startType(interfaceType) - w.pkg(pkg) - - n := t.NumEmbeddeds() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - ft := t.EmbeddedType(i) - tPkg := pkg - if named, _ := ft.(*types.Named); named != nil { - w.pos(named.Obj().Pos()) - } else { - w.pos(token.NoPos) - } - w.typ(ft, tPkg) - } - - // See comment for struct fields. In shallow mode we change the encoding - // for interface methods that are promoted from other packages. - - n = t.NumExplicitMethods() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - m := t.ExplicitMethod(i) - if w.p.shallow { - w.objectPath(m) - } - w.pos(m.Pos()) - w.string(m.Name()) - sig, _ := m.Type().(*types.Signature) - w.signature(sig) - } - - case *types.Union: - w.startType(unionType) - nt := t.Len() - w.uint64(uint64(nt)) - for i := 0; i < nt; i++ { - term := t.Term(i) - w.bool(term.Tilde()) - w.typ(term.Type(), pkg) - } - - default: - panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t))) - } -} - -// objectPath writes the package and objectPath to use to look up obj in a -// different package, when encoding in "shallow" mode. -// -// When doing a shallow import, the importer creates only the local package, -// and requests package symbols for dependencies from the client. -// However, certain types defined in the local package may hold objects defined -// (perhaps deeply) within another package. -// -// For example, consider the following: -// -// package a -// func F() chan * map[string] struct { X int } -// -// package b -// import "a" -// var B = a.F() -// -// In this example, the type of b.B holds fields defined in package a. -// In order to have the correct canonical objects for the field defined in the -// type of B, they are encoded as objectPaths and later looked up in the -// importer. The same problem applies to interface methods. -func (w *exportWriter) objectPath(obj types.Object) { - if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg { - // obj.Pkg() may be nil for the builtin error.Error. - // In this case, or if obj is declared in the local package, no need to - // encode. - w.string("") - return - } - objectPath, err := w.p.objectpathEncoder().For(obj) - if err != nil { - // Fall back to the empty string, which will cause the importer to create a - // new object, which matches earlier behavior. Creating a new object is - // sufficient for many purposes (such as type checking), but causes certain - // references algorithms to fail (golang/go#60819). However, we didn't - // notice this problem during months of gopls@v0.12.0 testing. - // - // TODO(golang/go#61674): this workaround is insufficient, as in the case - // where the field forwarded from an instantiated type that may not appear - // in the export data of the original package: - // - // // package a - // type A[P any] struct{ F P } - // - // // package b - // type B a.A[int] - // - // We need to update references algorithms not to depend on this - // de-duplication, at which point we may want to simply remove the - // workaround here. - w.string("") - return - } - w.string(string(objectPath)) - w.pkg(obj.Pkg()) -} - -func (w *exportWriter) signature(sig *types.Signature) { - w.paramList(sig.Params()) - w.paramList(sig.Results()) - if sig.Params().Len() > 0 { - w.bool(sig.Variadic()) - } -} - -func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) { - w.uint64(uint64(ts.Len())) - for i := 0; i < ts.Len(); i++ { - w.typ(ts.At(i), pkg) - } -} - -func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) { - ll := uint64(list.Len()) - w.uint64(ll) - for i := 0; i < list.Len(); i++ { - tparam := list.At(i) - // Set the type parameter exportName before exporting its type. - exportName := tparamExportName(prefix, tparam) - w.p.tparamNames[tparam.Obj()] = exportName - w.typ(list.At(i), pkg) - } -} - -const blankMarker = "$" - -// tparamExportName returns the 'exported' name of a type parameter, which -// differs from its actual object name: it is prefixed with a qualifier, and -// blank type parameter names are disambiguated by their index in the type -// parameter list. -func tparamExportName(prefix string, tparam *types.TypeParam) string { - assert(prefix != "") - name := tparam.Obj().Name() - if name == "_" { - name = blankMarker + strconv.Itoa(tparam.Index()) - } - return prefix + "." + name -} - -// tparamName returns the real name of a type parameter, after stripping its -// qualifying prefix and reverting blank-name encoding. See tparamExportName -// for details. -func tparamName(exportName string) string { - // Remove the "path" from the type param name that makes it unique. - ix := strings.LastIndex(exportName, ".") - if ix < 0 { - errorf("malformed type parameter export name %s: missing prefix", exportName) - } - name := exportName[ix+1:] - if strings.HasPrefix(name, blankMarker) { - return "_" - } - return name -} - -func (w *exportWriter) paramList(tup *types.Tuple) { - n := tup.Len() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - w.param(tup.At(i)) - } -} - -func (w *exportWriter) param(obj types.Object) { - w.pos(obj.Pos()) - w.localIdent(obj) - w.typ(obj.Type(), obj.Pkg()) -} - -func (w *exportWriter) value(typ types.Type, v constant.Value) { - w.typ(typ, nil) - if w.p.version >= iexportVersionGo1_18 { - w.int64(int64(v.Kind())) - } - - if v.Kind() == constant.Unknown { - // golang/go#60605: treat unknown constant values as if they have invalid type - // - // This loses some fidelity over the package type-checked from source, but that - // is acceptable. - // - // TODO(rfindley): we should switch on the recorded constant kind rather - // than the constant type - return - } - - switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { - case types.IsBoolean: - w.bool(constant.BoolVal(v)) - case types.IsInteger: - var i big.Int - if i64, exact := constant.Int64Val(v); exact { - i.SetInt64(i64) - } else if ui64, exact := constant.Uint64Val(v); exact { - i.SetUint64(ui64) - } else { - i.SetString(v.ExactString(), 10) - } - w.mpint(&i, typ) - case types.IsFloat: - f := constantToFloat(v) - w.mpfloat(f, typ) - case types.IsComplex: - w.mpfloat(constantToFloat(constant.Real(v)), typ) - w.mpfloat(constantToFloat(constant.Imag(v)), typ) - case types.IsString: - w.string(constant.StringVal(v)) - default: - if b.Kind() == types.Invalid { - // package contains type errors - break - } - panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying())) - } -} - -// constantToFloat converts a constant.Value with kind constant.Float to a -// big.Float. -func constantToFloat(x constant.Value) *big.Float { - x = constant.ToFloat(x) - // Use the same floating-point precision (512) as cmd/compile - // (see Mpprec in cmd/compile/internal/gc/mpfloat.go). - const mpprec = 512 - var f big.Float - f.SetPrec(mpprec) - if v, exact := constant.Float64Val(x); exact { - // float64 - f.SetFloat64(v) - } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { - // TODO(gri): add big.Rat accessor to constant.Value. - n := valueToRat(num) - d := valueToRat(denom) - f.SetRat(n.Quo(n, d)) - } else { - // Value too large to represent as a fraction => inaccessible. - // TODO(gri): add big.Float accessor to constant.Value. - _, ok := f.SetString(x.ExactString()) - assert(ok) - } - return &f -} - -func valueToRat(x constant.Value) *big.Rat { - // Convert little-endian to big-endian. - // I can't believe this is necessary. - bytes := constant.Bytes(x) - for i := 0; i < len(bytes)/2; i++ { - bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i] - } - return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes)) -} - -// mpint exports a multi-precision integer. -// -// For unsigned types, small values are written out as a single -// byte. Larger values are written out as a length-prefixed big-endian -// byte string, where the length prefix is encoded as its complement. -// For example, bytes 0, 1, and 2 directly represent the integer -// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-, -// 2-, and 3-byte big-endian string follow. -// -// Encoding for signed types use the same general approach as for -// unsigned types, except small values use zig-zag encoding and the -// bottom bit of length prefix byte for large values is reserved as a -// sign bit. -// -// The exact boundary between small and large encodings varies -// according to the maximum number of bytes needed to encode a value -// of type typ. As a special case, 8-bit types are always encoded as a -// single byte. -// -// TODO(mdempsky): Is this level of complexity really worthwhile? -func (w *exportWriter) mpint(x *big.Int, typ types.Type) { - basic, ok := typ.Underlying().(*types.Basic) - if !ok { - panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying())) - } - - signed, maxBytes := intSize(basic) - - negative := x.Sign() < 0 - if !signed && negative { - panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x)) - } - - b := x.Bytes() - if len(b) > 0 && b[0] == 0 { - panic(internalErrorf("leading zeros")) - } - if uint(len(b)) > maxBytes { - panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)) - } - - maxSmall := 256 - maxBytes - if signed { - maxSmall = 256 - 2*maxBytes - } - if maxBytes == 1 { - maxSmall = 256 - } - - // Check if x can use small value encoding. - if len(b) <= 1 { - var ux uint - if len(b) == 1 { - ux = uint(b[0]) - } - if signed { - ux <<= 1 - if negative { - ux-- - } - } - if ux < maxSmall { - w.data.WriteByte(byte(ux)) - return - } - } - - n := 256 - uint(len(b)) - if signed { - n = 256 - 2*uint(len(b)) - if negative { - n |= 1 - } - } - if n < maxSmall || n >= 256 { - panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)) - } - - w.data.WriteByte(byte(n)) - w.data.Write(b) -} - -// mpfloat exports a multi-precision floating point number. -// -// The number's value is decomposed into mantissa × 2**exponent, where -// mantissa is an integer. The value is written out as mantissa (as a -// multi-precision integer) and then the exponent, except exponent is -// omitted if mantissa is zero. -func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) { - if f.IsInf() { - panic("infinite constant") - } - - // Break into f = mant × 2**exp, with 0.5 <= mant < 1. - var mant big.Float - exp := int64(f.MantExp(&mant)) - - // Scale so that mant is an integer. - prec := mant.MinPrec() - mant.SetMantExp(&mant, int(prec)) - exp -= int64(prec) - - manti, acc := mant.Int(nil) - if acc != big.Exact { - panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc)) - } - w.mpint(manti, typ) - if manti.Sign() != 0 { - w.int64(exp) - } -} - -func (w *exportWriter) bool(b bool) bool { - var x uint64 - if b { - x = 1 - } - w.uint64(x) - return b -} - -func (w *exportWriter) int64(x int64) { w.data.int64(x) } -func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) } -func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) } - -func (w *exportWriter) localIdent(obj types.Object) { - // Anonymous parameters. - if obj == nil { - w.string("") - return - } - - name := obj.Name() - if name == "_" { - w.string("_") - return - } - - w.string(name) -} - -type intWriter struct { - bytes.Buffer -} - -func (w *intWriter) int64(x int64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutVarint(buf[:], x) - w.Write(buf[:n]) -} - -func (w *intWriter) uint64(x uint64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutUvarint(buf[:], x) - w.Write(buf[:n]) -} - -func assert(cond bool) { - if !cond { - panic("internal error: assertion failed") - } -} - -// The below is copied from go/src/cmd/compile/internal/gc/syntax.go. - -// objQueue is a FIFO queue of types.Object. The zero value of objQueue is -// a ready-to-use empty queue. -type objQueue struct { - ring []types.Object - head, tail int -} - -// empty returns true if q contains no Nodes. -func (q *objQueue) empty() bool { - return q.head == q.tail -} - -// pushTail appends n to the tail of the queue. -func (q *objQueue) pushTail(obj types.Object) { - if len(q.ring) == 0 { - q.ring = make([]types.Object, 16) - } else if q.head+len(q.ring) == q.tail { - // Grow the ring. - nring := make([]types.Object, len(q.ring)*2) - // Copy the old elements. - part := q.ring[q.head%len(q.ring):] - if q.tail-q.head <= len(part) { - part = part[:q.tail-q.head] - copy(nring, part) - } else { - pos := copy(nring, part) - copy(nring[pos:], q.ring[:q.tail%len(q.ring)]) - } - q.ring, q.head, q.tail = nring, 0, q.tail-q.head - } - - q.ring[q.tail%len(q.ring)] = obj - q.tail++ -} - -// popHead pops a node from the head of the queue. It panics if q is empty. -func (q *objQueue) popHead() types.Object { - if q.empty() { - panic("dequeue empty") - } - obj := q.ring[q.head%len(q.ring)] - q.head++ - return obj -} - -// internalError represents an error generated inside this package. -type internalError string - -func (e internalError) Error() string { return "gcimporter: " + string(e) } - -// TODO(adonovan): make this call panic, so that it's symmetric with errorf. -// Otherwise it's easy to forget to do anything with the error. -// -// TODO(adonovan): also, consider switching the names "errorf" and -// "internalErrorf" as the former is used for bugs, whose cause is -// internal inconsistency, whereas the latter is used for ordinary -// situations like bad input, whose cause is external. -func internalErrorf(format string, args ...interface{}) error { - return internalError(fmt.Sprintf(format, args...)) -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go deleted file mode 100644 index 9bde15e3..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go +++ /dev/null @@ -1,1082 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Indexed package import. -// See cmd/compile/internal/gc/iexport.go for the export data format. - -// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go. - -package gcimporter - -import ( - "bytes" - "encoding/binary" - "fmt" - "go/constant" - "go/token" - "go/types" - "io" - "math/big" - "sort" - "strings" - - "golang.org/x/tools/go/types/objectpath" -) - -type intReader struct { - *bytes.Reader - path string -} - -func (r *intReader) int64() int64 { - i, err := binary.ReadVarint(r.Reader) - if err != nil { - errorf("import %q: read varint error: %v", r.path, err) - } - return i -} - -func (r *intReader) uint64() uint64 { - i, err := binary.ReadUvarint(r.Reader) - if err != nil { - errorf("import %q: read varint error: %v", r.path, err) - } - return i -} - -// Keep this in sync with constants in iexport.go. -const ( - iexportVersionGo1_11 = 0 - iexportVersionPosCol = 1 - iexportVersionGo1_18 = 2 - iexportVersionGenerics = 2 - - iexportVersionCurrent = 2 -) - -type ident struct { - pkg *types.Package - name string -} - -const predeclReserved = 32 - -type itag uint64 - -const ( - // Types - definedType itag = iota - pointerType - sliceType - arrayType - chanType - mapType - signatureType - structType - interfaceType - typeParamType - instanceType - unionType -) - -// IImportData imports a package from the serialized package data -// and returns 0 and a reference to the package. -// If the export data version is not recognized or the format is otherwise -// compromised, an error is returned. -func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) { - pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, false, path, false, nil) - if err != nil { - return 0, nil, err - } - return 0, pkgs[0], nil -} - -// IImportBundle imports a set of packages from the serialized package bundle. -func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) { - return iimportCommon(fset, GetPackagesFromMap(imports), data, true, "", false, nil) -} - -// A GetPackagesFunc function obtains the non-nil symbols for a set of -// packages, creating and recursively importing them as needed. An -// implementation should store each package symbol is in the Pkg -// field of the items array. -// -// Any error causes importing to fail. This can be used to quickly read -// the import manifest of an export data file without fully decoding it. -type GetPackagesFunc = func(items []GetPackagesItem) error - -// A GetPackagesItem is a request from the importer for the package -// symbol of the specified name and path. -type GetPackagesItem struct { - Name, Path string - Pkg *types.Package // to be filled in by GetPackagesFunc call - - // private importer state - pathOffset uint64 - nameIndex map[string]uint64 -} - -// GetPackagesFromMap returns a GetPackagesFunc that retrieves -// packages from the given map of package path to package. -// -// The returned function may mutate m: each requested package that is not -// found is created with types.NewPackage and inserted into m. -func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc { - return func(items []GetPackagesItem) error { - for i, item := range items { - pkg, ok := m[item.Path] - if !ok { - pkg = types.NewPackage(item.Path, item.Name) - m[item.Path] = pkg - } - items[i].Pkg = pkg - } - return nil - } -} - -func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, bundle bool, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) { - const currentVersion = iexportVersionCurrent - version := int64(-1) - if !debug { - defer func() { - if e := recover(); e != nil { - if bundle { - err = fmt.Errorf("%v", e) - } else if version > currentVersion { - err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) - } else { - err = fmt.Errorf("internal error while importing %q (%v); please report an issue", path, e) - } - } - }() - } - - r := &intReader{bytes.NewReader(data), path} - - if bundle { - if v := r.uint64(); v != bundleVersion { - errorf("unknown bundle format version %d", v) - } - } - - version = int64(r.uint64()) - switch version { - case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: - default: - if version > iexportVersionGo1_18 { - errorf("unstable iexport format version %d, just rebuild compiler and std library", version) - } else { - errorf("unknown iexport format version %d", version) - } - } - - sLen := int64(r.uint64()) - var fLen int64 - var fileOffset []uint64 - if shallow { - // Shallow mode uses a different position encoding. - fLen = int64(r.uint64()) - fileOffset = make([]uint64, r.uint64()) - for i := range fileOffset { - fileOffset[i] = r.uint64() - } - } - dLen := int64(r.uint64()) - - whence, _ := r.Seek(0, io.SeekCurrent) - stringData := data[whence : whence+sLen] - fileData := data[whence+sLen : whence+sLen+fLen] - declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen] - r.Seek(sLen+fLen+dLen, io.SeekCurrent) - - p := iimporter{ - version: int(version), - ipath: path, - shallow: shallow, - reportf: reportf, - - stringData: stringData, - stringCache: make(map[uint64]string), - fileOffset: fileOffset, - fileData: fileData, - fileCache: make([]*token.File, len(fileOffset)), - pkgCache: make(map[uint64]*types.Package), - - declData: declData, - pkgIndex: make(map[*types.Package]map[string]uint64), - typCache: make(map[uint64]types.Type), - // Separate map for typeparams, keyed by their package and unique - // name. - tparamIndex: make(map[ident]types.Type), - - fake: fakeFileSet{ - fset: fset, - files: make(map[string]*fileInfo), - }, - } - defer p.fake.setLines() // set lines for files in fset - - for i, pt := range predeclared() { - p.typCache[uint64(i)] = pt - } - - // Gather the relevant packages from the manifest. - items := make([]GetPackagesItem, r.uint64()) - for i := range items { - pkgPathOff := r.uint64() - pkgPath := p.stringAt(pkgPathOff) - pkgName := p.stringAt(r.uint64()) - _ = r.uint64() // package height; unused by go/types - - if pkgPath == "" { - pkgPath = path - } - items[i].Name = pkgName - items[i].Path = pkgPath - items[i].pathOffset = pkgPathOff - - // Read index for package. - nameIndex := make(map[string]uint64) - nSyms := r.uint64() - // In shallow mode, only the current package (i=0) has an index. - assert(!(shallow && i > 0 && nSyms != 0)) - for ; nSyms > 0; nSyms-- { - name := p.stringAt(r.uint64()) - nameIndex[name] = r.uint64() - } - - items[i].nameIndex = nameIndex - } - - // Request packages all at once from the client, - // enabling a parallel implementation. - if err := getPackages(items); err != nil { - return nil, err // don't wrap this error - } - - // Check the results and complete the index. - pkgList := make([]*types.Package, len(items)) - for i, item := range items { - pkg := item.Pkg - if pkg == nil { - errorf("internal error: getPackages returned nil package for %q", item.Path) - } else if pkg.Path() != item.Path { - errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path) - } else if pkg.Name() != item.Name { - errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name) - } - p.pkgCache[item.pathOffset] = pkg - p.pkgIndex[pkg] = item.nameIndex - pkgList[i] = pkg - } - - if bundle { - pkgs = make([]*types.Package, r.uint64()) - for i := range pkgs { - pkg := p.pkgAt(r.uint64()) - imps := make([]*types.Package, r.uint64()) - for j := range imps { - imps[j] = p.pkgAt(r.uint64()) - } - pkg.SetImports(imps) - pkgs[i] = pkg - } - } else { - if len(pkgList) == 0 { - errorf("no packages found for %s", path) - panic("unreachable") - } - pkgs = pkgList[:1] - - // record all referenced packages as imports - list := append(([]*types.Package)(nil), pkgList[1:]...) - sort.Sort(byPath(list)) - pkgs[0].SetImports(list) - } - - for _, pkg := range pkgs { - if pkg.Complete() { - continue - } - - names := make([]string, 0, len(p.pkgIndex[pkg])) - for name := range p.pkgIndex[pkg] { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { - p.doDecl(pkg, name) - } - - // package was imported completely and without errors - pkg.MarkComplete() - } - - // SetConstraint can't be called if the constraint type is not yet complete. - // When type params are created in the 'P' case of (*importReader).obj(), - // the associated constraint type may not be complete due to recursion. - // Therefore, we defer calling SetConstraint there, and call it here instead - // after all types are complete. - for _, d := range p.later { - d.t.SetConstraint(d.constraint) - } - - for _, typ := range p.interfaceList { - typ.Complete() - } - - // Workaround for golang/go#61561. See the doc for instanceList for details. - for _, typ := range p.instanceList { - if iface, _ := typ.Underlying().(*types.Interface); iface != nil { - iface.Complete() - } - } - - return pkgs, nil -} - -type setConstraintArgs struct { - t *types.TypeParam - constraint types.Type -} - -type iimporter struct { - version int - ipath string - - shallow bool - reportf ReportFunc // if non-nil, used to report bugs - - stringData []byte - stringCache map[uint64]string - fileOffset []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i - fileData []byte - fileCache []*token.File // memoized decoding of file encoded as i - pkgCache map[uint64]*types.Package - - declData []byte - pkgIndex map[*types.Package]map[string]uint64 - typCache map[uint64]types.Type - tparamIndex map[ident]types.Type - - fake fakeFileSet - interfaceList []*types.Interface - - // Workaround for the go/types bug golang/go#61561: instances produced during - // instantiation may contain incomplete interfaces. Here we only complete the - // underlying type of the instance, which is the most common case but doesn't - // handle parameterized interface literals defined deeper in the type. - instanceList []types.Type // instances for later completion (see golang/go#61561) - - // Arguments for calls to SetConstraint that are deferred due to recursive types - later []setConstraintArgs - - indent int // for tracing support -} - -func (p *iimporter) trace(format string, args ...interface{}) { - if !trace { - // Call sites should also be guarded, but having this check here allows - // easily enabling/disabling debug trace statements. - return - } - fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) -} - -func (p *iimporter) doDecl(pkg *types.Package, name string) { - if debug { - p.trace("import decl %s", name) - p.indent++ - defer func() { - p.indent-- - p.trace("=> %s", name) - }() - } - // See if we've already imported this declaration. - if obj := pkg.Scope().Lookup(name); obj != nil { - return - } - - off, ok := p.pkgIndex[pkg][name] - if !ok { - // In deep mode, the index should be complete. In shallow - // mode, we should have already recursively loaded necessary - // dependencies so the above Lookup succeeds. - errorf("%v.%v not in index", pkg, name) - } - - r := &importReader{p: p, currPkg: pkg} - r.declReader.Reset(p.declData[off:]) - - r.obj(name) -} - -func (p *iimporter) stringAt(off uint64) string { - if s, ok := p.stringCache[off]; ok { - return s - } - - slen, n := binary.Uvarint(p.stringData[off:]) - if n <= 0 { - errorf("varint failed") - } - spos := off + uint64(n) - s := string(p.stringData[spos : spos+slen]) - p.stringCache[off] = s - return s -} - -func (p *iimporter) fileAt(index uint64) *token.File { - file := p.fileCache[index] - if file == nil { - off := p.fileOffset[index] - file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath}) - p.fileCache[index] = file - } - return file -} - -func (p *iimporter) decodeFile(rd intReader) *token.File { - filename := p.stringAt(rd.uint64()) - size := int(rd.uint64()) - file := p.fake.fset.AddFile(filename, -1, size) - - // SetLines requires a nondecreasing sequence. - // Because it is common for clients to derive the interval - // [start, start+len(name)] from a start position, and we - // want to ensure that the end offset is on the same line, - // we fill in the gaps of the sparse encoding with values - // that strictly increase by the largest possible amount. - // This allows us to avoid having to record the actual end - // offset of each needed line. - - lines := make([]int, int(rd.uint64())) - var index, offset int - for i, n := 0, int(rd.uint64()); i < n; i++ { - index += int(rd.uint64()) - offset += int(rd.uint64()) - lines[index] = offset - - // Ensure monotonicity between points. - for j := index - 1; j > 0 && lines[j] == 0; j-- { - lines[j] = lines[j+1] - 1 - } - } - - // Ensure monotonicity after last point. - for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- { - size-- - lines[j] = size - } - - if !file.SetLines(lines) { - errorf("SetLines failed: %d", lines) // can't happen - } - return file -} - -func (p *iimporter) pkgAt(off uint64) *types.Package { - if pkg, ok := p.pkgCache[off]; ok { - return pkg - } - path := p.stringAt(off) - errorf("missing package %q in %q", path, p.ipath) - return nil -} - -func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { - if t, ok := p.typCache[off]; ok && canReuse(base, t) { - return t - } - - if off < predeclReserved { - errorf("predeclared type missing from cache: %v", off) - } - - r := &importReader{p: p} - r.declReader.Reset(p.declData[off-predeclReserved:]) - t := r.doType(base) - - if canReuse(base, t) { - p.typCache[off] = t - } - return t -} - -// canReuse reports whether the type rhs on the RHS of the declaration for def -// may be re-used. -// -// Specifically, if def is non-nil and rhs is an interface type with methods, it -// may not be re-used because we have a convention of setting the receiver type -// for interface methods to def. -func canReuse(def *types.Named, rhs types.Type) bool { - if def == nil { - return true - } - iface, _ := rhs.(*types.Interface) - if iface == nil { - return true - } - // Don't use iface.Empty() here as iface may not be complete. - return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 -} - -type importReader struct { - p *iimporter - declReader bytes.Reader - currPkg *types.Package - prevFile string - prevLine int64 - prevColumn int64 -} - -func (r *importReader) obj(name string) { - tag := r.byte() - pos := r.pos() - - switch tag { - case 'A': - typ := r.typ() - - r.declare(types.NewTypeName(pos, r.currPkg, name, typ)) - - case 'C': - typ, val := r.value() - - r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) - - case 'F', 'G': - var tparams []*types.TypeParam - if tag == 'G' { - tparams = r.tparamList() - } - sig := r.signature(nil, nil, tparams) - r.declare(types.NewFunc(pos, r.currPkg, name, sig)) - - case 'T', 'U': - // Types can be recursive. We need to setup a stub - // declaration before recursing. - obj := types.NewTypeName(pos, r.currPkg, name, nil) - named := types.NewNamed(obj, nil, nil) - // Declare obj before calling r.tparamList, so the new type name is recognized - // if used in the constraint of one of its own typeparams (see #48280). - r.declare(obj) - if tag == 'U' { - tparams := r.tparamList() - named.SetTypeParams(tparams) - } - - underlying := r.p.typAt(r.uint64(), named).Underlying() - named.SetUnderlying(underlying) - - if !isInterface(underlying) { - for n := r.uint64(); n > 0; n-- { - mpos := r.pos() - mname := r.ident() - recv := r.param() - - // If the receiver has any targs, set those as the - // rparams of the method (since those are the - // typeparams being used in the method sig/body). - base := baseType(recv.Type()) - assert(base != nil) - targs := base.TypeArgs() - var rparams []*types.TypeParam - if targs.Len() > 0 { - rparams = make([]*types.TypeParam, targs.Len()) - for i := range rparams { - rparams[i] = targs.At(i).(*types.TypeParam) - } - } - msig := r.signature(recv, rparams, nil) - - named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) - } - } - - case 'P': - // We need to "declare" a typeparam in order to have a name that - // can be referenced recursively (if needed) in the type param's - // bound. - if r.p.version < iexportVersionGenerics { - errorf("unexpected type param type") - } - name0 := tparamName(name) - tn := types.NewTypeName(pos, r.currPkg, name0, nil) - t := types.NewTypeParam(tn, nil) - - // To handle recursive references to the typeparam within its - // bound, save the partial type in tparamIndex before reading the bounds. - id := ident{r.currPkg, name} - r.p.tparamIndex[id] = t - var implicit bool - if r.p.version >= iexportVersionGo1_18 { - implicit = r.bool() - } - constraint := r.typ() - if implicit { - iface, _ := constraint.(*types.Interface) - if iface == nil { - errorf("non-interface constraint marked implicit") - } - iface.MarkImplicit() - } - // The constraint type may not be complete, if we - // are in the middle of a type recursion involving type - // constraints. So, we defer SetConstraint until we have - // completely set up all types in ImportData. - r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) - - case 'V': - typ := r.typ() - - r.declare(types.NewVar(pos, r.currPkg, name, typ)) - - default: - errorf("unexpected tag: %v", tag) - } -} - -func (r *importReader) declare(obj types.Object) { - obj.Pkg().Scope().Insert(obj) -} - -func (r *importReader) value() (typ types.Type, val constant.Value) { - typ = r.typ() - if r.p.version >= iexportVersionGo1_18 { - // TODO: add support for using the kind. - _ = constant.Kind(r.int64()) - } - - switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { - case types.IsBoolean: - val = constant.MakeBool(r.bool()) - - case types.IsString: - val = constant.MakeString(r.string()) - - case types.IsInteger: - var x big.Int - r.mpint(&x, b) - val = constant.Make(&x) - - case types.IsFloat: - val = r.mpfloat(b) - - case types.IsComplex: - re := r.mpfloat(b) - im := r.mpfloat(b) - val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) - - default: - if b.Kind() == types.Invalid { - val = constant.MakeUnknown() - return - } - errorf("unexpected type %v", typ) // panics - panic("unreachable") - } - - return -} - -func intSize(b *types.Basic) (signed bool, maxBytes uint) { - if (b.Info() & types.IsUntyped) != 0 { - return true, 64 - } - - switch b.Kind() { - case types.Float32, types.Complex64: - return true, 3 - case types.Float64, types.Complex128: - return true, 7 - } - - signed = (b.Info() & types.IsUnsigned) == 0 - switch b.Kind() { - case types.Int8, types.Uint8: - maxBytes = 1 - case types.Int16, types.Uint16: - maxBytes = 2 - case types.Int32, types.Uint32: - maxBytes = 4 - default: - maxBytes = 8 - } - - return -} - -func (r *importReader) mpint(x *big.Int, typ *types.Basic) { - signed, maxBytes := intSize(typ) - - maxSmall := 256 - maxBytes - if signed { - maxSmall = 256 - 2*maxBytes - } - if maxBytes == 1 { - maxSmall = 256 - } - - n, _ := r.declReader.ReadByte() - if uint(n) < maxSmall { - v := int64(n) - if signed { - v >>= 1 - if n&1 != 0 { - v = ^v - } - } - x.SetInt64(v) - return - } - - v := -n - if signed { - v = -(n &^ 1) >> 1 - } - if v < 1 || uint(v) > maxBytes { - errorf("weird decoding: %v, %v => %v", n, signed, v) - } - b := make([]byte, v) - io.ReadFull(&r.declReader, b) - x.SetBytes(b) - if signed && n&1 != 0 { - x.Neg(x) - } -} - -func (r *importReader) mpfloat(typ *types.Basic) constant.Value { - var mant big.Int - r.mpint(&mant, typ) - var f big.Float - f.SetInt(&mant) - if f.Sign() != 0 { - f.SetMantExp(&f, int(r.int64())) - } - return constant.Make(&f) -} - -func (r *importReader) ident() string { - return r.string() -} - -func (r *importReader) qualifiedIdent() (*types.Package, string) { - name := r.string() - pkg := r.pkg() - return pkg, name -} - -func (r *importReader) pos() token.Pos { - if r.p.shallow { - // precise offsets are encoded only in shallow mode - return r.posv2() - } - if r.p.version >= iexportVersionPosCol { - r.posv1() - } else { - r.posv0() - } - - if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { - return token.NoPos - } - return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) -} - -func (r *importReader) posv0() { - delta := r.int64() - if delta != deltaNewFile { - r.prevLine += delta - } else if l := r.int64(); l == -1 { - r.prevLine += deltaNewFile - } else { - r.prevFile = r.string() - r.prevLine = l - } -} - -func (r *importReader) posv1() { - delta := r.int64() - r.prevColumn += delta >> 1 - if delta&1 != 0 { - delta = r.int64() - r.prevLine += delta >> 1 - if delta&1 != 0 { - r.prevFile = r.string() - } - } -} - -func (r *importReader) posv2() token.Pos { - file := r.uint64() - if file == 0 { - return token.NoPos - } - tf := r.p.fileAt(file - 1) - return tf.Pos(int(r.uint64())) -} - -func (r *importReader) typ() types.Type { - return r.p.typAt(r.uint64(), nil) -} - -func isInterface(t types.Type) bool { - _, ok := t.(*types.Interface) - return ok -} - -func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } -func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } - -func (r *importReader) doType(base *types.Named) (res types.Type) { - k := r.kind() - if debug { - r.p.trace("importing type %d (base: %s)", k, base) - r.p.indent++ - defer func() { - r.p.indent-- - r.p.trace("=> %s", res) - }() - } - switch k { - default: - errorf("unexpected kind tag in %q: %v", r.p.ipath, k) - return nil - - case definedType: - pkg, name := r.qualifiedIdent() - r.p.doDecl(pkg, name) - return pkg.Scope().Lookup(name).(*types.TypeName).Type() - case pointerType: - return types.NewPointer(r.typ()) - case sliceType: - return types.NewSlice(r.typ()) - case arrayType: - n := r.uint64() - return types.NewArray(r.typ(), int64(n)) - case chanType: - dir := chanDir(int(r.uint64())) - return types.NewChan(dir, r.typ()) - case mapType: - return types.NewMap(r.typ(), r.typ()) - case signatureType: - r.currPkg = r.pkg() - return r.signature(nil, nil, nil) - - case structType: - r.currPkg = r.pkg() - - fields := make([]*types.Var, r.uint64()) - tags := make([]string, len(fields)) - for i := range fields { - var field *types.Var - if r.p.shallow { - field, _ = r.objectPathObject().(*types.Var) - } - - fpos := r.pos() - fname := r.ident() - ftyp := r.typ() - emb := r.bool() - tag := r.string() - - // Either this is not a shallow import, the field is local, or the - // encoded objectPath failed to produce an object (a bug). - // - // Even in this last, buggy case, fall back on creating a new field. As - // discussed in iexport.go, this is not correct, but mostly works and is - // preferable to failing (for now at least). - if field == nil { - field = types.NewField(fpos, r.currPkg, fname, ftyp, emb) - } - - fields[i] = field - tags[i] = tag - } - return types.NewStruct(fields, tags) - - case interfaceType: - r.currPkg = r.pkg() - - embeddeds := make([]types.Type, r.uint64()) - for i := range embeddeds { - _ = r.pos() - embeddeds[i] = r.typ() - } - - methods := make([]*types.Func, r.uint64()) - for i := range methods { - var method *types.Func - if r.p.shallow { - method, _ = r.objectPathObject().(*types.Func) - } - - mpos := r.pos() - mname := r.ident() - - // TODO(mdempsky): Matches bimport.go, but I - // don't agree with this. - var recv *types.Var - if base != nil { - recv = types.NewVar(token.NoPos, r.currPkg, "", base) - } - msig := r.signature(recv, nil, nil) - - if method == nil { - method = types.NewFunc(mpos, r.currPkg, mname, msig) - } - methods[i] = method - } - - typ := newInterface(methods, embeddeds) - r.p.interfaceList = append(r.p.interfaceList, typ) - return typ - - case typeParamType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected type param type") - } - pkg, name := r.qualifiedIdent() - id := ident{pkg, name} - if t, ok := r.p.tparamIndex[id]; ok { - // We're already in the process of importing this typeparam. - return t - } - // Otherwise, import the definition of the typeparam now. - r.p.doDecl(pkg, name) - return r.p.tparamIndex[id] - - case instanceType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected instantiation type") - } - // pos does not matter for instances: they are positioned on the original - // type. - _ = r.pos() - len := r.uint64() - targs := make([]types.Type, len) - for i := range targs { - targs[i] = r.typ() - } - baseType := r.typ() - // The imported instantiated type doesn't include any methods, so - // we must always use the methods of the base (orig) type. - // TODO provide a non-nil *Environment - t, _ := types.Instantiate(nil, baseType, targs, false) - - // Workaround for golang/go#61561. See the doc for instanceList for details. - r.p.instanceList = append(r.p.instanceList, t) - return t - - case unionType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected instantiation type") - } - terms := make([]*types.Term, r.uint64()) - for i := range terms { - terms[i] = types.NewTerm(r.bool(), r.typ()) - } - return types.NewUnion(terms) - } -} - -func (r *importReader) kind() itag { - return itag(r.uint64()) -} - -// objectPathObject is the inverse of exportWriter.objectPath. -// -// In shallow mode, certain fields and methods may need to be looked up in an -// imported package. See the doc for exportWriter.objectPath for a full -// explanation. -func (r *importReader) objectPathObject() types.Object { - objPath := objectpath.Path(r.string()) - if objPath == "" { - return nil - } - pkg := r.pkg() - obj, err := objectpath.Object(pkg, objPath) - if err != nil { - if r.p.reportf != nil { - r.p.reportf("failed to find object for objectPath %q: %v", objPath, err) - } - } - return obj -} - -func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature { - params := r.paramList() - results := r.paramList() - variadic := params.Len() > 0 && r.bool() - return types.NewSignatureType(recv, rparams, tparams, params, results, variadic) -} - -func (r *importReader) tparamList() []*types.TypeParam { - n := r.uint64() - if n == 0 { - return nil - } - xs := make([]*types.TypeParam, n) - for i := range xs { - // Note: the standard library importer is tolerant of nil types here, - // though would panic in SetTypeParams. - xs[i] = r.typ().(*types.TypeParam) - } - return xs -} - -func (r *importReader) paramList() *types.Tuple { - xs := make([]*types.Var, r.uint64()) - for i := range xs { - xs[i] = r.param() - } - return types.NewTuple(xs...) -} - -func (r *importReader) param() *types.Var { - pos := r.pos() - name := r.ident() - typ := r.typ() - return types.NewParam(pos, r.currPkg, name, typ) -} - -func (r *importReader) bool() bool { - return r.uint64() != 0 -} - -func (r *importReader) int64() int64 { - n, err := binary.ReadVarint(&r.declReader) - if err != nil { - errorf("readVarint: %v", err) - } - return n -} - -func (r *importReader) uint64() uint64 { - n, err := binary.ReadUvarint(&r.declReader) - if err != nil { - errorf("readUvarint: %v", err) - } - return n -} - -func (r *importReader) byte() byte { - x, err := r.declReader.ReadByte() - if err != nil { - errorf("declReader.ReadByte: %v", err) - } - return x -} - -func baseType(typ types.Type) *types.Named { - // pointer receivers are never types.Named types - if p, _ := typ.(*types.Pointer); p != nil { - typ = p.Elem() - } - // receiver base types are always (possibly generic) types.Named types - n, _ := typ.(*types.Named) - return n -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go b/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go deleted file mode 100644 index 8b163e3d..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.11 -// +build !go1.11 - -package gcimporter - -import "go/types" - -func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { - named := make([]*types.Named, len(embeddeds)) - for i, e := range embeddeds { - var ok bool - named[i], ok = e.(*types.Named) - if !ok { - panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11") - } - } - return types.NewInterface(methods, named) -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go b/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go deleted file mode 100644 index 49984f40..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.11 -// +build go1.11 - -package gcimporter - -import "go/types" - -func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { - return types.NewInterfaceType(methods, embeddeds) -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go b/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go deleted file mode 100644 index d892273e..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.18 -// +build !go1.18 - -package gcimporter - -import "go/types" - -const iexportVersion = iexportVersionGo1_11 - -func additionalPredeclared() []types.Type { - return nil -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go deleted file mode 100644 index edbe6ea7..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.18 -// +build go1.18 - -package gcimporter - -import "go/types" - -const iexportVersion = iexportVersionGenerics - -// additionalPredeclared returns additional predeclared types in go.1.18. -func additionalPredeclared() []types.Type { - return []types.Type{ - // comparable - types.Universe.Lookup("comparable").Type(), - - // any - types.Universe.Lookup("any").Type(), - } -} - -// See cmd/compile/internal/types.SplitVargenSuffix. -func splitVargenSuffix(name string) (base, suffix string) { - i := len(name) - for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' { - i-- - } - const dot = "·" - if i >= len(dot) && name[i-len(dot):i] == dot { - i -= len(dot) - return name[:i], name[i:] - } - return name, "" -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go deleted file mode 100644 index 286bf445..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !(go1.18 && goexperiment.unified) -// +build !go1.18 !goexperiment.unified - -package gcimporter - -const unifiedIR = false diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go deleted file mode 100644 index b5d69ffb..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.18 && goexperiment.unified -// +build go1.18,goexperiment.unified - -package gcimporter - -const unifiedIR = true diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go deleted file mode 100644 index 8eb20729..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.18 -// +build !go1.18 - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" -) - -func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data") - return -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go deleted file mode 100644 index b977435f..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go +++ /dev/null @@ -1,728 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Derived from go/internal/gcimporter/ureader.go - -//go:build go1.18 -// +build go1.18 - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" - "sort" - "strings" - - "golang.org/x/tools/internal/pkgbits" -) - -// A pkgReader holds the shared state for reading a unified IR package -// description. -type pkgReader struct { - pkgbits.PkgDecoder - - fake fakeFileSet - - ctxt *types.Context - imports map[string]*types.Package // previously imported packages, indexed by path - - // lazily initialized arrays corresponding to the unified IR - // PosBase, Pkg, and Type sections, respectively. - posBases []string // position bases (i.e., file names) - pkgs []*types.Package - typs []types.Type - - // laterFns holds functions that need to be invoked at the end of - // import reading. - laterFns []func() - // laterFors is used in case of 'type A B' to ensure that B is processed before A. - laterFors map[types.Type]int - - // ifaces holds a list of constructed Interfaces, which need to have - // Complete called after importing is done. - ifaces []*types.Interface -} - -// later adds a function to be invoked at the end of import reading. -func (pr *pkgReader) later(fn func()) { - pr.laterFns = append(pr.laterFns, fn) -} - -// See cmd/compile/internal/noder.derivedInfo. -type derivedInfo struct { - idx pkgbits.Index - needed bool -} - -// See cmd/compile/internal/noder.typeInfo. -type typeInfo struct { - idx pkgbits.Index - derived bool -} - -func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - if !debug { - defer func() { - if x := recover(); x != nil { - err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x) - } - }() - } - - s := string(data) - s = s[:strings.LastIndex(s, "\n$$\n")] - input := pkgbits.NewPkgDecoder(path, s) - pkg = readUnifiedPackage(fset, nil, imports, input) - return -} - -// laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing. -func (pr *pkgReader) laterFor(t types.Type, fn func()) { - if pr.laterFors == nil { - pr.laterFors = make(map[types.Type]int) - } - pr.laterFors[t] = len(pr.laterFns) - pr.laterFns = append(pr.laterFns, fn) -} - -// readUnifiedPackage reads a package description from the given -// unified IR export data decoder. -func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { - pr := pkgReader{ - PkgDecoder: input, - - fake: fakeFileSet{ - fset: fset, - files: make(map[string]*fileInfo), - }, - - ctxt: ctxt, - imports: imports, - - posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), - pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), - typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), - } - defer pr.fake.setLines() - - r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) - pkg := r.pkg() - r.Bool() // has init - - for i, n := 0, r.Len(); i < n; i++ { - // As if r.obj(), but avoiding the Scope.Lookup call, - // to avoid eager loading of imports. - r.Sync(pkgbits.SyncObject) - assert(!r.Bool()) - r.p.objIdx(r.Reloc(pkgbits.RelocObj)) - assert(r.Len() == 0) - } - - r.Sync(pkgbits.SyncEOF) - - for _, fn := range pr.laterFns { - fn() - } - - for _, iface := range pr.ifaces { - iface.Complete() - } - - // Imports() of pkg are all of the transitive packages that were loaded. - var imps []*types.Package - for _, imp := range pr.pkgs { - if imp != nil && imp != pkg { - imps = append(imps, imp) - } - } - sort.Sort(byPath(imps)) - pkg.SetImports(imps) - - pkg.MarkComplete() - return pkg -} - -// A reader holds the state for reading a single unified IR element -// within a package. -type reader struct { - pkgbits.Decoder - - p *pkgReader - - dict *readerDict -} - -// A readerDict holds the state for type parameters that parameterize -// the current unified IR element. -type readerDict struct { - // bounds is a slice of typeInfos corresponding to the underlying - // bounds of the element's type parameters. - bounds []typeInfo - - // tparams is a slice of the constructed TypeParams for the element. - tparams []*types.TypeParam - - // devived is a slice of types derived from tparams, which may be - // instantiated while reading the current element. - derived []derivedInfo - derivedTypes []types.Type // lazily instantiated from derived -} - -func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { - return &reader{ - Decoder: pr.NewDecoder(k, idx, marker), - p: pr, - } -} - -func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { - return &reader{ - Decoder: pr.TempDecoder(k, idx, marker), - p: pr, - } -} - -func (pr *pkgReader) retireReader(r *reader) { - pr.RetireDecoder(&r.Decoder) -} - -// @@@ Positions - -func (r *reader) pos() token.Pos { - r.Sync(pkgbits.SyncPos) - if !r.Bool() { - return token.NoPos - } - - // TODO(mdempsky): Delta encoding. - posBase := r.posBase() - line := r.Uint() - col := r.Uint() - return r.p.fake.pos(posBase, int(line), int(col)) -} - -func (r *reader) posBase() string { - return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) -} - -func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { - if b := pr.posBases[idx]; b != "" { - return b - } - - var filename string - { - r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) - - // Within types2, position bases have a lot more details (e.g., - // keeping track of where //line directives appeared exactly). - // - // For go/types, we just track the file name. - - filename = r.String() - - if r.Bool() { // file base - // Was: "b = token.NewTrimmedFileBase(filename, true)" - } else { // line base - pos := r.pos() - line := r.Uint() - col := r.Uint() - - // Was: "b = token.NewLineBase(pos, filename, true, line, col)" - _, _, _ = pos, line, col - } - pr.retireReader(r) - } - b := filename - pr.posBases[idx] = b - return b -} - -// @@@ Packages - -func (r *reader) pkg() *types.Package { - r.Sync(pkgbits.SyncPkg) - return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) -} - -func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { - // TODO(mdempsky): Consider using some non-nil pointer to indicate - // the universe scope, so we don't need to keep re-reading it. - if pkg := pr.pkgs[idx]; pkg != nil { - return pkg - } - - pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() - pr.pkgs[idx] = pkg - return pkg -} - -func (r *reader) doPkg() *types.Package { - path := r.String() - switch path { - case "": - path = r.p.PkgPath() - case "builtin": - return nil // universe - case "unsafe": - return types.Unsafe - } - - if pkg := r.p.imports[path]; pkg != nil { - return pkg - } - - name := r.String() - - pkg := types.NewPackage(path, name) - r.p.imports[path] = pkg - - return pkg -} - -// @@@ Types - -func (r *reader) typ() types.Type { - return r.p.typIdx(r.typInfo(), r.dict) -} - -func (r *reader) typInfo() typeInfo { - r.Sync(pkgbits.SyncType) - if r.Bool() { - return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} - } - return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} -} - -func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { - idx := info.idx - var where *types.Type - if info.derived { - where = &dict.derivedTypes[idx] - idx = dict.derived[idx].idx - } else { - where = &pr.typs[idx] - } - - if typ := *where; typ != nil { - return typ - } - - var typ types.Type - { - r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) - r.dict = dict - - typ = r.doTyp() - assert(typ != nil) - pr.retireReader(r) - } - // See comment in pkgReader.typIdx explaining how this happens. - if prev := *where; prev != nil { - return prev - } - - *where = typ - return typ -} - -func (r *reader) doTyp() (res types.Type) { - switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { - default: - errorf("unhandled type tag: %v", tag) - panic("unreachable") - - case pkgbits.TypeBasic: - return types.Typ[r.Len()] - - case pkgbits.TypeNamed: - obj, targs := r.obj() - name := obj.(*types.TypeName) - if len(targs) != 0 { - t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) - return t - } - return name.Type() - - case pkgbits.TypeTypeParam: - return r.dict.tparams[r.Len()] - - case pkgbits.TypeArray: - len := int64(r.Uint64()) - return types.NewArray(r.typ(), len) - case pkgbits.TypeChan: - dir := types.ChanDir(r.Len()) - return types.NewChan(dir, r.typ()) - case pkgbits.TypeMap: - return types.NewMap(r.typ(), r.typ()) - case pkgbits.TypePointer: - return types.NewPointer(r.typ()) - case pkgbits.TypeSignature: - return r.signature(nil, nil, nil) - case pkgbits.TypeSlice: - return types.NewSlice(r.typ()) - case pkgbits.TypeStruct: - return r.structType() - case pkgbits.TypeInterface: - return r.interfaceType() - case pkgbits.TypeUnion: - return r.unionType() - } -} - -func (r *reader) structType() *types.Struct { - fields := make([]*types.Var, r.Len()) - var tags []string - for i := range fields { - pos := r.pos() - pkg, name := r.selector() - ftyp := r.typ() - tag := r.String() - embedded := r.Bool() - - fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) - if tag != "" { - for len(tags) < i { - tags = append(tags, "") - } - tags = append(tags, tag) - } - } - return types.NewStruct(fields, tags) -} - -func (r *reader) unionType() *types.Union { - terms := make([]*types.Term, r.Len()) - for i := range terms { - terms[i] = types.NewTerm(r.Bool(), r.typ()) - } - return types.NewUnion(terms) -} - -func (r *reader) interfaceType() *types.Interface { - methods := make([]*types.Func, r.Len()) - embeddeds := make([]types.Type, r.Len()) - implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() - - for i := range methods { - pos := r.pos() - pkg, name := r.selector() - mtyp := r.signature(nil, nil, nil) - methods[i] = types.NewFunc(pos, pkg, name, mtyp) - } - - for i := range embeddeds { - embeddeds[i] = r.typ() - } - - iface := types.NewInterfaceType(methods, embeddeds) - if implicit { - iface.MarkImplicit() - } - - // We need to call iface.Complete(), but if there are any embedded - // defined types, then we may not have set their underlying - // interface type yet. So we need to defer calling Complete until - // after we've called SetUnderlying everywhere. - // - // TODO(mdempsky): After CL 424876 lands, it should be safe to call - // iface.Complete() immediately. - r.p.ifaces = append(r.p.ifaces, iface) - - return iface -} - -func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { - r.Sync(pkgbits.SyncSignature) - - params := r.params() - results := r.params() - variadic := r.Bool() - - return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) -} - -func (r *reader) params() *types.Tuple { - r.Sync(pkgbits.SyncParams) - - params := make([]*types.Var, r.Len()) - for i := range params { - params[i] = r.param() - } - - return types.NewTuple(params...) -} - -func (r *reader) param() *types.Var { - r.Sync(pkgbits.SyncParam) - - pos := r.pos() - pkg, name := r.localIdent() - typ := r.typ() - - return types.NewParam(pos, pkg, name, typ) -} - -// @@@ Objects - -func (r *reader) obj() (types.Object, []types.Type) { - r.Sync(pkgbits.SyncObject) - - assert(!r.Bool()) - - pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) - obj := pkgScope(pkg).Lookup(name) - - targs := make([]types.Type, r.Len()) - for i := range targs { - targs[i] = r.typ() - } - - return obj, targs -} - -func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { - - var objPkg *types.Package - var objName string - var tag pkgbits.CodeObj - { - rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) - - objPkg, objName = rname.qualifiedIdent() - assert(objName != "") - - tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) - pr.retireReader(rname) - } - - if tag == pkgbits.ObjStub { - assert(objPkg == nil || objPkg == types.Unsafe) - return objPkg, objName - } - - // Ignore local types promoted to global scope (#55110). - if _, suffix := splitVargenSuffix(objName); suffix != "" { - return objPkg, objName - } - - if objPkg.Scope().Lookup(objName) == nil { - dict := pr.objDictIdx(idx) - - r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) - r.dict = dict - - declare := func(obj types.Object) { - objPkg.Scope().Insert(obj) - } - - switch tag { - default: - panic("weird") - - case pkgbits.ObjAlias: - pos := r.pos() - typ := r.typ() - declare(types.NewTypeName(pos, objPkg, objName, typ)) - - case pkgbits.ObjConst: - pos := r.pos() - typ := r.typ() - val := r.Value() - declare(types.NewConst(pos, objPkg, objName, typ, val)) - - case pkgbits.ObjFunc: - pos := r.pos() - tparams := r.typeParamNames() - sig := r.signature(nil, nil, tparams) - declare(types.NewFunc(pos, objPkg, objName, sig)) - - case pkgbits.ObjType: - pos := r.pos() - - obj := types.NewTypeName(pos, objPkg, objName, nil) - named := types.NewNamed(obj, nil, nil) - declare(obj) - - named.SetTypeParams(r.typeParamNames()) - - setUnderlying := func(underlying types.Type) { - // If the underlying type is an interface, we need to - // duplicate its methods so we can replace the receiver - // parameter's type (#49906). - if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 { - methods := make([]*types.Func, iface.NumExplicitMethods()) - for i := range methods { - fn := iface.ExplicitMethod(i) - sig := fn.Type().(*types.Signature) - - recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named) - methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic())) - } - - embeds := make([]types.Type, iface.NumEmbeddeds()) - for i := range embeds { - embeds[i] = iface.EmbeddedType(i) - } - - newIface := types.NewInterfaceType(methods, embeds) - r.p.ifaces = append(r.p.ifaces, newIface) - underlying = newIface - } - - named.SetUnderlying(underlying) - } - - // Since go.dev/cl/455279, we can assume rhs.Underlying() will - // always be non-nil. However, to temporarily support users of - // older snapshot releases, we continue to fallback to the old - // behavior for now. - // - // TODO(mdempsky): Remove fallback code and simplify after - // allowing time for snapshot users to upgrade. - rhs := r.typ() - if underlying := rhs.Underlying(); underlying != nil { - setUnderlying(underlying) - } else { - pk := r.p - pk.laterFor(named, func() { - // First be sure that the rhs is initialized, if it needs to be initialized. - delete(pk.laterFors, named) // prevent cycles - if i, ok := pk.laterFors[rhs]; ok { - f := pk.laterFns[i] - pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op - f() // initialize RHS - } - setUnderlying(rhs.Underlying()) - }) - } - - for i, n := 0, r.Len(); i < n; i++ { - named.AddMethod(r.method()) - } - - case pkgbits.ObjVar: - pos := r.pos() - typ := r.typ() - declare(types.NewVar(pos, objPkg, objName, typ)) - } - } - - return objPkg, objName -} - -func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { - - var dict readerDict - - { - r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) - if implicits := r.Len(); implicits != 0 { - errorf("unexpected object with %v implicit type parameter(s)", implicits) - } - - dict.bounds = make([]typeInfo, r.Len()) - for i := range dict.bounds { - dict.bounds[i] = r.typInfo() - } - - dict.derived = make([]derivedInfo, r.Len()) - dict.derivedTypes = make([]types.Type, len(dict.derived)) - for i := range dict.derived { - dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()} - } - - pr.retireReader(r) - } - // function references follow, but reader doesn't need those - - return &dict -} - -func (r *reader) typeParamNames() []*types.TypeParam { - r.Sync(pkgbits.SyncTypeParamNames) - - // Note: This code assumes it only processes objects without - // implement type parameters. This is currently fine, because - // reader is only used to read in exported declarations, which are - // always package scoped. - - if len(r.dict.bounds) == 0 { - return nil - } - - // Careful: Type parameter lists may have cycles. To allow for this, - // we construct the type parameter list in two passes: first we - // create all the TypeNames and TypeParams, then we construct and - // set the bound type. - - r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds)) - for i := range r.dict.bounds { - pos := r.pos() - pkg, name := r.localIdent() - - tname := types.NewTypeName(pos, pkg, name, nil) - r.dict.tparams[i] = types.NewTypeParam(tname, nil) - } - - typs := make([]types.Type, len(r.dict.bounds)) - for i, bound := range r.dict.bounds { - typs[i] = r.p.typIdx(bound, r.dict) - } - - // TODO(mdempsky): This is subtle, elaborate further. - // - // We have to save tparams outside of the closure, because - // typeParamNames() can be called multiple times with the same - // dictionary instance. - // - // Also, this needs to happen later to make sure SetUnderlying has - // been called. - // - // TODO(mdempsky): Is it safe to have a single "later" slice or do - // we need to have multiple passes? See comments on CL 386002 and - // go.dev/issue/52104. - tparams := r.dict.tparams - r.p.later(func() { - for i, typ := range typs { - tparams[i].SetConstraint(typ) - } - }) - - return r.dict.tparams -} - -func (r *reader) method() *types.Func { - r.Sync(pkgbits.SyncMethod) - pos := r.pos() - pkg, name := r.selector() - - rparams := r.typeParamNames() - sig := r.signature(r.param(), rparams, nil) - - _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. - return types.NewFunc(pos, pkg, name, sig) -} - -func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } -func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } -func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } - -func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { - r.Sync(marker) - return r.pkg(), r.String() -} - -// pkgScope returns pkg.Scope(). -// If pkg is nil, it returns types.Universe instead. -// -// TODO(mdempsky): Remove after x/tools can depend on Go 1.19. -func pkgScope(pkg *types.Package) *types.Scope { - if pkg != nil { - return pkg.Scope() - } - return types.Universe -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go deleted file mode 100644 index 55312522..00000000 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ /dev/null @@ -1,465 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gocommand is a helper for calling the go command. -package gocommand - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "log" - "os" - "os/exec" - "reflect" - "regexp" - "runtime" - "strconv" - "strings" - "sync" - "time" - - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" - "golang.org/x/tools/internal/event/tag" -) - -// An Runner will run go command invocations and serialize -// them if it sees a concurrency error. -type Runner struct { - // once guards the runner initialization. - once sync.Once - - // inFlight tracks available workers. - inFlight chan struct{} - - // serialized guards the ability to run a go command serially, - // to avoid deadlocks when claiming workers. - serialized chan struct{} -} - -const maxInFlight = 10 - -func (runner *Runner) initialize() { - runner.once.Do(func() { - runner.inFlight = make(chan struct{}, maxInFlight) - runner.serialized = make(chan struct{}, 1) - }) -} - -// 1.13: go: updates to go.mod needed, but contents have changed -// 1.14: go: updating go.mod: existing contents have changed since last read -var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`) - -// verb is an event label for the go command verb. -var verb = keys.NewString("verb", "go command verb") - -func invLabels(inv Invocation) []label.Label { - return []label.Label{verb.Of(inv.Verb), tag.Directory.Of(inv.WorkingDir)} -} - -// Run is a convenience wrapper around RunRaw. -// It returns only stdout and a "friendly" error. -func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) { - ctx, done := event.Start(ctx, "gocommand.Runner.Run", invLabels(inv)...) - defer done() - - stdout, _, friendly, _ := runner.RunRaw(ctx, inv) - return stdout, friendly -} - -// RunPiped runs the invocation serially, always waiting for any concurrent -// invocations to complete first. -func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error { - ctx, done := event.Start(ctx, "gocommand.Runner.RunPiped", invLabels(inv)...) - defer done() - - _, err := runner.runPiped(ctx, inv, stdout, stderr) - return err -} - -// RunRaw runs the invocation, serializing requests only if they fight over -// go.mod changes. -// Postcondition: both error results have same nilness. -func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { - ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...) - defer done() - // Make sure the runner is always initialized. - runner.initialize() - - // First, try to run the go command concurrently. - stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv) - - // If we encounter a load concurrency error, we need to retry serially. - if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) { - event.Error(ctx, "Load concurrency error, will retry serially", err) - - // Run serially by calling runPiped. - stdout.Reset() - stderr.Reset() - friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) - } - - return stdout, stderr, friendlyErr, err -} - -// Postcondition: both error results have same nilness. -func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { - // Wait for 1 worker to become available. - select { - case <-ctx.Done(): - return nil, nil, ctx.Err(), ctx.Err() - case runner.inFlight <- struct{}{}: - defer func() { <-runner.inFlight }() - } - - stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} - friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr) - return stdout, stderr, friendlyErr, err -} - -// Postcondition: both error results have same nilness. -func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) { - // Make sure the runner is always initialized. - runner.initialize() - - // Acquire the serialization lock. This avoids deadlocks between two - // runPiped commands. - select { - case <-ctx.Done(): - return ctx.Err(), ctx.Err() - case runner.serialized <- struct{}{}: - defer func() { <-runner.serialized }() - } - - // Wait for all in-progress go commands to return before proceeding, - // to avoid load concurrency errors. - for i := 0; i < maxInFlight; i++ { - select { - case <-ctx.Done(): - return ctx.Err(), ctx.Err() - case runner.inFlight <- struct{}{}: - // Make sure we always "return" any workers we took. - defer func() { <-runner.inFlight }() - } - } - - return inv.runWithFriendlyError(ctx, stdout, stderr) -} - -// An Invocation represents a call to the go command. -type Invocation struct { - Verb string - Args []string - BuildFlags []string - - // If ModFlag is set, the go command is invoked with -mod=ModFlag. - ModFlag string - - // If ModFile is set, the go command is invoked with -modfile=ModFile. - ModFile string - - // If Overlay is set, the go command is invoked with -overlay=Overlay. - Overlay string - - // If CleanEnv is set, the invocation will run only with the environment - // in Env, not starting with os.Environ. - CleanEnv bool - Env []string - WorkingDir string - Logf func(format string, args ...interface{}) -} - -// Postcondition: both error results have same nilness. -func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) { - rawError = i.run(ctx, stdout, stderr) - if rawError != nil { - friendlyError = rawError - // Check for 'go' executable not being found. - if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound { - friendlyError = fmt.Errorf("go command required, not found: %v", ee) - } - if ctx.Err() != nil { - friendlyError = ctx.Err() - } - friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr) - } - return -} - -func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { - log := i.Logf - if log == nil { - log = func(string, ...interface{}) {} - } - - goArgs := []string{i.Verb} - - appendModFile := func() { - if i.ModFile != "" { - goArgs = append(goArgs, "-modfile="+i.ModFile) - } - } - appendModFlag := func() { - if i.ModFlag != "" { - goArgs = append(goArgs, "-mod="+i.ModFlag) - } - } - appendOverlayFlag := func() { - if i.Overlay != "" { - goArgs = append(goArgs, "-overlay="+i.Overlay) - } - } - - switch i.Verb { - case "env", "version": - goArgs = append(goArgs, i.Args...) - case "mod": - // mod needs the sub-verb before flags. - goArgs = append(goArgs, i.Args[0]) - appendModFile() - goArgs = append(goArgs, i.Args[1:]...) - case "get": - goArgs = append(goArgs, i.BuildFlags...) - appendModFile() - goArgs = append(goArgs, i.Args...) - - default: // notably list and build. - goArgs = append(goArgs, i.BuildFlags...) - appendModFile() - appendModFlag() - appendOverlayFlag() - goArgs = append(goArgs, i.Args...) - } - cmd := exec.Command("go", goArgs...) - cmd.Stdout = stdout - cmd.Stderr = stderr - - // cmd.WaitDelay was added only in go1.20 (see #50436). - if waitDelay := reflect.ValueOf(cmd).Elem().FieldByName("WaitDelay"); waitDelay.IsValid() { - // https://go.dev/issue/59541: don't wait forever copying stderr - // after the command has exited. - // After CL 484741 we copy stdout manually, so we we'll stop reading that as - // soon as ctx is done. However, we also don't want to wait around forever - // for stderr. Give a much-longer-than-reasonable delay and then assume that - // something has wedged in the kernel or runtime. - waitDelay.Set(reflect.ValueOf(30 * time.Second)) - } - - // On darwin the cwd gets resolved to the real path, which breaks anything that - // expects the working directory to keep the original path, including the - // go command when dealing with modules. - // The Go stdlib has a special feature where if the cwd and the PWD are the - // same node then it trusts the PWD, so by setting it in the env for the child - // process we fix up all the paths returned by the go command. - if !i.CleanEnv { - cmd.Env = os.Environ() - } - cmd.Env = append(cmd.Env, i.Env...) - if i.WorkingDir != "" { - cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir) - cmd.Dir = i.WorkingDir - } - - defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now()) - - return runCmdContext(ctx, cmd) -} - -// DebugHangingGoCommands may be set by tests to enable additional -// instrumentation (including panics) for debugging hanging Go commands. -// -// See golang/go#54461 for details. -var DebugHangingGoCommands = false - -// runCmdContext is like exec.CommandContext except it sends os.Interrupt -// before os.Kill. -func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) { - // If cmd.Stdout is not an *os.File, the exec package will create a pipe and - // copy it to the Writer in a goroutine until the process has finished and - // either the pipe reaches EOF or command's WaitDelay expires. - // - // However, the output from 'go list' can be quite large, and we don't want to - // keep reading (and allocating buffers) if we've already decided we don't - // care about the output. We don't want to wait for the process to finish, and - // we don't wait to wait for the WaitDelay to expire either. - // - // Instead, if cmd.Stdout requires a copying goroutine we explicitly replace - // it with a pipe (which is an *os.File), which we can close in order to stop - // copying output as soon as we realize we don't care about it. - var stdoutW *os.File - if cmd.Stdout != nil { - if _, ok := cmd.Stdout.(*os.File); !ok { - var stdoutR *os.File - stdoutR, stdoutW, err = os.Pipe() - if err != nil { - return err - } - prevStdout := cmd.Stdout - cmd.Stdout = stdoutW - - stdoutErr := make(chan error, 1) - go func() { - _, err := io.Copy(prevStdout, stdoutR) - if err != nil { - err = fmt.Errorf("copying stdout: %w", err) - } - stdoutErr <- err - }() - defer func() { - // We started a goroutine to copy a stdout pipe. - // Wait for it to finish, or terminate it if need be. - var err2 error - select { - case err2 = <-stdoutErr: - stdoutR.Close() - case <-ctx.Done(): - stdoutR.Close() - // Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close - // should cause the Read call in io.Copy to unblock and return - // immediately, but we still need to receive from stdoutErr to confirm - // that it has happened. - <-stdoutErr - err2 = ctx.Err() - } - if err == nil { - err = err2 - } - }() - - // Per https://pkg.go.dev/os/exec#Cmd, “If Stdout and Stderr are the - // same writer, and have a type that can be compared with ==, at most - // one goroutine at a time will call Write.” - // - // Since we're starting a goroutine that writes to cmd.Stdout, we must - // also update cmd.Stderr so that it still holds. - func() { - defer func() { recover() }() - if cmd.Stderr == prevStdout { - cmd.Stderr = cmd.Stdout - } - }() - } - } - - err = cmd.Start() - if stdoutW != nil { - // The child process has inherited the pipe file, - // so close the copy held in this process. - stdoutW.Close() - stdoutW = nil - } - if err != nil { - return err - } - - resChan := make(chan error, 1) - go func() { - resChan <- cmd.Wait() - }() - - // If we're interested in debugging hanging Go commands, stop waiting after a - // minute and panic with interesting information. - debug := DebugHangingGoCommands - if debug { - timer := time.NewTimer(1 * time.Minute) - defer timer.Stop() - select { - case err := <-resChan: - return err - case <-timer.C: - HandleHangingGoCommand(cmd.Process) - case <-ctx.Done(): - } - } else { - select { - case err := <-resChan: - return err - case <-ctx.Done(): - } - } - - // Cancelled. Interrupt and see if it ends voluntarily. - if err := cmd.Process.Signal(os.Interrupt); err == nil { - // (We used to wait only 1s but this proved - // fragile on loaded builder machines.) - timer := time.NewTimer(5 * time.Second) - defer timer.Stop() - select { - case err := <-resChan: - return err - case <-timer.C: - } - } - - // Didn't shut down in response to interrupt. Kill it hard. - // TODO(rfindley): per advice from bcmills@, it may be better to send SIGQUIT - // on certain platforms, such as unix. - if err := cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) && debug { - log.Printf("error killing the Go command: %v", err) - } - - return <-resChan -} - -func HandleHangingGoCommand(proc *os.Process) { - switch runtime.GOOS { - case "linux", "darwin", "freebsd", "netbsd": - fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND - -The gopls test runner has detected a hanging go command. In order to debug -this, the output of ps and lsof/fstat is printed below. - -See golang/go#54461 for more details.`) - - fmt.Fprintln(os.Stderr, "\nps axo ppid,pid,command:") - fmt.Fprintln(os.Stderr, "-------------------------") - psCmd := exec.Command("ps", "axo", "ppid,pid,command") - psCmd.Stdout = os.Stderr - psCmd.Stderr = os.Stderr - if err := psCmd.Run(); err != nil { - panic(fmt.Sprintf("running ps: %v", err)) - } - - listFiles := "lsof" - if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { - listFiles = "fstat" - } - - fmt.Fprintln(os.Stderr, "\n"+listFiles+":") - fmt.Fprintln(os.Stderr, "-----") - listFilesCmd := exec.Command(listFiles) - listFilesCmd.Stdout = os.Stderr - listFilesCmd.Stderr = os.Stderr - if err := listFilesCmd.Run(); err != nil { - panic(fmt.Sprintf("running %s: %v", listFiles, err)) - } - } - panic(fmt.Sprintf("detected hanging go command (pid %d): see golang/go#54461 for more details", proc.Pid)) -} - -func cmdDebugStr(cmd *exec.Cmd) string { - env := make(map[string]string) - for _, kv := range cmd.Env { - split := strings.SplitN(kv, "=", 2) - if len(split) == 2 { - k, v := split[0], split[1] - env[k] = v - } - } - - var args []string - for _, arg := range cmd.Args { - quoted := strconv.Quote(arg) - if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { - args = append(args, quoted) - } else { - args = append(args, arg) - } - } - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go deleted file mode 100644 index 2d3d408c..00000000 --- a/vendor/golang.org/x/tools/internal/gocommand/vendor.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocommand - -import ( - "bytes" - "context" - "fmt" - "os" - "path/filepath" - "regexp" - "strings" - "time" - - "golang.org/x/mod/semver" -) - -// ModuleJSON holds information about a module. -type ModuleJSON struct { - Path string // module path - Version string // module version - Versions []string // available module versions (with -versions) - Replace *ModuleJSON // replaced by this module - Time *time.Time // time version was created - Update *ModuleJSON // available update, if any (with -u) - Main bool // is this the main module? - Indirect bool // is this module only an indirect dependency of main module? - Dir string // directory holding files for this module, if any - GoMod string // path to go.mod file used when loading this module, if any - GoVersion string // go version used in module -} - -var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) - -// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands -// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, -// of which only Verb and Args are modified to run the appropriate Go command. -// Inspired by setDefaultBuildMod in modload/init.go -func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) { - mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) - if err != nil { - return false, nil, err - } - - // We check the GOFLAGS to see if there is anything overridden or not. - inv.Verb = "env" - inv.Args = []string{"GOFLAGS"} - stdout, err := r.Run(ctx, inv) - if err != nil { - return false, nil, err - } - goflags := string(bytes.TrimSpace(stdout.Bytes())) - matches := modFlagRegexp.FindStringSubmatch(goflags) - var modFlag string - if len(matches) != 0 { - modFlag = matches[1] - } - // Don't override an explicit '-mod=' argument. - if modFlag == "vendor" { - return true, mainMod, nil - } else if modFlag != "" { - return false, nil, nil - } - if mainMod == nil || !go114 { - return false, nil, nil - } - // Check 1.14's automatic vendor mode. - if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { - if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { - // The Go version is at least 1.14, and a vendor directory exists. - // Set -mod=vendor by default. - return true, mainMod, nil - } - } - return false, nil, nil -} - -// getMainModuleAnd114 gets one of the main modules' information and whether the -// go command in use is 1.14+. This is the information needed to figure out -// if vendoring should be enabled. -func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { - const format = `{{.Path}} -{{.Dir}} -{{.GoMod}} -{{.GoVersion}} -{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}} -` - inv.Verb = "list" - inv.Args = []string{"-m", "-f", format} - stdout, err := r.Run(ctx, inv) - if err != nil { - return nil, false, err - } - - lines := strings.Split(stdout.String(), "\n") - if len(lines) < 5 { - return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String()) - } - mod := &ModuleJSON{ - Path: lines[0], - Dir: lines[1], - GoMod: lines[2], - GoVersion: lines[3], - Main: true, - } - return mod, lines[4] == "go1.14", nil -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go deleted file mode 100644 index 446c5846..00000000 --- a/vendor/golang.org/x/tools/internal/gocommand/version.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocommand - -import ( - "context" - "fmt" - "regexp" - "strings" -) - -// GoVersion reports the minor version number of the highest release -// tag built into the go command on the PATH. -// -// Note that this may be higher than the version of the go tool used -// to build this application, and thus the versions of the standard -// go/{scanner,parser,ast,types} packages that are linked into it. -// In that case, callers should either downgrade to the version of -// go used to build the application, or report an error that the -// application is too old to use the go command on the PATH. -func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { - inv.Verb = "list" - inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`} - inv.BuildFlags = nil // This is not a build command. - inv.ModFlag = "" - inv.ModFile = "" - inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off") - - stdoutBytes, err := r.Run(ctx, inv) - if err != nil { - return 0, err - } - stdout := stdoutBytes.String() - if len(stdout) < 3 { - return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout) - } - // Split up "[go1.1 go1.15]" and return highest go1.X value. - tags := strings.Fields(stdout[1 : len(stdout)-2]) - for i := len(tags) - 1; i >= 0; i-- { - var version int - if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil { - continue - } - return version, nil - } - return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags) -} - -// GoVersionOutput returns the complete output of the go version command. -func GoVersionOutput(ctx context.Context, inv Invocation, r *Runner) (string, error) { - inv.Verb = "version" - goVersion, err := r.Run(ctx, inv) - if err != nil { - return "", err - } - return goVersion.String(), nil -} - -// ParseGoVersionOutput extracts the Go version string -// from the output of the "go version" command. -// Given an unrecognized form, it returns an empty string. -func ParseGoVersionOutput(data string) string { - re := regexp.MustCompile(`^go version (go\S+|devel \S+)`) - m := re.FindStringSubmatch(data) - if len(m) != 2 { - return "" // unrecognized version - } - return m[1] -} diff --git a/vendor/golang.org/x/tools/internal/gopathwalk/walk.go b/vendor/golang.org/x/tools/internal/gopathwalk/walk.go deleted file mode 100644 index 52f74e64..00000000 --- a/vendor/golang.org/x/tools/internal/gopathwalk/walk.go +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gopathwalk is like filepath.Walk but specialized for finding Go -// packages, particularly in $GOPATH and $GOROOT. -package gopathwalk - -import ( - "bufio" - "bytes" - "io/fs" - "log" - "os" - "path/filepath" - "strings" - "time" -) - -// Options controls the behavior of a Walk call. -type Options struct { - // If Logf is non-nil, debug logging is enabled through this function. - Logf func(format string, args ...interface{}) - // Search module caches. Also disables legacy goimports ignore rules. - ModulesEnabled bool -} - -// RootType indicates the type of a Root. -type RootType int - -const ( - RootUnknown RootType = iota - RootGOROOT - RootGOPATH - RootCurrentModule - RootModuleCache - RootOther -) - -// A Root is a starting point for a Walk. -type Root struct { - Path string - Type RootType -} - -// Walk walks Go source directories ($GOROOT, $GOPATH, etc) to find packages. -// For each package found, add will be called with the absolute -// paths of the containing source directory and the package directory. -func Walk(roots []Root, add func(root Root, dir string), opts Options) { - WalkSkip(roots, add, func(Root, string) bool { return false }, opts) -} - -// WalkSkip walks Go source directories ($GOROOT, $GOPATH, etc) to find packages. -// For each package found, add will be called with the absolute -// paths of the containing source directory and the package directory. -// For each directory that will be scanned, skip will be called -// with the absolute paths of the containing source directory and the directory. -// If skip returns false on a directory it will be processed. -func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root, dir string) bool, opts Options) { - for _, root := range roots { - walkDir(root, add, skip, opts) - } -} - -// walkDir creates a walker and starts fastwalk with this walker. -func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) { - if _, err := os.Stat(root.Path); os.IsNotExist(err) { - if opts.Logf != nil { - opts.Logf("skipping nonexistent directory: %v", root.Path) - } - return - } - start := time.Now() - if opts.Logf != nil { - opts.Logf("scanning %s", root.Path) - } - - w := &walker{ - root: root, - add: add, - skip: skip, - opts: opts, - added: make(map[string]bool), - } - w.init() - - // Add a trailing path separator to cause filepath.WalkDir to traverse symlinks. - path := root.Path - if len(path) == 0 { - path = "." + string(filepath.Separator) - } else if !os.IsPathSeparator(path[len(path)-1]) { - path = path + string(filepath.Separator) - } - - if err := filepath.WalkDir(path, w.walk); err != nil { - logf := opts.Logf - if logf == nil { - logf = log.Printf - } - logf("scanning directory %v: %v", root.Path, err) - } - - if opts.Logf != nil { - opts.Logf("scanned %s in %v", root.Path, time.Since(start)) - } -} - -// walker is the callback for fastwalk.Walk. -type walker struct { - root Root // The source directory to scan. - add func(Root, string) // The callback that will be invoked for every possible Go package dir. - skip func(Root, string) bool // The callback that will be invoked for every dir. dir is skipped if it returns true. - opts Options // Options passed to Walk by the user. - - pathSymlinks []os.FileInfo - ignoredDirs []string - - added map[string]bool -} - -// init initializes the walker based on its Options -func (w *walker) init() { - var ignoredPaths []string - if w.root.Type == RootModuleCache { - ignoredPaths = []string{"cache"} - } - if !w.opts.ModulesEnabled && w.root.Type == RootGOPATH { - ignoredPaths = w.getIgnoredDirs(w.root.Path) - ignoredPaths = append(ignoredPaths, "v", "mod") - } - - for _, p := range ignoredPaths { - full := filepath.Join(w.root.Path, p) - w.ignoredDirs = append(w.ignoredDirs, full) - if w.opts.Logf != nil { - w.opts.Logf("Directory added to ignore list: %s", full) - } - } -} - -// getIgnoredDirs reads an optional config file at /.goimportsignore -// of relative directories to ignore when scanning for go files. -// The provided path is one of the $GOPATH entries with "src" appended. -func (w *walker) getIgnoredDirs(path string) []string { - file := filepath.Join(path, ".goimportsignore") - slurp, err := os.ReadFile(file) - if w.opts.Logf != nil { - if err != nil { - w.opts.Logf("%v", err) - } else { - w.opts.Logf("Read %s", file) - } - } - if err != nil { - return nil - } - - var ignoredDirs []string - bs := bufio.NewScanner(bytes.NewReader(slurp)) - for bs.Scan() { - line := strings.TrimSpace(bs.Text()) - if line == "" || strings.HasPrefix(line, "#") { - continue - } - ignoredDirs = append(ignoredDirs, line) - } - return ignoredDirs -} - -// shouldSkipDir reports whether the file should be skipped or not. -func (w *walker) shouldSkipDir(dir string) bool { - for _, ignoredDir := range w.ignoredDirs { - if dir == ignoredDir { - return true - } - } - if w.skip != nil { - // Check with the user specified callback. - return w.skip(w.root, dir) - } - return false -} - -// walk walks through the given path. -// -// Errors are logged if w.opts.Logf is non-nil, but otherwise ignored: -// walk returns only nil or fs.SkipDir. -func (w *walker) walk(path string, d fs.DirEntry, err error) error { - if err != nil { - // We have no way to report errors back through Walk or WalkSkip, - // so just log and ignore them. - if w.opts.Logf != nil { - w.opts.Logf("%v", err) - } - if d == nil { - // Nothing more to do: the error prevents us from knowing - // what path even represents. - return nil - } - } - - if d.Type().IsRegular() { - if !strings.HasSuffix(path, ".go") { - return nil - } - - dir := filepath.Dir(path) - if dir == w.root.Path && (w.root.Type == RootGOROOT || w.root.Type == RootGOPATH) { - // Doesn't make sense to have regular files - // directly in your $GOPATH/src or $GOROOT/src. - return nil - } - - if !w.added[dir] { - w.add(w.root, dir) - w.added[dir] = true - } - return nil - } - - if d.IsDir() { - base := filepath.Base(path) - if base == "" || base[0] == '.' || base[0] == '_' || - base == "testdata" || - (w.root.Type == RootGOROOT && w.opts.ModulesEnabled && base == "vendor") || - (!w.opts.ModulesEnabled && base == "node_modules") { - return fs.SkipDir - } - if w.shouldSkipDir(path) { - return fs.SkipDir - } - return nil - } - - if d.Type()&os.ModeSymlink != 0 { - // TODO(bcmills): 'go list all' itself ignores symlinks within GOROOT/src - // and GOPATH/src. Do we really need to traverse them here? If so, why? - - fi, err := os.Stat(path) - if err != nil || !fi.IsDir() { - // Not a directory. Just walk the file (or broken link) and be done. - return w.walk(path, fs.FileInfoToDirEntry(fi), err) - } - - // Avoid walking symlink cycles: if we have already followed a symlink to - // this directory as a parent of itself, don't follow it again. - // - // This doesn't catch the first time through a cycle, but it also minimizes - // the number of extra stat calls we make if we *don't* encounter a cycle. - // Since we don't actually expect to encounter symlink cycles in practice, - // this seems like the right tradeoff. - for _, parent := range w.pathSymlinks { - if os.SameFile(fi, parent) { - return nil - } - } - - w.pathSymlinks = append(w.pathSymlinks, fi) - defer func() { - w.pathSymlinks = w.pathSymlinks[:len(w.pathSymlinks)-1] - }() - - // On some platforms the OS (or the Go os package) sometimes fails to - // resolve directory symlinks before a trailing slash - // (even though POSIX requires it to do so). - // - // On macOS that failure may be caused by a known libc/kernel bug; - // see https://go.dev/issue/59586. - // - // On Windows before Go 1.21, it may be caused by a bug in - // os.Lstat (fixed in https://go.dev/cl/463177). - // - // Since we need to handle this explicitly on broken platforms anyway, - // it is simplest to just always do that and not rely on POSIX pathname - // resolution to walk the directory (such as by calling WalkDir with - // a trailing slash appended to the path). - // - // Instead, we make a sequence of walk calls — directly and through - // recursive calls to filepath.WalkDir — simulating what WalkDir would do - // if the symlink were a regular directory. - - // First we call walk on the path as a directory - // (instead of a symlink). - err = w.walk(path, fs.FileInfoToDirEntry(fi), nil) - if err == fs.SkipDir { - return nil - } else if err != nil { - // This should be impossible, but handle it anyway in case - // walk is changed to return other errors. - return err - } - - // Now read the directory and walk its entries. - ents, err := os.ReadDir(path) - if err != nil { - // Report the ReadDir error, as filepath.WalkDir would do. - err = w.walk(path, fs.FileInfoToDirEntry(fi), err) - if err == fs.SkipDir { - return nil - } else if err != nil { - return err // Again, should be impossible. - } - // Fall through and iterate over whatever entries we did manage to get. - } - - for _, d := range ents { - nextPath := filepath.Join(path, d.Name()) - if d.IsDir() { - // We want to walk the whole directory tree rooted at nextPath, - // not just the single entry for the directory. - err := filepath.WalkDir(nextPath, w.walk) - if err != nil && w.opts.Logf != nil { - w.opts.Logf("%v", err) - } - } else { - err := w.walk(nextPath, d, nil) - if err == fs.SkipDir { - // Skip the rest of the entries in the parent directory of nextPath - // (that is, path itself). - break - } else if err != nil { - return err // Again, should be impossible. - } - } - } - return nil - } - - // Not a file, regular directory, or symlink; skip. - return nil -} diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go deleted file mode 100644 index dd369c07..00000000 --- a/vendor/golang.org/x/tools/internal/imports/fix.go +++ /dev/null @@ -1,1769 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package imports - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/token" - "io/fs" - "io/ioutil" - "os" - "path" - "path/filepath" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "unicode" - "unicode/utf8" - - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/gopathwalk" -) - -// importToGroup is a list of functions which map from an import path to -// a group number. -var importToGroup = []func(localPrefix, importPath string) (num int, ok bool){ - func(localPrefix, importPath string) (num int, ok bool) { - if localPrefix == "" { - return - } - for _, p := range strings.Split(localPrefix, ",") { - if strings.HasPrefix(importPath, p) || strings.TrimSuffix(p, "/") == importPath { - return 3, true - } - } - return - }, - func(_, importPath string) (num int, ok bool) { - if strings.HasPrefix(importPath, "appengine") { - return 2, true - } - return - }, - func(_, importPath string) (num int, ok bool) { - firstComponent := strings.Split(importPath, "/")[0] - if strings.Contains(firstComponent, ".") { - return 1, true - } - return - }, -} - -func importGroup(localPrefix, importPath string) int { - for _, fn := range importToGroup { - if n, ok := fn(localPrefix, importPath); ok { - return n - } - } - return 0 -} - -type ImportFixType int - -const ( - AddImport ImportFixType = iota - DeleteImport - SetImportName -) - -type ImportFix struct { - // StmtInfo represents the import statement this fix will add, remove, or change. - StmtInfo ImportInfo - // IdentName is the identifier that this fix will add or remove. - IdentName string - // FixType is the type of fix this is (AddImport, DeleteImport, SetImportName). - FixType ImportFixType - Relevance float64 // see pkg -} - -// An ImportInfo represents a single import statement. -type ImportInfo struct { - ImportPath string // import path, e.g. "crypto/rand". - Name string // import name, e.g. "crand", or "" if none. -} - -// A packageInfo represents what's known about a package. -type packageInfo struct { - name string // real package name, if known. - exports map[string]bool // known exports. -} - -// parseOtherFiles parses all the Go files in srcDir except filename, including -// test files if filename looks like a test. -func parseOtherFiles(fset *token.FileSet, srcDir, filename string) []*ast.File { - // This could use go/packages but it doesn't buy much, and it fails - // with https://golang.org/issue/26296 in LoadFiles mode in some cases. - considerTests := strings.HasSuffix(filename, "_test.go") - - fileBase := filepath.Base(filename) - packageFileInfos, err := os.ReadDir(srcDir) - if err != nil { - return nil - } - - var files []*ast.File - for _, fi := range packageFileInfos { - if fi.Name() == fileBase || !strings.HasSuffix(fi.Name(), ".go") { - continue - } - if !considerTests && strings.HasSuffix(fi.Name(), "_test.go") { - continue - } - - f, err := parser.ParseFile(fset, filepath.Join(srcDir, fi.Name()), nil, 0) - if err != nil { - continue - } - - files = append(files, f) - } - - return files -} - -// addGlobals puts the names of package vars into the provided map. -func addGlobals(f *ast.File, globals map[string]bool) { - for _, decl := range f.Decls { - genDecl, ok := decl.(*ast.GenDecl) - if !ok { - continue - } - - for _, spec := range genDecl.Specs { - valueSpec, ok := spec.(*ast.ValueSpec) - if !ok { - continue - } - globals[valueSpec.Names[0].Name] = true - } - } -} - -// collectReferences builds a map of selector expressions, from -// left hand side (X) to a set of right hand sides (Sel). -func collectReferences(f *ast.File) references { - refs := references{} - - var visitor visitFn - visitor = func(node ast.Node) ast.Visitor { - if node == nil { - return visitor - } - switch v := node.(type) { - case *ast.SelectorExpr: - xident, ok := v.X.(*ast.Ident) - if !ok { - break - } - if xident.Obj != nil { - // If the parser can resolve it, it's not a package ref. - break - } - if !ast.IsExported(v.Sel.Name) { - // Whatever this is, it's not exported from a package. - break - } - pkgName := xident.Name - r := refs[pkgName] - if r == nil { - r = make(map[string]bool) - refs[pkgName] = r - } - r[v.Sel.Name] = true - } - return visitor - } - ast.Walk(visitor, f) - return refs -} - -// collectImports returns all the imports in f. -// Unnamed imports (., _) and "C" are ignored. -func collectImports(f *ast.File) []*ImportInfo { - var imports []*ImportInfo - for _, imp := range f.Imports { - var name string - if imp.Name != nil { - name = imp.Name.Name - } - if imp.Path.Value == `"C"` || name == "_" || name == "." { - continue - } - path := strings.Trim(imp.Path.Value, `"`) - imports = append(imports, &ImportInfo{ - Name: name, - ImportPath: path, - }) - } - return imports -} - -// findMissingImport searches pass's candidates for an import that provides -// pkg, containing all of syms. -func (p *pass) findMissingImport(pkg string, syms map[string]bool) *ImportInfo { - for _, candidate := range p.candidates { - pkgInfo, ok := p.knownPackages[candidate.ImportPath] - if !ok { - continue - } - if p.importIdentifier(candidate) != pkg { - continue - } - - allFound := true - for right := range syms { - if !pkgInfo.exports[right] { - allFound = false - break - } - } - - if allFound { - return candidate - } - } - return nil -} - -// references is set of references found in a Go file. The first map key is the -// left hand side of a selector expression, the second key is the right hand -// side, and the value should always be true. -type references map[string]map[string]bool - -// A pass contains all the inputs and state necessary to fix a file's imports. -// It can be modified in some ways during use; see comments below. -type pass struct { - // Inputs. These must be set before a call to load, and not modified after. - fset *token.FileSet // fset used to parse f and its siblings. - f *ast.File // the file being fixed. - srcDir string // the directory containing f. - env *ProcessEnv // the environment to use for go commands, etc. - loadRealPackageNames bool // if true, load package names from disk rather than guessing them. - otherFiles []*ast.File // sibling files. - - // Intermediate state, generated by load. - existingImports map[string][]*ImportInfo - allRefs references - missingRefs references - - // Inputs to fix. These can be augmented between successive fix calls. - lastTry bool // indicates that this is the last call and fix should clean up as best it can. - candidates []*ImportInfo // candidate imports in priority order. - knownPackages map[string]*packageInfo // information about all known packages. -} - -// loadPackageNames saves the package names for everything referenced by imports. -func (p *pass) loadPackageNames(imports []*ImportInfo) error { - if p.env.Logf != nil { - p.env.Logf("loading package names for %v packages", len(imports)) - defer func() { - p.env.Logf("done loading package names for %v packages", len(imports)) - }() - } - var unknown []string - for _, imp := range imports { - if _, ok := p.knownPackages[imp.ImportPath]; ok { - continue - } - unknown = append(unknown, imp.ImportPath) - } - - resolver, err := p.env.GetResolver() - if err != nil { - return err - } - - names, err := resolver.loadPackageNames(unknown, p.srcDir) - if err != nil { - return err - } - - for path, name := range names { - p.knownPackages[path] = &packageInfo{ - name: name, - exports: map[string]bool{}, - } - } - return nil -} - -// importIdentifier returns the identifier that imp will introduce. It will -// guess if the package name has not been loaded, e.g. because the source -// is not available. -func (p *pass) importIdentifier(imp *ImportInfo) string { - if imp.Name != "" { - return imp.Name - } - known := p.knownPackages[imp.ImportPath] - if known != nil && known.name != "" { - return known.name - } - return ImportPathToAssumedName(imp.ImportPath) -} - -// load reads in everything necessary to run a pass, and reports whether the -// file already has all the imports it needs. It fills in p.missingRefs with the -// file's missing symbols, if any, or removes unused imports if not. -func (p *pass) load() ([]*ImportFix, bool) { - p.knownPackages = map[string]*packageInfo{} - p.missingRefs = references{} - p.existingImports = map[string][]*ImportInfo{} - - // Load basic information about the file in question. - p.allRefs = collectReferences(p.f) - - // Load stuff from other files in the same package: - // global variables so we know they don't need resolving, and imports - // that we might want to mimic. - globals := map[string]bool{} - for _, otherFile := range p.otherFiles { - // Don't load globals from files that are in the same directory - // but a different package. Using them to suggest imports is OK. - if p.f.Name.Name == otherFile.Name.Name { - addGlobals(otherFile, globals) - } - p.candidates = append(p.candidates, collectImports(otherFile)...) - } - - // Resolve all the import paths we've seen to package names, and store - // f's imports by the identifier they introduce. - imports := collectImports(p.f) - if p.loadRealPackageNames { - err := p.loadPackageNames(append(imports, p.candidates...)) - if err != nil { - if p.env.Logf != nil { - p.env.Logf("loading package names: %v", err) - } - return nil, false - } - } - for _, imp := range imports { - p.existingImports[p.importIdentifier(imp)] = append(p.existingImports[p.importIdentifier(imp)], imp) - } - - // Find missing references. - for left, rights := range p.allRefs { - if globals[left] { - continue - } - _, ok := p.existingImports[left] - if !ok { - p.missingRefs[left] = rights - continue - } - } - if len(p.missingRefs) != 0 { - return nil, false - } - - return p.fix() -} - -// fix attempts to satisfy missing imports using p.candidates. If it finds -// everything, or if p.lastTry is true, it updates fixes to add the imports it found, -// delete anything unused, and update import names, and returns true. -func (p *pass) fix() ([]*ImportFix, bool) { - // Find missing imports. - var selected []*ImportInfo - for left, rights := range p.missingRefs { - if imp := p.findMissingImport(left, rights); imp != nil { - selected = append(selected, imp) - } - } - - if !p.lastTry && len(selected) != len(p.missingRefs) { - return nil, false - } - - // Found everything, or giving up. Add the new imports and remove any unused. - var fixes []*ImportFix - for _, identifierImports := range p.existingImports { - for _, imp := range identifierImports { - // We deliberately ignore globals here, because we can't be sure - // they're in the same package. People do things like put multiple - // main packages in the same directory, and we don't want to - // remove imports if they happen to have the same name as a var in - // a different package. - if _, ok := p.allRefs[p.importIdentifier(imp)]; !ok { - fixes = append(fixes, &ImportFix{ - StmtInfo: *imp, - IdentName: p.importIdentifier(imp), - FixType: DeleteImport, - }) - continue - } - - // An existing import may need to update its import name to be correct. - if name := p.importSpecName(imp); name != imp.Name { - fixes = append(fixes, &ImportFix{ - StmtInfo: ImportInfo{ - Name: name, - ImportPath: imp.ImportPath, - }, - IdentName: p.importIdentifier(imp), - FixType: SetImportName, - }) - } - } - } - // Collecting fixes involved map iteration, so sort for stability. See - // golang/go#59976. - sortFixes(fixes) - - // collect selected fixes in a separate slice, so that it can be sorted - // separately. Note that these fixes must occur after fixes to existing - // imports. TODO(rfindley): figure out why. - var selectedFixes []*ImportFix - for _, imp := range selected { - selectedFixes = append(selectedFixes, &ImportFix{ - StmtInfo: ImportInfo{ - Name: p.importSpecName(imp), - ImportPath: imp.ImportPath, - }, - IdentName: p.importIdentifier(imp), - FixType: AddImport, - }) - } - sortFixes(selectedFixes) - - return append(fixes, selectedFixes...), true -} - -func sortFixes(fixes []*ImportFix) { - sort.Slice(fixes, func(i, j int) bool { - fi, fj := fixes[i], fixes[j] - if fi.StmtInfo.ImportPath != fj.StmtInfo.ImportPath { - return fi.StmtInfo.ImportPath < fj.StmtInfo.ImportPath - } - if fi.StmtInfo.Name != fj.StmtInfo.Name { - return fi.StmtInfo.Name < fj.StmtInfo.Name - } - if fi.IdentName != fj.IdentName { - return fi.IdentName < fj.IdentName - } - return fi.FixType < fj.FixType - }) -} - -// importSpecName gets the import name of imp in the import spec. -// -// When the import identifier matches the assumed import name, the import name does -// not appear in the import spec. -func (p *pass) importSpecName(imp *ImportInfo) string { - // If we did not load the real package names, or the name is already set, - // we just return the existing name. - if !p.loadRealPackageNames || imp.Name != "" { - return imp.Name - } - - ident := p.importIdentifier(imp) - if ident == ImportPathToAssumedName(imp.ImportPath) { - return "" // ident not needed since the assumed and real names are the same. - } - return ident -} - -// apply will perform the fixes on f in order. -func apply(fset *token.FileSet, f *ast.File, fixes []*ImportFix) { - for _, fix := range fixes { - switch fix.FixType { - case DeleteImport: - astutil.DeleteNamedImport(fset, f, fix.StmtInfo.Name, fix.StmtInfo.ImportPath) - case AddImport: - astutil.AddNamedImport(fset, f, fix.StmtInfo.Name, fix.StmtInfo.ImportPath) - case SetImportName: - // Find the matching import path and change the name. - for _, spec := range f.Imports { - path := strings.Trim(spec.Path.Value, `"`) - if path == fix.StmtInfo.ImportPath { - spec.Name = &ast.Ident{ - Name: fix.StmtInfo.Name, - NamePos: spec.Pos(), - } - } - } - } - } -} - -// assumeSiblingImportsValid assumes that siblings' use of packages is valid, -// adding the exports they use. -func (p *pass) assumeSiblingImportsValid() { - for _, f := range p.otherFiles { - refs := collectReferences(f) - imports := collectImports(f) - importsByName := map[string]*ImportInfo{} - for _, imp := range imports { - importsByName[p.importIdentifier(imp)] = imp - } - for left, rights := range refs { - if imp, ok := importsByName[left]; ok { - if m, ok := stdlib[imp.ImportPath]; ok { - // We have the stdlib in memory; no need to guess. - rights = copyExports(m) - } - p.addCandidate(imp, &packageInfo{ - // no name; we already know it. - exports: rights, - }) - } - } - } -} - -// addCandidate adds a candidate import to p, and merges in the information -// in pkg. -func (p *pass) addCandidate(imp *ImportInfo, pkg *packageInfo) { - p.candidates = append(p.candidates, imp) - if existing, ok := p.knownPackages[imp.ImportPath]; ok { - if existing.name == "" { - existing.name = pkg.name - } - for export := range pkg.exports { - existing.exports[export] = true - } - } else { - p.knownPackages[imp.ImportPath] = pkg - } -} - -// fixImports adds and removes imports from f so that all its references are -// satisfied and there are no unused imports. -// -// This is declared as a variable rather than a function so goimports can -// easily be extended by adding a file with an init function. -var fixImports = fixImportsDefault - -func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) error { - fixes, err := getFixes(context.Background(), fset, f, filename, env) - if err != nil { - return err - } - apply(fset, f, fixes) - return err -} - -// getFixes gets the import fixes that need to be made to f in order to fix the imports. -// It does not modify the ast. -func getFixes(ctx context.Context, fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) ([]*ImportFix, error) { - abs, err := filepath.Abs(filename) - if err != nil { - return nil, err - } - srcDir := filepath.Dir(abs) - if env.Logf != nil { - env.Logf("fixImports(filename=%q), abs=%q, srcDir=%q ...", filename, abs, srcDir) - } - - // First pass: looking only at f, and using the naive algorithm to - // derive package names from import paths, see if the file is already - // complete. We can't add any imports yet, because we don't know - // if missing references are actually package vars. - p := &pass{fset: fset, f: f, srcDir: srcDir, env: env} - if fixes, done := p.load(); done { - return fixes, nil - } - - otherFiles := parseOtherFiles(fset, srcDir, filename) - - // Second pass: add information from other files in the same package, - // like their package vars and imports. - p.otherFiles = otherFiles - if fixes, done := p.load(); done { - return fixes, nil - } - - // Now we can try adding imports from the stdlib. - p.assumeSiblingImportsValid() - addStdlibCandidates(p, p.missingRefs) - if fixes, done := p.fix(); done { - return fixes, nil - } - - // Third pass: get real package names where we had previously used - // the naive algorithm. - p = &pass{fset: fset, f: f, srcDir: srcDir, env: env} - p.loadRealPackageNames = true - p.otherFiles = otherFiles - if fixes, done := p.load(); done { - return fixes, nil - } - - if err := addStdlibCandidates(p, p.missingRefs); err != nil { - return nil, err - } - p.assumeSiblingImportsValid() - if fixes, done := p.fix(); done { - return fixes, nil - } - - // Go look for candidates in $GOPATH, etc. We don't necessarily load - // the real exports of sibling imports, so keep assuming their contents. - if err := addExternalCandidates(ctx, p, p.missingRefs, filename); err != nil { - return nil, err - } - - p.lastTry = true - fixes, _ := p.fix() - return fixes, nil -} - -// MaxRelevance is the highest relevance, used for the standard library. -// Chosen arbitrarily to match pre-existing gopls code. -const MaxRelevance = 7.0 - -// getCandidatePkgs works with the passed callback to find all acceptable packages. -// It deduplicates by import path, and uses a cached stdlib rather than reading -// from disk. -func getCandidatePkgs(ctx context.Context, wrappedCallback *scanCallback, filename, filePkg string, env *ProcessEnv) error { - notSelf := func(p *pkg) bool { - return p.packageName != filePkg || p.dir != filepath.Dir(filename) - } - goenv, err := env.goEnv() - if err != nil { - return err - } - - var mu sync.Mutex // to guard asynchronous access to dupCheck - dupCheck := map[string]struct{}{} - - // Start off with the standard library. - for importPath, exports := range stdlib { - p := &pkg{ - dir: filepath.Join(goenv["GOROOT"], "src", importPath), - importPathShort: importPath, - packageName: path.Base(importPath), - relevance: MaxRelevance, - } - dupCheck[importPath] = struct{}{} - if notSelf(p) && wrappedCallback.dirFound(p) && wrappedCallback.packageNameLoaded(p) { - wrappedCallback.exportsLoaded(p, exports) - } - } - - scanFilter := &scanCallback{ - rootFound: func(root gopathwalk.Root) bool { - // Exclude goroot results -- getting them is relatively expensive, not cached, - // and generally redundant with the in-memory version. - return root.Type != gopathwalk.RootGOROOT && wrappedCallback.rootFound(root) - }, - dirFound: wrappedCallback.dirFound, - packageNameLoaded: func(pkg *pkg) bool { - mu.Lock() - defer mu.Unlock() - if _, ok := dupCheck[pkg.importPathShort]; ok { - return false - } - dupCheck[pkg.importPathShort] = struct{}{} - return notSelf(pkg) && wrappedCallback.packageNameLoaded(pkg) - }, - exportsLoaded: func(pkg *pkg, exports []string) { - // If we're an x_test, load the package under test's test variant. - if strings.HasSuffix(filePkg, "_test") && pkg.dir == filepath.Dir(filename) { - var err error - _, exports, err = loadExportsFromFiles(ctx, env, pkg.dir, true) - if err != nil { - return - } - } - wrappedCallback.exportsLoaded(pkg, exports) - }, - } - resolver, err := env.GetResolver() - if err != nil { - return err - } - return resolver.scan(ctx, scanFilter) -} - -func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map[string]float64, error) { - result := make(map[string]float64) - resolver, err := env.GetResolver() - if err != nil { - return nil, err - } - for _, path := range paths { - result[path] = resolver.scoreImportPath(ctx, path) - } - return result, nil -} - -func PrimeCache(ctx context.Context, env *ProcessEnv) error { - // Fully scan the disk for directories, but don't actually read any Go files. - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true - }, - dirFound: func(pkg *pkg) bool { - return false - }, - packageNameLoaded: func(pkg *pkg) bool { - return false - }, - } - return getCandidatePkgs(ctx, callback, "", "", env) -} - -func candidateImportName(pkg *pkg) string { - if ImportPathToAssumedName(pkg.importPathShort) != pkg.packageName { - return pkg.packageName - } - return "" -} - -// GetAllCandidates calls wrapped for each package whose name starts with -// searchPrefix, and can be imported from filename with the package name filePkg. -// -// Beware that the wrapped function may be called multiple times concurrently. -// TODO(adonovan): encapsulate the concurrency. -func GetAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error { - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true - }, - dirFound: func(pkg *pkg) bool { - if !canUse(filename, pkg.dir) { - return false - } - // Try the assumed package name first, then a simpler path match - // in case of packages named vN, which are not uncommon. - return strings.HasPrefix(ImportPathToAssumedName(pkg.importPathShort), searchPrefix) || - strings.HasPrefix(path.Base(pkg.importPathShort), searchPrefix) - }, - packageNameLoaded: func(pkg *pkg) bool { - if !strings.HasPrefix(pkg.packageName, searchPrefix) { - return false - } - wrapped(ImportFix{ - StmtInfo: ImportInfo{ - ImportPath: pkg.importPathShort, - Name: candidateImportName(pkg), - }, - IdentName: pkg.packageName, - FixType: AddImport, - Relevance: pkg.relevance, - }) - return false - }, - } - return getCandidatePkgs(ctx, callback, filename, filePkg, env) -} - -// GetImportPaths calls wrapped for each package whose import path starts with -// searchPrefix, and can be imported from filename with the package name filePkg. -func GetImportPaths(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error { - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true - }, - dirFound: func(pkg *pkg) bool { - if !canUse(filename, pkg.dir) { - return false - } - return strings.HasPrefix(pkg.importPathShort, searchPrefix) - }, - packageNameLoaded: func(pkg *pkg) bool { - wrapped(ImportFix{ - StmtInfo: ImportInfo{ - ImportPath: pkg.importPathShort, - Name: candidateImportName(pkg), - }, - IdentName: pkg.packageName, - FixType: AddImport, - Relevance: pkg.relevance, - }) - return false - }, - } - return getCandidatePkgs(ctx, callback, filename, filePkg, env) -} - -// A PackageExport is a package and its exports. -type PackageExport struct { - Fix *ImportFix - Exports []string -} - -// GetPackageExports returns all known packages with name pkg and their exports. -func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchPkg, filename, filePkg string, env *ProcessEnv) error { - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true - }, - dirFound: func(pkg *pkg) bool { - return pkgIsCandidate(filename, references{searchPkg: nil}, pkg) - }, - packageNameLoaded: func(pkg *pkg) bool { - return pkg.packageName == searchPkg - }, - exportsLoaded: func(pkg *pkg, exports []string) { - sort.Strings(exports) - wrapped(PackageExport{ - Fix: &ImportFix{ - StmtInfo: ImportInfo{ - ImportPath: pkg.importPathShort, - Name: candidateImportName(pkg), - }, - IdentName: pkg.packageName, - FixType: AddImport, - Relevance: pkg.relevance, - }, - Exports: exports, - }) - }, - } - return getCandidatePkgs(ctx, callback, filename, filePkg, env) -} - -var requiredGoEnvVars = []string{"GO111MODULE", "GOFLAGS", "GOINSECURE", "GOMOD", "GOMODCACHE", "GONOPROXY", "GONOSUMDB", "GOPATH", "GOPROXY", "GOROOT", "GOSUMDB", "GOWORK"} - -// ProcessEnv contains environment variables and settings that affect the use of -// the go command, the go/build package, etc. -type ProcessEnv struct { - GocmdRunner *gocommand.Runner - - BuildFlags []string - ModFlag string - ModFile string - - // SkipPathInScan returns true if the path should be skipped from scans of - // the RootCurrentModule root type. The function argument is a clean, - // absolute path. - SkipPathInScan func(string) bool - - // Env overrides the OS environment, and can be used to specify - // GOPROXY, GO111MODULE, etc. PATH cannot be set here, because - // exec.Command will not honor it. - // Specifying all of RequiredGoEnvVars avoids a call to `go env`. - Env map[string]string - - WorkingDir string - - // If Logf is non-nil, debug logging is enabled through this function. - Logf func(format string, args ...interface{}) - - initialized bool - - resolver Resolver -} - -func (e *ProcessEnv) goEnv() (map[string]string, error) { - if err := e.init(); err != nil { - return nil, err - } - return e.Env, nil -} - -func (e *ProcessEnv) matchFile(dir, name string) (bool, error) { - bctx, err := e.buildContext() - if err != nil { - return false, err - } - return bctx.MatchFile(dir, name) -} - -// CopyConfig copies the env's configuration into a new env. -func (e *ProcessEnv) CopyConfig() *ProcessEnv { - copy := &ProcessEnv{ - GocmdRunner: e.GocmdRunner, - initialized: e.initialized, - BuildFlags: e.BuildFlags, - Logf: e.Logf, - WorkingDir: e.WorkingDir, - resolver: nil, - Env: map[string]string{}, - } - for k, v := range e.Env { - copy.Env[k] = v - } - return copy -} - -func (e *ProcessEnv) init() error { - if e.initialized { - return nil - } - - foundAllRequired := true - for _, k := range requiredGoEnvVars { - if _, ok := e.Env[k]; !ok { - foundAllRequired = false - break - } - } - if foundAllRequired { - e.initialized = true - return nil - } - - if e.Env == nil { - e.Env = map[string]string{} - } - - goEnv := map[string]string{} - stdout, err := e.invokeGo(context.TODO(), "env", append([]string{"-json"}, requiredGoEnvVars...)...) - if err != nil { - return err - } - if err := json.Unmarshal(stdout.Bytes(), &goEnv); err != nil { - return err - } - for k, v := range goEnv { - e.Env[k] = v - } - e.initialized = true - return nil -} - -func (e *ProcessEnv) env() []string { - var env []string // the gocommand package will prepend os.Environ. - for k, v := range e.Env { - env = append(env, k+"="+v) - } - return env -} - -func (e *ProcessEnv) GetResolver() (Resolver, error) { - if e.resolver != nil { - return e.resolver, nil - } - if err := e.init(); err != nil { - return nil, err - } - if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 { - e.resolver = newGopathResolver(e) - return e.resolver, nil - } - e.resolver = newModuleResolver(e) - return e.resolver, nil -} - -func (e *ProcessEnv) buildContext() (*build.Context, error) { - ctx := build.Default - goenv, err := e.goEnv() - if err != nil { - return nil, err - } - ctx.GOROOT = goenv["GOROOT"] - ctx.GOPATH = goenv["GOPATH"] - - // As of Go 1.14, build.Context has a Dir field - // (see golang.org/issue/34860). - // Populate it only if present. - rc := reflect.ValueOf(&ctx).Elem() - dir := rc.FieldByName("Dir") - if dir.IsValid() && dir.Kind() == reflect.String { - dir.SetString(e.WorkingDir) - } - - // Since Go 1.11, go/build.Context.Import may invoke 'go list' depending on - // the value in GO111MODULE in the process's environment. We always want to - // run in GOPATH mode when calling Import, so we need to prevent this from - // happening. In Go 1.16, GO111MODULE defaults to "on", so this problem comes - // up more frequently. - // - // HACK: setting any of the Context I/O hooks prevents Import from invoking - // 'go list', regardless of GO111MODULE. This is undocumented, but it's - // unlikely to change before GOPATH support is removed. - ctx.ReadDir = ioutil.ReadDir - - return &ctx, nil -} - -func (e *ProcessEnv) invokeGo(ctx context.Context, verb string, args ...string) (*bytes.Buffer, error) { - inv := gocommand.Invocation{ - Verb: verb, - Args: args, - BuildFlags: e.BuildFlags, - Env: e.env(), - Logf: e.Logf, - WorkingDir: e.WorkingDir, - } - return e.GocmdRunner.Run(ctx, inv) -} - -func addStdlibCandidates(pass *pass, refs references) error { - goenv, err := pass.env.goEnv() - if err != nil { - return err - } - add := func(pkg string) { - // Prevent self-imports. - if path.Base(pkg) == pass.f.Name.Name && filepath.Join(goenv["GOROOT"], "src", pkg) == pass.srcDir { - return - } - exports := copyExports(stdlib[pkg]) - pass.addCandidate( - &ImportInfo{ImportPath: pkg}, - &packageInfo{name: path.Base(pkg), exports: exports}) - } - for left := range refs { - if left == "rand" { - // Make sure we try crypto/rand before math/rand. - add("crypto/rand") - add("math/rand") - continue - } - for importPath := range stdlib { - if path.Base(importPath) == left { - add(importPath) - } - } - } - return nil -} - -// A Resolver does the build-system-specific parts of goimports. -type Resolver interface { - // loadPackageNames loads the package names in importPaths. - loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) - // scan works with callback to search for packages. See scanCallback for details. - scan(ctx context.Context, callback *scanCallback) error - // loadExports returns the set of exported symbols in the package at dir. - // loadExports may be called concurrently. - loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error) - // scoreImportPath returns the relevance for an import path. - scoreImportPath(ctx context.Context, path string) float64 - - ClearForNewScan() -} - -// A scanCallback controls a call to scan and receives its results. -// In general, minor errors will be silently discarded; a user should not -// expect to receive a full series of calls for everything. -type scanCallback struct { - // rootFound is called before scanning a new root dir. If it returns true, - // the root will be scanned. Returning false will not necessarily prevent - // directories from that root making it to dirFound. - rootFound func(gopathwalk.Root) bool - // dirFound is called when a directory is found that is possibly a Go package. - // pkg will be populated with everything except packageName. - // If it returns true, the package's name will be loaded. - dirFound func(pkg *pkg) bool - // packageNameLoaded is called when a package is found and its name is loaded. - // If it returns true, the package's exports will be loaded. - packageNameLoaded func(pkg *pkg) bool - // exportsLoaded is called when a package's exports have been loaded. - exportsLoaded func(pkg *pkg, exports []string) -} - -func addExternalCandidates(ctx context.Context, pass *pass, refs references, filename string) error { - ctx, done := event.Start(ctx, "imports.addExternalCandidates") - defer done() - - var mu sync.Mutex - found := make(map[string][]pkgDistance) - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true // We want everything. - }, - dirFound: func(pkg *pkg) bool { - return pkgIsCandidate(filename, refs, pkg) - }, - packageNameLoaded: func(pkg *pkg) bool { - if _, want := refs[pkg.packageName]; !want { - return false - } - if pkg.dir == pass.srcDir && pass.f.Name.Name == pkg.packageName { - // The candidate is in the same directory and has the - // same package name. Don't try to import ourselves. - return false - } - if !canUse(filename, pkg.dir) { - return false - } - mu.Lock() - defer mu.Unlock() - found[pkg.packageName] = append(found[pkg.packageName], pkgDistance{pkg, distance(pass.srcDir, pkg.dir)}) - return false // We'll do our own loading after we sort. - }, - } - resolver, err := pass.env.GetResolver() - if err != nil { - return err - } - if err = resolver.scan(context.Background(), callback); err != nil { - return err - } - - // Search for imports matching potential package references. - type result struct { - imp *ImportInfo - pkg *packageInfo - } - results := make(chan result, len(refs)) - - ctx, cancel := context.WithCancel(context.TODO()) - var wg sync.WaitGroup - defer func() { - cancel() - wg.Wait() - }() - var ( - firstErr error - firstErrOnce sync.Once - ) - for pkgName, symbols := range refs { - wg.Add(1) - go func(pkgName string, symbols map[string]bool) { - defer wg.Done() - - found, err := findImport(ctx, pass, found[pkgName], pkgName, symbols, filename) - - if err != nil { - firstErrOnce.Do(func() { - firstErr = err - cancel() - }) - return - } - - if found == nil { - return // No matching package. - } - - imp := &ImportInfo{ - ImportPath: found.importPathShort, - } - - pkg := &packageInfo{ - name: pkgName, - exports: symbols, - } - results <- result{imp, pkg} - }(pkgName, symbols) - } - go func() { - wg.Wait() - close(results) - }() - - for result := range results { - pass.addCandidate(result.imp, result.pkg) - } - return firstErr -} - -// notIdentifier reports whether ch is an invalid identifier character. -func notIdentifier(ch rune) bool { - return !('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || - '0' <= ch && ch <= '9' || - ch == '_' || - ch >= utf8.RuneSelf && (unicode.IsLetter(ch) || unicode.IsDigit(ch))) -} - -// ImportPathToAssumedName returns the assumed package name of an import path. -// It does this using only string parsing of the import path. -// It picks the last element of the path that does not look like a major -// version, and then picks the valid identifier off the start of that element. -// It is used to determine if a local rename should be added to an import for -// clarity. -// This function could be moved to a standard package and exported if we want -// for use in other tools. -func ImportPathToAssumedName(importPath string) string { - base := path.Base(importPath) - if strings.HasPrefix(base, "v") { - if _, err := strconv.Atoi(base[1:]); err == nil { - dir := path.Dir(importPath) - if dir != "." { - base = path.Base(dir) - } - } - } - base = strings.TrimPrefix(base, "go-") - if i := strings.IndexFunc(base, notIdentifier); i >= 0 { - base = base[:i] - } - return base -} - -// gopathResolver implements resolver for GOPATH workspaces. -type gopathResolver struct { - env *ProcessEnv - walked bool - cache *dirInfoCache - scanSema chan struct{} // scanSema prevents concurrent scans. -} - -func newGopathResolver(env *ProcessEnv) *gopathResolver { - r := &gopathResolver{ - env: env, - cache: &dirInfoCache{ - dirs: map[string]*directoryPackageInfo{}, - listeners: map[*int]cacheListener{}, - }, - scanSema: make(chan struct{}, 1), - } - r.scanSema <- struct{}{} - return r -} - -func (r *gopathResolver) ClearForNewScan() { - <-r.scanSema - r.cache = &dirInfoCache{ - dirs: map[string]*directoryPackageInfo{}, - listeners: map[*int]cacheListener{}, - } - r.walked = false - r.scanSema <- struct{}{} -} - -func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) { - names := map[string]string{} - bctx, err := r.env.buildContext() - if err != nil { - return nil, err - } - for _, path := range importPaths { - names[path] = importPathToName(bctx, path, srcDir) - } - return names, nil -} - -// importPathToName finds out the actual package name, as declared in its .go files. -func importPathToName(bctx *build.Context, importPath, srcDir string) string { - // Fast path for standard library without going to disk. - if _, ok := stdlib[importPath]; ok { - return path.Base(importPath) // stdlib packages always match their paths. - } - - buildPkg, err := bctx.Import(importPath, srcDir, build.FindOnly) - if err != nil { - return "" - } - pkgName, err := packageDirToName(buildPkg.Dir) - if err != nil { - return "" - } - return pkgName -} - -// packageDirToName is a faster version of build.Import if -// the only thing desired is the package name. Given a directory, -// packageDirToName then only parses one file in the package, -// trusting that the files in the directory are consistent. -func packageDirToName(dir string) (packageName string, err error) { - d, err := os.Open(dir) - if err != nil { - return "", err - } - names, err := d.Readdirnames(-1) - d.Close() - if err != nil { - return "", err - } - sort.Strings(names) // to have predictable behavior - var lastErr error - var nfile int - for _, name := range names { - if !strings.HasSuffix(name, ".go") { - continue - } - if strings.HasSuffix(name, "_test.go") { - continue - } - nfile++ - fullFile := filepath.Join(dir, name) - - fset := token.NewFileSet() - f, err := parser.ParseFile(fset, fullFile, nil, parser.PackageClauseOnly) - if err != nil { - lastErr = err - continue - } - pkgName := f.Name.Name - if pkgName == "documentation" { - // Special case from go/build.ImportDir, not - // handled by ctx.MatchFile. - continue - } - if pkgName == "main" { - // Also skip package main, assuming it's a +build ignore generator or example. - // Since you can't import a package main anyway, there's no harm here. - continue - } - return pkgName, nil - } - if lastErr != nil { - return "", lastErr - } - return "", fmt.Errorf("no importable package found in %d Go files", nfile) -} - -type pkg struct { - dir string // absolute file path to pkg directory ("/usr/lib/go/src/net/http") - importPathShort string // vendorless import path ("net/http", "a/b") - packageName string // package name loaded from source if requested - relevance float64 // a weakly-defined score of how relevant a package is. 0 is most relevant. -} - -type pkgDistance struct { - pkg *pkg - distance int // relative distance to target -} - -// byDistanceOrImportPathShortLength sorts by relative distance breaking ties -// on the short import path length and then the import string itself. -type byDistanceOrImportPathShortLength []pkgDistance - -func (s byDistanceOrImportPathShortLength) Len() int { return len(s) } -func (s byDistanceOrImportPathShortLength) Less(i, j int) bool { - di, dj := s[i].distance, s[j].distance - if di == -1 { - return false - } - if dj == -1 { - return true - } - if di != dj { - return di < dj - } - - vi, vj := s[i].pkg.importPathShort, s[j].pkg.importPathShort - if len(vi) != len(vj) { - return len(vi) < len(vj) - } - return vi < vj -} -func (s byDistanceOrImportPathShortLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -func distance(basepath, targetpath string) int { - p, err := filepath.Rel(basepath, targetpath) - if err != nil { - return -1 - } - if p == "." { - return 0 - } - return strings.Count(p, string(filepath.Separator)) + 1 -} - -func (r *gopathResolver) scan(ctx context.Context, callback *scanCallback) error { - add := func(root gopathwalk.Root, dir string) { - // We assume cached directories have not changed. We can skip them and their - // children. - if _, ok := r.cache.Load(dir); ok { - return - } - - importpath := filepath.ToSlash(dir[len(root.Path)+len("/"):]) - info := directoryPackageInfo{ - status: directoryScanned, - dir: dir, - rootType: root.Type, - nonCanonicalImportPath: VendorlessPath(importpath), - } - r.cache.Store(dir, info) - } - processDir := func(info directoryPackageInfo) { - // Skip this directory if we were not able to get the package information successfully. - if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { - return - } - - p := &pkg{ - importPathShort: info.nonCanonicalImportPath, - dir: info.dir, - relevance: MaxRelevance - 1, - } - if info.rootType == gopathwalk.RootGOROOT { - p.relevance = MaxRelevance - } - - if !callback.dirFound(p) { - return - } - var err error - p.packageName, err = r.cache.CachePackageName(info) - if err != nil { - return - } - - if !callback.packageNameLoaded(p) { - return - } - if _, exports, err := r.loadExports(ctx, p, false); err == nil { - callback.exportsLoaded(p, exports) - } - } - stop := r.cache.ScanAndListen(ctx, processDir) - defer stop() - - goenv, err := r.env.goEnv() - if err != nil { - return err - } - var roots []gopathwalk.Root - roots = append(roots, gopathwalk.Root{Path: filepath.Join(goenv["GOROOT"], "src"), Type: gopathwalk.RootGOROOT}) - for _, p := range filepath.SplitList(goenv["GOPATH"]) { - roots = append(roots, gopathwalk.Root{Path: filepath.Join(p, "src"), Type: gopathwalk.RootGOPATH}) - } - // The callback is not necessarily safe to use in the goroutine below. Process roots eagerly. - roots = filterRoots(roots, callback.rootFound) - // We can't cancel walks, because we need them to finish to have a usable - // cache. Instead, run them in a separate goroutine and detach. - scanDone := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - return - case <-r.scanSema: - } - defer func() { r.scanSema <- struct{}{} }() - gopathwalk.Walk(roots, add, gopathwalk.Options{Logf: r.env.Logf, ModulesEnabled: false}) - close(scanDone) - }() - select { - case <-ctx.Done(): - case <-scanDone: - } - return nil -} - -func (r *gopathResolver) scoreImportPath(ctx context.Context, path string) float64 { - if _, ok := stdlib[path]; ok { - return MaxRelevance - } - return MaxRelevance - 1 -} - -func filterRoots(roots []gopathwalk.Root, include func(gopathwalk.Root) bool) []gopathwalk.Root { - var result []gopathwalk.Root - for _, root := range roots { - if !include(root) { - continue - } - result = append(result, root) - } - return result -} - -func (r *gopathResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error) { - if info, ok := r.cache.Load(pkg.dir); ok && !includeTest { - return r.cache.CacheExports(ctx, r.env, info) - } - return loadExportsFromFiles(ctx, r.env, pkg.dir, includeTest) -} - -// VendorlessPath returns the devendorized version of the import path ipath. -// For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b". -func VendorlessPath(ipath string) string { - // Devendorize for use in import statement. - if i := strings.LastIndex(ipath, "/vendor/"); i >= 0 { - return ipath[i+len("/vendor/"):] - } - if strings.HasPrefix(ipath, "vendor/") { - return ipath[len("vendor/"):] - } - return ipath -} - -func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, includeTest bool) (string, []string, error) { - // Look for non-test, buildable .go files which could provide exports. - all, err := os.ReadDir(dir) - if err != nil { - return "", nil, err - } - var files []fs.DirEntry - for _, fi := range all { - name := fi.Name() - if !strings.HasSuffix(name, ".go") || (!includeTest && strings.HasSuffix(name, "_test.go")) { - continue - } - match, err := env.matchFile(dir, fi.Name()) - if err != nil || !match { - continue - } - files = append(files, fi) - } - - if len(files) == 0 { - return "", nil, fmt.Errorf("dir %v contains no buildable, non-test .go files", dir) - } - - var pkgName string - var exports []string - fset := token.NewFileSet() - for _, fi := range files { - select { - case <-ctx.Done(): - return "", nil, ctx.Err() - default: - } - - fullFile := filepath.Join(dir, fi.Name()) - f, err := parser.ParseFile(fset, fullFile, nil, 0) - if err != nil { - if env.Logf != nil { - env.Logf("error parsing %v: %v", fullFile, err) - } - continue - } - if f.Name.Name == "documentation" { - // Special case from go/build.ImportDir, not - // handled by MatchFile above. - continue - } - if includeTest && strings.HasSuffix(f.Name.Name, "_test") { - // x_test package. We want internal test files only. - continue - } - pkgName = f.Name.Name - for name := range f.Scope.Objects { - if ast.IsExported(name) { - exports = append(exports, name) - } - } - } - - if env.Logf != nil { - sortedExports := append([]string(nil), exports...) - sort.Strings(sortedExports) - env.Logf("loaded exports in dir %v (package %v): %v", dir, pkgName, strings.Join(sortedExports, ", ")) - } - return pkgName, exports, nil -} - -// findImport searches for a package with the given symbols. -// If no package is found, findImport returns ("", false, nil) -func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgName string, symbols map[string]bool, filename string) (*pkg, error) { - // Sort the candidates by their import package length, - // assuming that shorter package names are better than long - // ones. Note that this sorts by the de-vendored name, so - // there's no "penalty" for vendoring. - sort.Sort(byDistanceOrImportPathShortLength(candidates)) - if pass.env.Logf != nil { - for i, c := range candidates { - pass.env.Logf("%s candidate %d/%d: %v in %v", pkgName, i+1, len(candidates), c.pkg.importPathShort, c.pkg.dir) - } - } - resolver, err := pass.env.GetResolver() - if err != nil { - return nil, err - } - - // Collect exports for packages with matching names. - rescv := make([]chan *pkg, len(candidates)) - for i := range candidates { - rescv[i] = make(chan *pkg, 1) - } - const maxConcurrentPackageImport = 4 - loadExportsSem := make(chan struct{}, maxConcurrentPackageImport) - - ctx, cancel := context.WithCancel(ctx) - var wg sync.WaitGroup - defer func() { - cancel() - wg.Wait() - }() - - wg.Add(1) - go func() { - defer wg.Done() - for i, c := range candidates { - select { - case loadExportsSem <- struct{}{}: - case <-ctx.Done(): - return - } - - wg.Add(1) - go func(c pkgDistance, resc chan<- *pkg) { - defer func() { - <-loadExportsSem - wg.Done() - }() - - if pass.env.Logf != nil { - pass.env.Logf("loading exports in dir %s (seeking package %s)", c.pkg.dir, pkgName) - } - // If we're an x_test, load the package under test's test variant. - includeTest := strings.HasSuffix(pass.f.Name.Name, "_test") && c.pkg.dir == pass.srcDir - _, exports, err := resolver.loadExports(ctx, c.pkg, includeTest) - if err != nil { - if pass.env.Logf != nil { - pass.env.Logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err) - } - resc <- nil - return - } - - exportsMap := make(map[string]bool, len(exports)) - for _, sym := range exports { - exportsMap[sym] = true - } - - // If it doesn't have the right - // symbols, send nil to mean no match. - for symbol := range symbols { - if !exportsMap[symbol] { - resc <- nil - return - } - } - resc <- c.pkg - }(c, rescv[i]) - } - }() - - for _, resc := range rescv { - pkg := <-resc - if pkg == nil { - continue - } - return pkg, nil - } - return nil, nil -} - -// pkgIsCandidate reports whether pkg is a candidate for satisfying the -// finding which package pkgIdent in the file named by filename is trying -// to refer to. -// -// This check is purely lexical and is meant to be as fast as possible -// because it's run over all $GOPATH directories to filter out poor -// candidates in order to limit the CPU and I/O later parsing the -// exports in candidate packages. -// -// filename is the file being formatted. -// pkgIdent is the package being searched for, like "client" (if -// searching for "client.New") -func pkgIsCandidate(filename string, refs references, pkg *pkg) bool { - // Check "internal" and "vendor" visibility: - if !canUse(filename, pkg.dir) { - return false - } - - // Speed optimization to minimize disk I/O: - // the last two components on disk must contain the - // package name somewhere. - // - // This permits mismatch naming like directory - // "go-foo" being package "foo", or "pkg.v3" being "pkg", - // or directory "google.golang.org/api/cloudbilling/v1" - // being package "cloudbilling", but doesn't - // permit a directory "foo" to be package - // "bar", which is strongly discouraged - // anyway. There's no reason goimports needs - // to be slow just to accommodate that. - for pkgIdent := range refs { - lastTwo := lastTwoComponents(pkg.importPathShort) - if strings.Contains(lastTwo, pkgIdent) { - return true - } - if hasHyphenOrUpperASCII(lastTwo) && !hasHyphenOrUpperASCII(pkgIdent) { - lastTwo = lowerASCIIAndRemoveHyphen(lastTwo) - if strings.Contains(lastTwo, pkgIdent) { - return true - } - } - } - return false -} - -func hasHyphenOrUpperASCII(s string) bool { - for i := 0; i < len(s); i++ { - b := s[i] - if b == '-' || ('A' <= b && b <= 'Z') { - return true - } - } - return false -} - -func lowerASCIIAndRemoveHyphen(s string) (ret string) { - buf := make([]byte, 0, len(s)) - for i := 0; i < len(s); i++ { - b := s[i] - switch { - case b == '-': - continue - case 'A' <= b && b <= 'Z': - buf = append(buf, b+('a'-'A')) - default: - buf = append(buf, b) - } - } - return string(buf) -} - -// canUse reports whether the package in dir is usable from filename, -// respecting the Go "internal" and "vendor" visibility rules. -func canUse(filename, dir string) bool { - // Fast path check, before any allocations. If it doesn't contain vendor - // or internal, it's not tricky: - // Note that this can false-negative on directories like "notinternal", - // but we check it correctly below. This is just a fast path. - if !strings.Contains(dir, "vendor") && !strings.Contains(dir, "internal") { - return true - } - - dirSlash := filepath.ToSlash(dir) - if !strings.Contains(dirSlash, "/vendor/") && !strings.Contains(dirSlash, "/internal/") && !strings.HasSuffix(dirSlash, "/internal") { - return true - } - // Vendor or internal directory only visible from children of parent. - // That means the path from the current directory to the target directory - // can contain ../vendor or ../internal but not ../foo/vendor or ../foo/internal - // or bar/vendor or bar/internal. - // After stripping all the leading ../, the only okay place to see vendor or internal - // is at the very beginning of the path. - absfile, err := filepath.Abs(filename) - if err != nil { - return false - } - absdir, err := filepath.Abs(dir) - if err != nil { - return false - } - rel, err := filepath.Rel(absfile, absdir) - if err != nil { - return false - } - relSlash := filepath.ToSlash(rel) - if i := strings.LastIndex(relSlash, "../"); i >= 0 { - relSlash = relSlash[i+len("../"):] - } - return !strings.Contains(relSlash, "/vendor/") && !strings.Contains(relSlash, "/internal/") && !strings.HasSuffix(relSlash, "/internal") -} - -// lastTwoComponents returns at most the last two path components -// of v, using either / or \ as the path separator. -func lastTwoComponents(v string) string { - nslash := 0 - for i := len(v) - 1; i >= 0; i-- { - if v[i] == '/' || v[i] == '\\' { - nslash++ - if nslash == 2 { - return v[i:] - } - } - } - return v -} - -type visitFn func(node ast.Node) ast.Visitor - -func (fn visitFn) Visit(node ast.Node) ast.Visitor { - return fn(node) -} - -func copyExports(pkg []string) map[string]bool { - m := make(map[string]bool, len(pkg)) - for _, v := range pkg { - m[v] = true - } - return m -} diff --git a/vendor/golang.org/x/tools/internal/imports/imports.go b/vendor/golang.org/x/tools/internal/imports/imports.go deleted file mode 100644 index 58e637b9..00000000 --- a/vendor/golang.org/x/tools/internal/imports/imports.go +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run mkstdlib.go - -// Package imports implements a Go pretty-printer (like package "go/format") -// that also adds or removes import statements as necessary. -package imports - -import ( - "bufio" - "bytes" - "context" - "fmt" - "go/ast" - "go/format" - "go/parser" - "go/printer" - "go/token" - "io" - "regexp" - "strconv" - "strings" - - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/internal/event" -) - -// Options is golang.org/x/tools/imports.Options with extra internal-only options. -type Options struct { - Env *ProcessEnv // The environment to use. Note: this contains the cached module and filesystem state. - - // LocalPrefix is a comma-separated string of import path prefixes, which, if - // set, instructs Process to sort the import paths with the given prefixes - // into another group after 3rd-party packages. - LocalPrefix string - - Fragment bool // Accept fragment of a source file (no package statement) - AllErrors bool // Report all errors (not just the first 10 on different lines) - - Comments bool // Print comments (true if nil *Options provided) - TabIndent bool // Use tabs for indent (true if nil *Options provided) - TabWidth int // Tab width (8 if nil *Options provided) - - FormatOnly bool // Disable the insertion and deletion of imports -} - -// Process implements golang.org/x/tools/imports.Process with explicit context in opt.Env. -func Process(filename string, src []byte, opt *Options) (formatted []byte, err error) { - fileSet := token.NewFileSet() - file, adjust, err := parse(fileSet, filename, src, opt) - if err != nil { - return nil, err - } - - if !opt.FormatOnly { - if err := fixImports(fileSet, file, filename, opt.Env); err != nil { - return nil, err - } - } - return formatFile(fileSet, file, src, adjust, opt) -} - -// FixImports returns a list of fixes to the imports that, when applied, -// will leave the imports in the same state as Process. src and opt must -// be specified. -// -// Note that filename's directory influences which imports can be chosen, -// so it is important that filename be accurate. -func FixImports(ctx context.Context, filename string, src []byte, opt *Options) (fixes []*ImportFix, err error) { - ctx, done := event.Start(ctx, "imports.FixImports") - defer done() - - fileSet := token.NewFileSet() - file, _, err := parse(fileSet, filename, src, opt) - if err != nil { - return nil, err - } - - return getFixes(ctx, fileSet, file, filename, opt.Env) -} - -// ApplyFixes applies all of the fixes to the file and formats it. extraMode -// is added in when parsing the file. src and opts must be specified, but no -// env is needed. -func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, extraMode parser.Mode) (formatted []byte, err error) { - // Don't use parse() -- we don't care about fragments or statement lists - // here, and we need to work with unparseable files. - fileSet := token.NewFileSet() - parserMode := parser.Mode(0) - if opt.Comments { - parserMode |= parser.ParseComments - } - if opt.AllErrors { - parserMode |= parser.AllErrors - } - parserMode |= extraMode - - file, err := parser.ParseFile(fileSet, filename, src, parserMode) - if file == nil { - return nil, err - } - - // Apply the fixes to the file. - apply(fileSet, file, fixes) - - return formatFile(fileSet, file, src, nil, opt) -} - -// formatFile formats the file syntax tree. -// It may mutate the token.FileSet. -// -// If an adjust function is provided, it is called after formatting -// with the original source (formatFile's src parameter) and the -// formatted file, and returns the postpocessed result. -func formatFile(fset *token.FileSet, file *ast.File, src []byte, adjust func(orig []byte, src []byte) []byte, opt *Options) ([]byte, error) { - mergeImports(file) - sortImports(opt.LocalPrefix, fset.File(file.Pos()), file) - var spacesBefore []string // import paths we need spaces before - for _, impSection := range astutil.Imports(fset, file) { - // Within each block of contiguous imports, see if any - // import lines are in different group numbers. If so, - // we'll need to put a space between them so it's - // compatible with gofmt. - lastGroup := -1 - for _, importSpec := range impSection { - importPath, _ := strconv.Unquote(importSpec.Path.Value) - groupNum := importGroup(opt.LocalPrefix, importPath) - if groupNum != lastGroup && lastGroup != -1 { - spacesBefore = append(spacesBefore, importPath) - } - lastGroup = groupNum - } - - } - - printerMode := printer.UseSpaces - if opt.TabIndent { - printerMode |= printer.TabIndent - } - printConfig := &printer.Config{Mode: printerMode, Tabwidth: opt.TabWidth} - - var buf bytes.Buffer - err := printConfig.Fprint(&buf, fset, file) - if err != nil { - return nil, err - } - out := buf.Bytes() - if adjust != nil { - out = adjust(src, out) - } - if len(spacesBefore) > 0 { - out, err = addImportSpaces(bytes.NewReader(out), spacesBefore) - if err != nil { - return nil, err - } - } - - out, err = format.Source(out) - if err != nil { - return nil, err - } - return out, nil -} - -// parse parses src, which was read from filename, -// as a Go source file or statement list. -func parse(fset *token.FileSet, filename string, src []byte, opt *Options) (*ast.File, func(orig, src []byte) []byte, error) { - parserMode := parser.Mode(0) - if opt.Comments { - parserMode |= parser.ParseComments - } - if opt.AllErrors { - parserMode |= parser.AllErrors - } - - // Try as whole source file. - file, err := parser.ParseFile(fset, filename, src, parserMode) - if err == nil { - return file, nil, nil - } - // If the error is that the source file didn't begin with a - // package line and we accept fragmented input, fall through to - // try as a source fragment. Stop and return on any other error. - if !opt.Fragment || !strings.Contains(err.Error(), "expected 'package'") { - return nil, nil, err - } - - // If this is a declaration list, make it a source file - // by inserting a package clause. - // Insert using a ;, not a newline, so that parse errors are on - // the correct line. - const prefix = "package main;" - psrc := append([]byte(prefix), src...) - file, err = parser.ParseFile(fset, filename, psrc, parserMode) - if err == nil { - // Gofmt will turn the ; into a \n. - // Do that ourselves now and update the file contents, - // so that positions and line numbers are correct going forward. - psrc[len(prefix)-1] = '\n' - fset.File(file.Package).SetLinesForContent(psrc) - - // If a main function exists, we will assume this is a main - // package and leave the file. - if containsMainFunc(file) { - return file, nil, nil - } - - adjust := func(orig, src []byte) []byte { - // Remove the package clause. - src = src[len(prefix):] - return matchSpace(orig, src) - } - return file, adjust, nil - } - // If the error is that the source file didn't begin with a - // declaration, fall through to try as a statement list. - // Stop and return on any other error. - if !strings.Contains(err.Error(), "expected declaration") { - return nil, nil, err - } - - // If this is a statement list, make it a source file - // by inserting a package clause and turning the list - // into a function body. This handles expressions too. - // Insert using a ;, not a newline, so that the line numbers - // in fsrc match the ones in src. - fsrc := append(append([]byte("package p; func _() {"), src...), '}') - file, err = parser.ParseFile(fset, filename, fsrc, parserMode) - if err == nil { - adjust := func(orig, src []byte) []byte { - // Remove the wrapping. - // Gofmt has turned the ; into a \n\n. - src = src[len("package p\n\nfunc _() {"):] - src = src[:len(src)-len("}\n")] - // Gofmt has also indented the function body one level. - // Remove that indent. - src = bytes.Replace(src, []byte("\n\t"), []byte("\n"), -1) - return matchSpace(orig, src) - } - return file, adjust, nil - } - - // Failed, and out of options. - return nil, nil, err -} - -// containsMainFunc checks if a file contains a function declaration with the -// function signature 'func main()' -func containsMainFunc(file *ast.File) bool { - for _, decl := range file.Decls { - if f, ok := decl.(*ast.FuncDecl); ok { - if f.Name.Name != "main" { - continue - } - - if len(f.Type.Params.List) != 0 { - continue - } - - if f.Type.Results != nil && len(f.Type.Results.List) != 0 { - continue - } - - return true - } - } - - return false -} - -func cutSpace(b []byte) (before, middle, after []byte) { - i := 0 - for i < len(b) && (b[i] == ' ' || b[i] == '\t' || b[i] == '\n') { - i++ - } - j := len(b) - for j > 0 && (b[j-1] == ' ' || b[j-1] == '\t' || b[j-1] == '\n') { - j-- - } - if i <= j { - return b[:i], b[i:j], b[j:] - } - return nil, nil, b[j:] -} - -// matchSpace reformats src to use the same space context as orig. -// 1. If orig begins with blank lines, matchSpace inserts them at the beginning of src. -// 2. matchSpace copies the indentation of the first non-blank line in orig -// to every non-blank line in src. -// 3. matchSpace copies the trailing space from orig and uses it in place -// of src's trailing space. -func matchSpace(orig []byte, src []byte) []byte { - before, _, after := cutSpace(orig) - i := bytes.LastIndex(before, []byte{'\n'}) - before, indent := before[:i+1], before[i+1:] - - _, src, _ = cutSpace(src) - - var b bytes.Buffer - b.Write(before) - for len(src) > 0 { - line := src - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, src = line[:i+1], line[i+1:] - } else { - src = nil - } - if len(line) > 0 && line[0] != '\n' { // not blank - b.Write(indent) - } - b.Write(line) - } - b.Write(after) - return b.Bytes() -} - -var impLine = regexp.MustCompile(`^\s+(?:[\w\.]+\s+)?"(.+?)"`) - -func addImportSpaces(r io.Reader, breaks []string) ([]byte, error) { - var out bytes.Buffer - in := bufio.NewReader(r) - inImports := false - done := false - for { - s, err := in.ReadString('\n') - if err == io.EOF { - break - } else if err != nil { - return nil, err - } - - if !inImports && !done && strings.HasPrefix(s, "import") { - inImports = true - } - if inImports && (strings.HasPrefix(s, "var") || - strings.HasPrefix(s, "func") || - strings.HasPrefix(s, "const") || - strings.HasPrefix(s, "type")) { - done = true - inImports = false - } - if inImports && len(breaks) > 0 { - if m := impLine.FindStringSubmatch(s); m != nil { - if m[1] == breaks[0] { - out.WriteByte('\n') - breaks = breaks[1:] - } - } - } - - fmt.Fprint(&out, s) - } - return out.Bytes(), nil -} diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go deleted file mode 100644 index 5f4d435d..00000000 --- a/vendor/golang.org/x/tools/internal/imports/mod.go +++ /dev/null @@ -1,723 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package imports - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "os" - "path" - "path/filepath" - "regexp" - "sort" - "strconv" - "strings" - - "golang.org/x/mod/module" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/gopathwalk" -) - -// ModuleResolver implements resolver for modules using the go command as little -// as feasible. -type ModuleResolver struct { - env *ProcessEnv - moduleCacheDir string - dummyVendorMod *gocommand.ModuleJSON // If vendoring is enabled, the pseudo-module that represents the /vendor directory. - roots []gopathwalk.Root - scanSema chan struct{} // scanSema prevents concurrent scans and guards scannedRoots. - scannedRoots map[gopathwalk.Root]bool - - initialized bool - mains []*gocommand.ModuleJSON - mainByDir map[string]*gocommand.ModuleJSON - modsByModPath []*gocommand.ModuleJSON // All modules, ordered by # of path components in module Path... - modsByDir []*gocommand.ModuleJSON // ...or number of path components in their Dir. - - // moduleCacheCache stores information about the module cache. - moduleCacheCache *dirInfoCache - otherCache *dirInfoCache -} - -func newModuleResolver(e *ProcessEnv) *ModuleResolver { - r := &ModuleResolver{ - env: e, - scanSema: make(chan struct{}, 1), - } - r.scanSema <- struct{}{} - return r -} - -func (r *ModuleResolver) init() error { - if r.initialized { - return nil - } - - goenv, err := r.env.goEnv() - if err != nil { - return err - } - inv := gocommand.Invocation{ - BuildFlags: r.env.BuildFlags, - ModFlag: r.env.ModFlag, - ModFile: r.env.ModFile, - Env: r.env.env(), - Logf: r.env.Logf, - WorkingDir: r.env.WorkingDir, - } - - vendorEnabled := false - var mainModVendor *gocommand.ModuleJSON - - // Module vendor directories are ignored in workspace mode: - // https://go.googlesource.com/proposal/+/master/design/45713-workspace.md - if len(r.env.Env["GOWORK"]) == 0 { - vendorEnabled, mainModVendor, err = gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) - if err != nil { - return err - } - } - - if mainModVendor != nil && vendorEnabled { - // Vendor mode is on, so all the non-Main modules are irrelevant, - // and we need to search /vendor for everything. - r.mains = []*gocommand.ModuleJSON{mainModVendor} - r.dummyVendorMod = &gocommand.ModuleJSON{ - Path: "", - Dir: filepath.Join(mainModVendor.Dir, "vendor"), - } - r.modsByModPath = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod} - r.modsByDir = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod} - } else { - // Vendor mode is off, so run go list -m ... to find everything. - err := r.initAllMods() - // We expect an error when running outside of a module with - // GO111MODULE=on. Other errors are fatal. - if err != nil { - if errMsg := err.Error(); !strings.Contains(errMsg, "working directory is not part of a module") && !strings.Contains(errMsg, "go.mod file not found") { - return err - } - } - } - - if gmc := r.env.Env["GOMODCACHE"]; gmc != "" { - r.moduleCacheDir = gmc - } else { - gopaths := filepath.SplitList(goenv["GOPATH"]) - if len(gopaths) == 0 { - return fmt.Errorf("empty GOPATH") - } - r.moduleCacheDir = filepath.Join(gopaths[0], "/pkg/mod") - } - - sort.Slice(r.modsByModPath, func(i, j int) bool { - count := func(x int) int { - return strings.Count(r.modsByModPath[x].Path, "/") - } - return count(j) < count(i) // descending order - }) - sort.Slice(r.modsByDir, func(i, j int) bool { - count := func(x int) int { - return strings.Count(r.modsByDir[x].Dir, string(filepath.Separator)) - } - return count(j) < count(i) // descending order - }) - - r.roots = []gopathwalk.Root{ - {Path: filepath.Join(goenv["GOROOT"], "/src"), Type: gopathwalk.RootGOROOT}, - } - r.mainByDir = make(map[string]*gocommand.ModuleJSON) - for _, main := range r.mains { - r.roots = append(r.roots, gopathwalk.Root{Path: main.Dir, Type: gopathwalk.RootCurrentModule}) - r.mainByDir[main.Dir] = main - } - if vendorEnabled { - r.roots = append(r.roots, gopathwalk.Root{Path: r.dummyVendorMod.Dir, Type: gopathwalk.RootOther}) - } else { - addDep := func(mod *gocommand.ModuleJSON) { - if mod.Replace == nil { - // This is redundant with the cache, but we'll skip it cheaply enough. - r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootModuleCache}) - } else { - r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootOther}) - } - } - // Walk dependent modules before scanning the full mod cache, direct deps first. - for _, mod := range r.modsByModPath { - if !mod.Indirect && !mod.Main { - addDep(mod) - } - } - for _, mod := range r.modsByModPath { - if mod.Indirect && !mod.Main { - addDep(mod) - } - } - r.roots = append(r.roots, gopathwalk.Root{Path: r.moduleCacheDir, Type: gopathwalk.RootModuleCache}) - } - - r.scannedRoots = map[gopathwalk.Root]bool{} - if r.moduleCacheCache == nil { - r.moduleCacheCache = &dirInfoCache{ - dirs: map[string]*directoryPackageInfo{}, - listeners: map[*int]cacheListener{}, - } - } - if r.otherCache == nil { - r.otherCache = &dirInfoCache{ - dirs: map[string]*directoryPackageInfo{}, - listeners: map[*int]cacheListener{}, - } - } - r.initialized = true - return nil -} - -func (r *ModuleResolver) initAllMods() error { - stdout, err := r.env.invokeGo(context.TODO(), "list", "-m", "-e", "-json", "...") - if err != nil { - return err - } - for dec := json.NewDecoder(stdout); dec.More(); { - mod := &gocommand.ModuleJSON{} - if err := dec.Decode(mod); err != nil { - return err - } - if mod.Dir == "" { - if r.env.Logf != nil { - r.env.Logf("module %v has not been downloaded and will be ignored", mod.Path) - } - // Can't do anything with a module that's not downloaded. - continue - } - // golang/go#36193: the go command doesn't always clean paths. - mod.Dir = filepath.Clean(mod.Dir) - r.modsByModPath = append(r.modsByModPath, mod) - r.modsByDir = append(r.modsByDir, mod) - if mod.Main { - r.mains = append(r.mains, mod) - } - } - return nil -} - -func (r *ModuleResolver) ClearForNewScan() { - <-r.scanSema - r.scannedRoots = map[gopathwalk.Root]bool{} - r.otherCache = &dirInfoCache{ - dirs: map[string]*directoryPackageInfo{}, - listeners: map[*int]cacheListener{}, - } - r.scanSema <- struct{}{} -} - -func (r *ModuleResolver) ClearForNewMod() { - <-r.scanSema - *r = ModuleResolver{ - env: r.env, - moduleCacheCache: r.moduleCacheCache, - otherCache: r.otherCache, - scanSema: r.scanSema, - } - r.init() - r.scanSema <- struct{}{} -} - -// findPackage returns the module and directory that contains the package at -// the given import path, or returns nil, "" if no module is in scope. -func (r *ModuleResolver) findPackage(importPath string) (*gocommand.ModuleJSON, string) { - // This can't find packages in the stdlib, but that's harmless for all - // the existing code paths. - for _, m := range r.modsByModPath { - if !strings.HasPrefix(importPath, m.Path) { - continue - } - pathInModule := importPath[len(m.Path):] - pkgDir := filepath.Join(m.Dir, pathInModule) - if r.dirIsNestedModule(pkgDir, m) { - continue - } - - if info, ok := r.cacheLoad(pkgDir); ok { - if loaded, err := info.reachedStatus(nameLoaded); loaded { - if err != nil { - continue // No package in this dir. - } - return m, pkgDir - } - if scanned, err := info.reachedStatus(directoryScanned); scanned && err != nil { - continue // Dir is unreadable, etc. - } - // This is slightly wrong: a directory doesn't have to have an - // importable package to count as a package for package-to-module - // resolution. package main or _test files should count but - // don't. - // TODO(heschi): fix this. - if _, err := r.cachePackageName(info); err == nil { - return m, pkgDir - } - } - - // Not cached. Read the filesystem. - pkgFiles, err := os.ReadDir(pkgDir) - if err != nil { - continue - } - // A module only contains a package if it has buildable go - // files in that directory. If not, it could be provided by an - // outer module. See #29736. - for _, fi := range pkgFiles { - if ok, _ := r.env.matchFile(pkgDir, fi.Name()); ok { - return m, pkgDir - } - } - } - return nil, "" -} - -func (r *ModuleResolver) cacheLoad(dir string) (directoryPackageInfo, bool) { - if info, ok := r.moduleCacheCache.Load(dir); ok { - return info, ok - } - return r.otherCache.Load(dir) -} - -func (r *ModuleResolver) cacheStore(info directoryPackageInfo) { - if info.rootType == gopathwalk.RootModuleCache { - r.moduleCacheCache.Store(info.dir, info) - } else { - r.otherCache.Store(info.dir, info) - } -} - -func (r *ModuleResolver) cacheKeys() []string { - return append(r.moduleCacheCache.Keys(), r.otherCache.Keys()...) -} - -// cachePackageName caches the package name for a dir already in the cache. -func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (string, error) { - if info.rootType == gopathwalk.RootModuleCache { - return r.moduleCacheCache.CachePackageName(info) - } - return r.otherCache.CachePackageName(info) -} - -func (r *ModuleResolver) cacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []string, error) { - if info.rootType == gopathwalk.RootModuleCache { - return r.moduleCacheCache.CacheExports(ctx, env, info) - } - return r.otherCache.CacheExports(ctx, env, info) -} - -// findModuleByDir returns the module that contains dir, or nil if no such -// module is in scope. -func (r *ModuleResolver) findModuleByDir(dir string) *gocommand.ModuleJSON { - // This is quite tricky and may not be correct. dir could be: - // - a package in the main module. - // - a replace target underneath the main module's directory. - // - a nested module in the above. - // - a replace target somewhere totally random. - // - a nested module in the above. - // - in the mod cache. - // - in /vendor/ in -mod=vendor mode. - // - nested module? Dunno. - // Rumor has it that replace targets cannot contain other replace targets. - // - // Note that it is critical here that modsByDir is sorted to have deeper dirs - // first. This ensures that findModuleByDir finds the innermost module. - // See also golang/go#56291. - for _, m := range r.modsByDir { - if !strings.HasPrefix(dir, m.Dir) { - continue - } - - if r.dirIsNestedModule(dir, m) { - continue - } - - return m - } - return nil -} - -// dirIsNestedModule reports if dir is contained in a nested module underneath -// mod, not actually in mod. -func (r *ModuleResolver) dirIsNestedModule(dir string, mod *gocommand.ModuleJSON) bool { - if !strings.HasPrefix(dir, mod.Dir) { - return false - } - if r.dirInModuleCache(dir) { - // Nested modules in the module cache are pruned, - // so it cannot be a nested module. - return false - } - if mod != nil && mod == r.dummyVendorMod { - // The /vendor pseudomodule is flattened and doesn't actually count. - return false - } - modDir, _ := r.modInfo(dir) - if modDir == "" { - return false - } - return modDir != mod.Dir -} - -func (r *ModuleResolver) modInfo(dir string) (modDir string, modName string) { - readModName := func(modFile string) string { - modBytes, err := os.ReadFile(modFile) - if err != nil { - return "" - } - return modulePath(modBytes) - } - - if r.dirInModuleCache(dir) { - if matches := modCacheRegexp.FindStringSubmatch(dir); len(matches) == 3 { - index := strings.Index(dir, matches[1]+"@"+matches[2]) - modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2]) - return modDir, readModName(filepath.Join(modDir, "go.mod")) - } - } - for { - if info, ok := r.cacheLoad(dir); ok { - return info.moduleDir, info.moduleName - } - f := filepath.Join(dir, "go.mod") - info, err := os.Stat(f) - if err == nil && !info.IsDir() { - return dir, readModName(f) - } - - d := filepath.Dir(dir) - if len(d) >= len(dir) { - return "", "" // reached top of file system, no go.mod - } - dir = d - } -} - -func (r *ModuleResolver) dirInModuleCache(dir string) bool { - if r.moduleCacheDir == "" { - return false - } - return strings.HasPrefix(dir, r.moduleCacheDir) -} - -func (r *ModuleResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) { - if err := r.init(); err != nil { - return nil, err - } - names := map[string]string{} - for _, path := range importPaths { - _, packageDir := r.findPackage(path) - if packageDir == "" { - continue - } - name, err := packageDirToName(packageDir) - if err != nil { - continue - } - names[path] = name - } - return names, nil -} - -func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error { - ctx, done := event.Start(ctx, "imports.ModuleResolver.scan") - defer done() - - if err := r.init(); err != nil { - return err - } - - processDir := func(info directoryPackageInfo) { - // Skip this directory if we were not able to get the package information successfully. - if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { - return - } - pkg, err := r.canonicalize(info) - if err != nil { - return - } - - if !callback.dirFound(pkg) { - return - } - pkg.packageName, err = r.cachePackageName(info) - if err != nil { - return - } - - if !callback.packageNameLoaded(pkg) { - return - } - _, exports, err := r.loadExports(ctx, pkg, false) - if err != nil { - return - } - callback.exportsLoaded(pkg, exports) - } - - // Start processing everything in the cache, and listen for the new stuff - // we discover in the walk below. - stop1 := r.moduleCacheCache.ScanAndListen(ctx, processDir) - defer stop1() - stop2 := r.otherCache.ScanAndListen(ctx, processDir) - defer stop2() - - // We assume cached directories are fully cached, including all their - // children, and have not changed. We can skip them. - skip := func(root gopathwalk.Root, dir string) bool { - if r.env.SkipPathInScan != nil && root.Type == gopathwalk.RootCurrentModule { - if root.Path == dir { - return false - } - - if r.env.SkipPathInScan(filepath.Clean(dir)) { - return true - } - } - - info, ok := r.cacheLoad(dir) - if !ok { - return false - } - // This directory can be skipped as long as we have already scanned it. - // Packages with errors will continue to have errors, so there is no need - // to rescan them. - packageScanned, _ := info.reachedStatus(directoryScanned) - return packageScanned - } - - // Add anything new to the cache, and process it if we're still listening. - add := func(root gopathwalk.Root, dir string) { - r.cacheStore(r.scanDirForPackage(root, dir)) - } - - // r.roots and the callback are not necessarily safe to use in the - // goroutine below. Process them eagerly. - roots := filterRoots(r.roots, callback.rootFound) - // We can't cancel walks, because we need them to finish to have a usable - // cache. Instead, run them in a separate goroutine and detach. - scanDone := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - return - case <-r.scanSema: - } - defer func() { r.scanSema <- struct{}{} }() - // We have the lock on r.scannedRoots, and no other scans can run. - for _, root := range roots { - if ctx.Err() != nil { - return - } - - if r.scannedRoots[root] { - continue - } - gopathwalk.WalkSkip([]gopathwalk.Root{root}, add, skip, gopathwalk.Options{Logf: r.env.Logf, ModulesEnabled: true}) - r.scannedRoots[root] = true - } - close(scanDone) - }() - select { - case <-ctx.Done(): - case <-scanDone: - } - return nil -} - -func (r *ModuleResolver) scoreImportPath(ctx context.Context, path string) float64 { - if _, ok := stdlib[path]; ok { - return MaxRelevance - } - mod, _ := r.findPackage(path) - return modRelevance(mod) -} - -func modRelevance(mod *gocommand.ModuleJSON) float64 { - var relevance float64 - switch { - case mod == nil: // out of scope - return MaxRelevance - 4 - case mod.Indirect: - relevance = MaxRelevance - 3 - case !mod.Main: - relevance = MaxRelevance - 2 - default: - relevance = MaxRelevance - 1 // main module ties with stdlib - } - - _, versionString, ok := module.SplitPathVersion(mod.Path) - if ok { - index := strings.Index(versionString, "v") - if index == -1 { - return relevance - } - if versionNumber, err := strconv.ParseFloat(versionString[index+1:], 64); err == nil { - relevance += versionNumber / 1000 - } - } - - return relevance -} - -// canonicalize gets the result of canonicalizing the packages using the results -// of initializing the resolver from 'go list -m'. -func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) { - // Packages in GOROOT are already canonical, regardless of the std/cmd modules. - if info.rootType == gopathwalk.RootGOROOT { - return &pkg{ - importPathShort: info.nonCanonicalImportPath, - dir: info.dir, - packageName: path.Base(info.nonCanonicalImportPath), - relevance: MaxRelevance, - }, nil - } - - importPath := info.nonCanonicalImportPath - mod := r.findModuleByDir(info.dir) - // Check if the directory is underneath a module that's in scope. - if mod != nil { - // It is. If dir is the target of a replace directive, - // our guessed import path is wrong. Use the real one. - if mod.Dir == info.dir { - importPath = mod.Path - } else { - dirInMod := info.dir[len(mod.Dir)+len("/"):] - importPath = path.Join(mod.Path, filepath.ToSlash(dirInMod)) - } - } else if !strings.HasPrefix(importPath, info.moduleName) { - // The module's name doesn't match the package's import path. It - // probably needs a replace directive we don't have. - return nil, fmt.Errorf("package in %q is not valid without a replace statement", info.dir) - } - - res := &pkg{ - importPathShort: importPath, - dir: info.dir, - relevance: modRelevance(mod), - } - // We may have discovered a package that has a different version - // in scope already. Canonicalize to that one if possible. - if _, canonicalDir := r.findPackage(importPath); canonicalDir != "" { - res.dir = canonicalDir - } - return res, nil -} - -func (r *ModuleResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error) { - if err := r.init(); err != nil { - return "", nil, err - } - if info, ok := r.cacheLoad(pkg.dir); ok && !includeTest { - return r.cacheExports(ctx, r.env, info) - } - return loadExportsFromFiles(ctx, r.env, pkg.dir, includeTest) -} - -func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) directoryPackageInfo { - subdir := "" - if dir != root.Path { - subdir = dir[len(root.Path)+len("/"):] - } - importPath := filepath.ToSlash(subdir) - if strings.HasPrefix(importPath, "vendor/") { - // Only enter vendor directories if they're explicitly requested as a root. - return directoryPackageInfo{ - status: directoryScanned, - err: fmt.Errorf("unwanted vendor directory"), - } - } - switch root.Type { - case gopathwalk.RootCurrentModule: - importPath = path.Join(r.mainByDir[root.Path].Path, filepath.ToSlash(subdir)) - case gopathwalk.RootModuleCache: - matches := modCacheRegexp.FindStringSubmatch(subdir) - if len(matches) == 0 { - return directoryPackageInfo{ - status: directoryScanned, - err: fmt.Errorf("invalid module cache path: %v", subdir), - } - } - modPath, err := module.UnescapePath(filepath.ToSlash(matches[1])) - if err != nil { - if r.env.Logf != nil { - r.env.Logf("decoding module cache path %q: %v", subdir, err) - } - return directoryPackageInfo{ - status: directoryScanned, - err: fmt.Errorf("decoding module cache path %q: %v", subdir, err), - } - } - importPath = path.Join(modPath, filepath.ToSlash(matches[3])) - } - - modDir, modName := r.modInfo(dir) - result := directoryPackageInfo{ - status: directoryScanned, - dir: dir, - rootType: root.Type, - nonCanonicalImportPath: importPath, - moduleDir: modDir, - moduleName: modName, - } - if root.Type == gopathwalk.RootGOROOT { - // stdlib packages are always in scope, despite the confusing go.mod - return result - } - return result -} - -// modCacheRegexp splits a path in a module cache into module, module version, and package. -var modCacheRegexp = regexp.MustCompile(`(.*)@([^/\\]*)(.*)`) - -var ( - slashSlash = []byte("//") - moduleStr = []byte("module") -) - -// modulePath returns the module path from the gomod file text. -// If it cannot find a module path, it returns an empty string. -// It is tolerant of unrelated problems in the go.mod file. -// -// Copied from cmd/go/internal/modfile. -func modulePath(mod []byte) string { - for len(mod) > 0 { - line := mod - mod = nil - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, mod = line[:i], line[i+1:] - } - if i := bytes.Index(line, slashSlash); i >= 0 { - line = line[:i] - } - line = bytes.TrimSpace(line) - if !bytes.HasPrefix(line, moduleStr) { - continue - } - line = line[len(moduleStr):] - n := len(line) - line = bytes.TrimSpace(line) - if len(line) == n || len(line) == 0 { - continue - } - - if line[0] == '"' || line[0] == '`' { - p, err := strconv.Unquote(string(line)) - if err != nil { - return "" // malformed quoted string or multiline module path - } - return p - } - - return string(line) - } - return "" // missing module path -} diff --git a/vendor/golang.org/x/tools/internal/imports/mod_cache.go b/vendor/golang.org/x/tools/internal/imports/mod_cache.go deleted file mode 100644 index 45690abb..00000000 --- a/vendor/golang.org/x/tools/internal/imports/mod_cache.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package imports - -import ( - "context" - "fmt" - "sync" - - "golang.org/x/tools/internal/gopathwalk" -) - -// To find packages to import, the resolver needs to know about all of -// the packages that could be imported. This includes packages that are -// already in modules that are in (1) the current module, (2) replace targets, -// and (3) packages in the module cache. Packages in (1) and (2) may change over -// time, as the client may edit the current module and locally replaced modules. -// The module cache (which includes all of the packages in (3)) can only -// ever be added to. -// -// The resolver can thus save state about packages in the module cache -// and guarantee that this will not change over time. To obtain information -// about new modules added to the module cache, the module cache should be -// rescanned. -// -// It is OK to serve information about modules that have been deleted, -// as they do still exist. -// TODO(suzmue): can we share information with the caller about -// what module needs to be downloaded to import this package? - -type directoryPackageStatus int - -const ( - _ directoryPackageStatus = iota - directoryScanned - nameLoaded - exportsLoaded -) - -type directoryPackageInfo struct { - // status indicates the extent to which this struct has been filled in. - status directoryPackageStatus - // err is non-nil when there was an error trying to reach status. - err error - - // Set when status >= directoryScanned. - - // dir is the absolute directory of this package. - dir string - rootType gopathwalk.RootType - // nonCanonicalImportPath is the package's expected import path. It may - // not actually be importable at that path. - nonCanonicalImportPath string - - // Module-related information. - moduleDir string // The directory that is the module root of this dir. - moduleName string // The module name that contains this dir. - - // Set when status >= nameLoaded. - - packageName string // the package name, as declared in the source. - - // Set when status >= exportsLoaded. - - exports []string -} - -// reachedStatus returns true when info has a status at least target and any error associated with -// an attempt to reach target. -func (info *directoryPackageInfo) reachedStatus(target directoryPackageStatus) (bool, error) { - if info.err == nil { - return info.status >= target, nil - } - if info.status == target { - return true, info.err - } - return true, nil -} - -// dirInfoCache is a concurrency safe map for storing information about -// directories that may contain packages. -// -// The information in this cache is built incrementally. Entries are initialized in scan. -// No new keys should be added in any other functions, as all directories containing -// packages are identified in scan. -// -// Other functions, including loadExports and findPackage, may update entries in this cache -// as they discover new things about the directory. -// -// The information in the cache is not expected to change for the cache's -// lifetime, so there is no protection against competing writes. Users should -// take care not to hold the cache across changes to the underlying files. -// -// TODO(suzmue): consider other concurrency strategies and data structures (RWLocks, sync.Map, etc) -type dirInfoCache struct { - mu sync.Mutex - // dirs stores information about packages in directories, keyed by absolute path. - dirs map[string]*directoryPackageInfo - listeners map[*int]cacheListener -} - -type cacheListener func(directoryPackageInfo) - -// ScanAndListen calls listener on all the items in the cache, and on anything -// newly added. The returned stop function waits for all in-flight callbacks to -// finish and blocks new ones. -func (d *dirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func() { - ctx, cancel := context.WithCancel(ctx) - - // Flushing out all the callbacks is tricky without knowing how many there - // are going to be. Setting an arbitrary limit makes it much easier. - const maxInFlight = 10 - sema := make(chan struct{}, maxInFlight) - for i := 0; i < maxInFlight; i++ { - sema <- struct{}{} - } - - cookie := new(int) // A unique ID we can use for the listener. - - // We can't hold mu while calling the listener. - d.mu.Lock() - var keys []string - for key := range d.dirs { - keys = append(keys, key) - } - d.listeners[cookie] = func(info directoryPackageInfo) { - select { - case <-ctx.Done(): - return - case <-sema: - } - listener(info) - sema <- struct{}{} - } - d.mu.Unlock() - - stop := func() { - cancel() - d.mu.Lock() - delete(d.listeners, cookie) - d.mu.Unlock() - for i := 0; i < maxInFlight; i++ { - <-sema - } - } - - // Process the pre-existing keys. - for _, k := range keys { - select { - case <-ctx.Done(): - return stop - default: - } - if v, ok := d.Load(k); ok { - listener(v) - } - } - - return stop -} - -// Store stores the package info for dir. -func (d *dirInfoCache) Store(dir string, info directoryPackageInfo) { - d.mu.Lock() - _, old := d.dirs[dir] - d.dirs[dir] = &info - var listeners []cacheListener - for _, l := range d.listeners { - listeners = append(listeners, l) - } - d.mu.Unlock() - - if !old { - for _, l := range listeners { - l(info) - } - } -} - -// Load returns a copy of the directoryPackageInfo for absolute directory dir. -func (d *dirInfoCache) Load(dir string) (directoryPackageInfo, bool) { - d.mu.Lock() - defer d.mu.Unlock() - info, ok := d.dirs[dir] - if !ok { - return directoryPackageInfo{}, false - } - return *info, true -} - -// Keys returns the keys currently present in d. -func (d *dirInfoCache) Keys() (keys []string) { - d.mu.Lock() - defer d.mu.Unlock() - for key := range d.dirs { - keys = append(keys, key) - } - return keys -} - -func (d *dirInfoCache) CachePackageName(info directoryPackageInfo) (string, error) { - if loaded, err := info.reachedStatus(nameLoaded); loaded { - return info.packageName, err - } - if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { - return "", fmt.Errorf("cannot read package name, scan error: %v", err) - } - info.packageName, info.err = packageDirToName(info.dir) - info.status = nameLoaded - d.Store(info.dir, info) - return info.packageName, info.err -} - -func (d *dirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []string, error) { - if reached, _ := info.reachedStatus(exportsLoaded); reached { - return info.packageName, info.exports, info.err - } - if reached, err := info.reachedStatus(nameLoaded); reached && err != nil { - return "", nil, err - } - info.packageName, info.exports, info.err = loadExportsFromFiles(ctx, env, info.dir, false) - if info.err == context.Canceled || info.err == context.DeadlineExceeded { - return info.packageName, info.exports, info.err - } - // The cache structure wants things to proceed linearly. We can skip a - // step here, but only if we succeed. - if info.status == nameLoaded || info.err == nil { - info.status = exportsLoaded - } else { - info.status = nameLoaded - } - d.Store(info.dir, info) - return info.packageName, info.exports, info.err -} diff --git a/vendor/golang.org/x/tools/internal/imports/sortimports.go b/vendor/golang.org/x/tools/internal/imports/sortimports.go deleted file mode 100644 index 1a0a7ebd..00000000 --- a/vendor/golang.org/x/tools/internal/imports/sortimports.go +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Hacked up copy of go/ast/import.go -// Modified to use a single token.File in preference to a FileSet. - -package imports - -import ( - "go/ast" - "go/token" - "log" - "sort" - "strconv" -) - -// sortImports sorts runs of consecutive import lines in import blocks in f. -// It also removes duplicate imports when it is possible to do so without data loss. -// -// It may mutate the token.File. -func sortImports(localPrefix string, tokFile *token.File, f *ast.File) { - for i, d := range f.Decls { - d, ok := d.(*ast.GenDecl) - if !ok || d.Tok != token.IMPORT { - // Not an import declaration, so we're done. - // Imports are always first. - break - } - - if len(d.Specs) == 0 { - // Empty import block, remove it. - f.Decls = append(f.Decls[:i], f.Decls[i+1:]...) - } - - if !d.Lparen.IsValid() { - // Not a block: sorted by default. - continue - } - - // Identify and sort runs of specs on successive lines. - i := 0 - specs := d.Specs[:0] - for j, s := range d.Specs { - if j > i && tokFile.Line(s.Pos()) > 1+tokFile.Line(d.Specs[j-1].End()) { - // j begins a new run. End this one. - specs = append(specs, sortSpecs(localPrefix, tokFile, f, d.Specs[i:j])...) - i = j - } - } - specs = append(specs, sortSpecs(localPrefix, tokFile, f, d.Specs[i:])...) - d.Specs = specs - - // Deduping can leave a blank line before the rparen; clean that up. - // Ignore line directives. - if len(d.Specs) > 0 { - lastSpec := d.Specs[len(d.Specs)-1] - lastLine := tokFile.PositionFor(lastSpec.Pos(), false).Line - if rParenLine := tokFile.PositionFor(d.Rparen, false).Line; rParenLine > lastLine+1 { - tokFile.MergeLine(rParenLine - 1) // has side effects! - } - } - } -} - -// mergeImports merges all the import declarations into the first one. -// Taken from golang.org/x/tools/ast/astutil. -// This does not adjust line numbers properly -func mergeImports(f *ast.File) { - if len(f.Decls) <= 1 { - return - } - - // Merge all the import declarations into the first one. - var first *ast.GenDecl - for i := 0; i < len(f.Decls); i++ { - decl := f.Decls[i] - gen, ok := decl.(*ast.GenDecl) - if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") { - continue - } - if first == nil { - first = gen - continue // Don't touch the first one. - } - // We now know there is more than one package in this import - // declaration. Ensure that it ends up parenthesized. - first.Lparen = first.Pos() - // Move the imports of the other import declaration to the first one. - for _, spec := range gen.Specs { - spec.(*ast.ImportSpec).Path.ValuePos = first.Pos() - first.Specs = append(first.Specs, spec) - } - f.Decls = append(f.Decls[:i], f.Decls[i+1:]...) - i-- - } -} - -// declImports reports whether gen contains an import of path. -// Taken from golang.org/x/tools/ast/astutil. -func declImports(gen *ast.GenDecl, path string) bool { - if gen.Tok != token.IMPORT { - return false - } - for _, spec := range gen.Specs { - impspec := spec.(*ast.ImportSpec) - if importPath(impspec) == path { - return true - } - } - return false -} - -func importPath(s ast.Spec) string { - t, err := strconv.Unquote(s.(*ast.ImportSpec).Path.Value) - if err == nil { - return t - } - return "" -} - -func importName(s ast.Spec) string { - n := s.(*ast.ImportSpec).Name - if n == nil { - return "" - } - return n.Name -} - -func importComment(s ast.Spec) string { - c := s.(*ast.ImportSpec).Comment - if c == nil { - return "" - } - return c.Text() -} - -// collapse indicates whether prev may be removed, leaving only next. -func collapse(prev, next ast.Spec) bool { - if importPath(next) != importPath(prev) || importName(next) != importName(prev) { - return false - } - return prev.(*ast.ImportSpec).Comment == nil -} - -type posSpan struct { - Start token.Pos - End token.Pos -} - -// sortSpecs sorts the import specs within each import decl. -// It may mutate the token.File. -func sortSpecs(localPrefix string, tokFile *token.File, f *ast.File, specs []ast.Spec) []ast.Spec { - // Can't short-circuit here even if specs are already sorted, - // since they might yet need deduplication. - // A lone import, however, may be safely ignored. - if len(specs) <= 1 { - return specs - } - - // Record positions for specs. - pos := make([]posSpan, len(specs)) - for i, s := range specs { - pos[i] = posSpan{s.Pos(), s.End()} - } - - // Identify comments in this range. - // Any comment from pos[0].Start to the final line counts. - lastLine := tokFile.Line(pos[len(pos)-1].End) - cstart := len(f.Comments) - cend := len(f.Comments) - for i, g := range f.Comments { - if g.Pos() < pos[0].Start { - continue - } - if i < cstart { - cstart = i - } - if tokFile.Line(g.End()) > lastLine { - cend = i - break - } - } - comments := f.Comments[cstart:cend] - - // Assign each comment to the import spec preceding it. - importComment := map[*ast.ImportSpec][]*ast.CommentGroup{} - specIndex := 0 - for _, g := range comments { - for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() { - specIndex++ - } - s := specs[specIndex].(*ast.ImportSpec) - importComment[s] = append(importComment[s], g) - } - - // Sort the import specs by import path. - // Remove duplicates, when possible without data loss. - // Reassign the import paths to have the same position sequence. - // Reassign each comment to abut the end of its spec. - // Sort the comments by new position. - sort.Sort(byImportSpec{localPrefix, specs}) - - // Dedup. Thanks to our sorting, we can just consider - // adjacent pairs of imports. - deduped := specs[:0] - for i, s := range specs { - if i == len(specs)-1 || !collapse(s, specs[i+1]) { - deduped = append(deduped, s) - } else { - p := s.Pos() - tokFile.MergeLine(tokFile.Line(p)) // has side effects! - } - } - specs = deduped - - // Fix up comment positions - for i, s := range specs { - s := s.(*ast.ImportSpec) - if s.Name != nil { - s.Name.NamePos = pos[i].Start - } - s.Path.ValuePos = pos[i].Start - s.EndPos = pos[i].End - nextSpecPos := pos[i].End - - for _, g := range importComment[s] { - for _, c := range g.List { - c.Slash = pos[i].End - nextSpecPos = c.End() - } - } - if i < len(specs)-1 { - pos[i+1].Start = nextSpecPos - pos[i+1].End = nextSpecPos - } - } - - sort.Sort(byCommentPos(comments)) - - // Fixup comments can insert blank lines, because import specs are on different lines. - // We remove those blank lines here by merging import spec to the first import spec line. - firstSpecLine := tokFile.Line(specs[0].Pos()) - for _, s := range specs[1:] { - p := s.Pos() - line := tokFile.Line(p) - for previousLine := line - 1; previousLine >= firstSpecLine; { - // MergeLine can panic. Avoid the panic at the cost of not removing the blank line - // golang/go#50329 - if previousLine > 0 && previousLine < tokFile.LineCount() { - tokFile.MergeLine(previousLine) // has side effects! - previousLine-- - } else { - // try to gather some data to diagnose how this could happen - req := "Please report what the imports section of your go file looked like." - log.Printf("panic avoided: first:%d line:%d previous:%d max:%d. %s", - firstSpecLine, line, previousLine, tokFile.LineCount(), req) - } - } - } - return specs -} - -type byImportSpec struct { - localPrefix string - specs []ast.Spec // slice of *ast.ImportSpec -} - -func (x byImportSpec) Len() int { return len(x.specs) } -func (x byImportSpec) Swap(i, j int) { x.specs[i], x.specs[j] = x.specs[j], x.specs[i] } -func (x byImportSpec) Less(i, j int) bool { - ipath := importPath(x.specs[i]) - jpath := importPath(x.specs[j]) - - igroup := importGroup(x.localPrefix, ipath) - jgroup := importGroup(x.localPrefix, jpath) - if igroup != jgroup { - return igroup < jgroup - } - - if ipath != jpath { - return ipath < jpath - } - iname := importName(x.specs[i]) - jname := importName(x.specs[j]) - - if iname != jname { - return iname < jname - } - return importComment(x.specs[i]) < importComment(x.specs[j]) -} - -type byCommentPos []*ast.CommentGroup - -func (x byCommentPos) Len() int { return len(x) } -func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] } -func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() } diff --git a/vendor/golang.org/x/tools/internal/imports/zstdlib.go b/vendor/golang.org/x/tools/internal/imports/zstdlib.go deleted file mode 100644 index 9f992c2b..00000000 --- a/vendor/golang.org/x/tools/internal/imports/zstdlib.go +++ /dev/null @@ -1,11345 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by mkstdlib.go. DO NOT EDIT. - -package imports - -var stdlib = map[string][]string{ - "archive/tar": { - "ErrFieldTooLong", - "ErrHeader", - "ErrInsecurePath", - "ErrWriteAfterClose", - "ErrWriteTooLong", - "FileInfoHeader", - "Format", - "FormatGNU", - "FormatPAX", - "FormatUSTAR", - "FormatUnknown", - "Header", - "NewReader", - "NewWriter", - "Reader", - "TypeBlock", - "TypeChar", - "TypeCont", - "TypeDir", - "TypeFifo", - "TypeGNULongLink", - "TypeGNULongName", - "TypeGNUSparse", - "TypeLink", - "TypeReg", - "TypeRegA", - "TypeSymlink", - "TypeXGlobalHeader", - "TypeXHeader", - "Writer", - }, - "archive/zip": { - "Compressor", - "Decompressor", - "Deflate", - "ErrAlgorithm", - "ErrChecksum", - "ErrFormat", - "ErrInsecurePath", - "File", - "FileHeader", - "FileInfoHeader", - "NewReader", - "NewWriter", - "OpenReader", - "ReadCloser", - "Reader", - "RegisterCompressor", - "RegisterDecompressor", - "Store", - "Writer", - }, - "bufio": { - "ErrAdvanceTooFar", - "ErrBadReadCount", - "ErrBufferFull", - "ErrFinalToken", - "ErrInvalidUnreadByte", - "ErrInvalidUnreadRune", - "ErrNegativeAdvance", - "ErrNegativeCount", - "ErrTooLong", - "MaxScanTokenSize", - "NewReadWriter", - "NewReader", - "NewReaderSize", - "NewScanner", - "NewWriter", - "NewWriterSize", - "ReadWriter", - "Reader", - "ScanBytes", - "ScanLines", - "ScanRunes", - "ScanWords", - "Scanner", - "SplitFunc", - "Writer", - }, - "bytes": { - "Buffer", - "Clone", - "Compare", - "Contains", - "ContainsAny", - "ContainsFunc", - "ContainsRune", - "Count", - "Cut", - "CutPrefix", - "CutSuffix", - "Equal", - "EqualFold", - "ErrTooLarge", - "Fields", - "FieldsFunc", - "HasPrefix", - "HasSuffix", - "Index", - "IndexAny", - "IndexByte", - "IndexFunc", - "IndexRune", - "Join", - "LastIndex", - "LastIndexAny", - "LastIndexByte", - "LastIndexFunc", - "Map", - "MinRead", - "NewBuffer", - "NewBufferString", - "NewReader", - "Reader", - "Repeat", - "Replace", - "ReplaceAll", - "Runes", - "Split", - "SplitAfter", - "SplitAfterN", - "SplitN", - "Title", - "ToLower", - "ToLowerSpecial", - "ToTitle", - "ToTitleSpecial", - "ToUpper", - "ToUpperSpecial", - "ToValidUTF8", - "Trim", - "TrimFunc", - "TrimLeft", - "TrimLeftFunc", - "TrimPrefix", - "TrimRight", - "TrimRightFunc", - "TrimSpace", - "TrimSuffix", - }, - "cmp": { - "Compare", - "Less", - "Ordered", - }, - "compress/bzip2": { - "NewReader", - "StructuralError", - }, - "compress/flate": { - "BestCompression", - "BestSpeed", - "CorruptInputError", - "DefaultCompression", - "HuffmanOnly", - "InternalError", - "NewReader", - "NewReaderDict", - "NewWriter", - "NewWriterDict", - "NoCompression", - "ReadError", - "Reader", - "Resetter", - "WriteError", - "Writer", - }, - "compress/gzip": { - "BestCompression", - "BestSpeed", - "DefaultCompression", - "ErrChecksum", - "ErrHeader", - "Header", - "HuffmanOnly", - "NewReader", - "NewWriter", - "NewWriterLevel", - "NoCompression", - "Reader", - "Writer", - }, - "compress/lzw": { - "LSB", - "MSB", - "NewReader", - "NewWriter", - "Order", - "Reader", - "Writer", - }, - "compress/zlib": { - "BestCompression", - "BestSpeed", - "DefaultCompression", - "ErrChecksum", - "ErrDictionary", - "ErrHeader", - "HuffmanOnly", - "NewReader", - "NewReaderDict", - "NewWriter", - "NewWriterLevel", - "NewWriterLevelDict", - "NoCompression", - "Resetter", - "Writer", - }, - "container/heap": { - "Fix", - "Init", - "Interface", - "Pop", - "Push", - "Remove", - }, - "container/list": { - "Element", - "List", - "New", - }, - "container/ring": { - "New", - "Ring", - }, - "context": { - "AfterFunc", - "Background", - "CancelCauseFunc", - "CancelFunc", - "Canceled", - "Cause", - "Context", - "DeadlineExceeded", - "TODO", - "WithCancel", - "WithCancelCause", - "WithDeadline", - "WithDeadlineCause", - "WithTimeout", - "WithTimeoutCause", - "WithValue", - "WithoutCancel", - }, - "crypto": { - "BLAKE2b_256", - "BLAKE2b_384", - "BLAKE2b_512", - "BLAKE2s_256", - "Decrypter", - "DecrypterOpts", - "Hash", - "MD4", - "MD5", - "MD5SHA1", - "PrivateKey", - "PublicKey", - "RIPEMD160", - "RegisterHash", - "SHA1", - "SHA224", - "SHA256", - "SHA384", - "SHA3_224", - "SHA3_256", - "SHA3_384", - "SHA3_512", - "SHA512", - "SHA512_224", - "SHA512_256", - "Signer", - "SignerOpts", - }, - "crypto/aes": { - "BlockSize", - "KeySizeError", - "NewCipher", - }, - "crypto/cipher": { - "AEAD", - "Block", - "BlockMode", - "NewCBCDecrypter", - "NewCBCEncrypter", - "NewCFBDecrypter", - "NewCFBEncrypter", - "NewCTR", - "NewGCM", - "NewGCMWithNonceSize", - "NewGCMWithTagSize", - "NewOFB", - "Stream", - "StreamReader", - "StreamWriter", - }, - "crypto/des": { - "BlockSize", - "KeySizeError", - "NewCipher", - "NewTripleDESCipher", - }, - "crypto/dsa": { - "ErrInvalidPublicKey", - "GenerateKey", - "GenerateParameters", - "L1024N160", - "L2048N224", - "L2048N256", - "L3072N256", - "ParameterSizes", - "Parameters", - "PrivateKey", - "PublicKey", - "Sign", - "Verify", - }, - "crypto/ecdh": { - "Curve", - "P256", - "P384", - "P521", - "PrivateKey", - "PublicKey", - "X25519", - }, - "crypto/ecdsa": { - "GenerateKey", - "PrivateKey", - "PublicKey", - "Sign", - "SignASN1", - "Verify", - "VerifyASN1", - }, - "crypto/ed25519": { - "GenerateKey", - "NewKeyFromSeed", - "Options", - "PrivateKey", - "PrivateKeySize", - "PublicKey", - "PublicKeySize", - "SeedSize", - "Sign", - "SignatureSize", - "Verify", - "VerifyWithOptions", - }, - "crypto/elliptic": { - "Curve", - "CurveParams", - "GenerateKey", - "Marshal", - "MarshalCompressed", - "P224", - "P256", - "P384", - "P521", - "Unmarshal", - "UnmarshalCompressed", - }, - "crypto/hmac": { - "Equal", - "New", - }, - "crypto/md5": { - "BlockSize", - "New", - "Size", - "Sum", - }, - "crypto/rand": { - "Int", - "Prime", - "Read", - "Reader", - }, - "crypto/rc4": { - "Cipher", - "KeySizeError", - "NewCipher", - }, - "crypto/rsa": { - "CRTValue", - "DecryptOAEP", - "DecryptPKCS1v15", - "DecryptPKCS1v15SessionKey", - "EncryptOAEP", - "EncryptPKCS1v15", - "ErrDecryption", - "ErrMessageTooLong", - "ErrVerification", - "GenerateKey", - "GenerateMultiPrimeKey", - "OAEPOptions", - "PKCS1v15DecryptOptions", - "PSSOptions", - "PSSSaltLengthAuto", - "PSSSaltLengthEqualsHash", - "PrecomputedValues", - "PrivateKey", - "PublicKey", - "SignPKCS1v15", - "SignPSS", - "VerifyPKCS1v15", - "VerifyPSS", - }, - "crypto/sha1": { - "BlockSize", - "New", - "Size", - "Sum", - }, - "crypto/sha256": { - "BlockSize", - "New", - "New224", - "Size", - "Size224", - "Sum224", - "Sum256", - }, - "crypto/sha512": { - "BlockSize", - "New", - "New384", - "New512_224", - "New512_256", - "Size", - "Size224", - "Size256", - "Size384", - "Sum384", - "Sum512", - "Sum512_224", - "Sum512_256", - }, - "crypto/subtle": { - "ConstantTimeByteEq", - "ConstantTimeCompare", - "ConstantTimeCopy", - "ConstantTimeEq", - "ConstantTimeLessOrEq", - "ConstantTimeSelect", - "XORBytes", - }, - "crypto/tls": { - "AlertError", - "Certificate", - "CertificateRequestInfo", - "CertificateVerificationError", - "CipherSuite", - "CipherSuiteName", - "CipherSuites", - "Client", - "ClientAuthType", - "ClientHelloInfo", - "ClientSessionCache", - "ClientSessionState", - "Config", - "Conn", - "ConnectionState", - "CurveID", - "CurveP256", - "CurveP384", - "CurveP521", - "Dial", - "DialWithDialer", - "Dialer", - "ECDSAWithP256AndSHA256", - "ECDSAWithP384AndSHA384", - "ECDSAWithP521AndSHA512", - "ECDSAWithSHA1", - "Ed25519", - "InsecureCipherSuites", - "Listen", - "LoadX509KeyPair", - "NewLRUClientSessionCache", - "NewListener", - "NewResumptionState", - "NoClientCert", - "PKCS1WithSHA1", - "PKCS1WithSHA256", - "PKCS1WithSHA384", - "PKCS1WithSHA512", - "PSSWithSHA256", - "PSSWithSHA384", - "PSSWithSHA512", - "ParseSessionState", - "QUICClient", - "QUICConfig", - "QUICConn", - "QUICEncryptionLevel", - "QUICEncryptionLevelApplication", - "QUICEncryptionLevelEarly", - "QUICEncryptionLevelHandshake", - "QUICEncryptionLevelInitial", - "QUICEvent", - "QUICEventKind", - "QUICHandshakeDone", - "QUICNoEvent", - "QUICRejectedEarlyData", - "QUICServer", - "QUICSessionTicketOptions", - "QUICSetReadSecret", - "QUICSetWriteSecret", - "QUICTransportParameters", - "QUICTransportParametersRequired", - "QUICWriteData", - "RecordHeaderError", - "RenegotiateFreelyAsClient", - "RenegotiateNever", - "RenegotiateOnceAsClient", - "RenegotiationSupport", - "RequestClientCert", - "RequireAndVerifyClientCert", - "RequireAnyClientCert", - "Server", - "SessionState", - "SignatureScheme", - "TLS_AES_128_GCM_SHA256", - "TLS_AES_256_GCM_SHA384", - "TLS_CHACHA20_POLY1305_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", - "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", - "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - "TLS_ECDHE_RSA_WITH_RC4_128_SHA", - "TLS_FALLBACK_SCSV", - "TLS_RSA_WITH_3DES_EDE_CBC_SHA", - "TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_RC4_128_SHA", - "VerifyClientCertIfGiven", - "VersionName", - "VersionSSL30", - "VersionTLS10", - "VersionTLS11", - "VersionTLS12", - "VersionTLS13", - "X25519", - "X509KeyPair", - }, - "crypto/x509": { - "CANotAuthorizedForExtKeyUsage", - "CANotAuthorizedForThisName", - "CertPool", - "Certificate", - "CertificateInvalidError", - "CertificateRequest", - "ConstraintViolationError", - "CreateCertificate", - "CreateCertificateRequest", - "CreateRevocationList", - "DSA", - "DSAWithSHA1", - "DSAWithSHA256", - "DecryptPEMBlock", - "ECDSA", - "ECDSAWithSHA1", - "ECDSAWithSHA256", - "ECDSAWithSHA384", - "ECDSAWithSHA512", - "Ed25519", - "EncryptPEMBlock", - "ErrUnsupportedAlgorithm", - "Expired", - "ExtKeyUsage", - "ExtKeyUsageAny", - "ExtKeyUsageClientAuth", - "ExtKeyUsageCodeSigning", - "ExtKeyUsageEmailProtection", - "ExtKeyUsageIPSECEndSystem", - "ExtKeyUsageIPSECTunnel", - "ExtKeyUsageIPSECUser", - "ExtKeyUsageMicrosoftCommercialCodeSigning", - "ExtKeyUsageMicrosoftKernelCodeSigning", - "ExtKeyUsageMicrosoftServerGatedCrypto", - "ExtKeyUsageNetscapeServerGatedCrypto", - "ExtKeyUsageOCSPSigning", - "ExtKeyUsageServerAuth", - "ExtKeyUsageTimeStamping", - "HostnameError", - "IncompatibleUsage", - "IncorrectPasswordError", - "InsecureAlgorithmError", - "InvalidReason", - "IsEncryptedPEMBlock", - "KeyUsage", - "KeyUsageCRLSign", - "KeyUsageCertSign", - "KeyUsageContentCommitment", - "KeyUsageDataEncipherment", - "KeyUsageDecipherOnly", - "KeyUsageDigitalSignature", - "KeyUsageEncipherOnly", - "KeyUsageKeyAgreement", - "KeyUsageKeyEncipherment", - "MD2WithRSA", - "MD5WithRSA", - "MarshalECPrivateKey", - "MarshalPKCS1PrivateKey", - "MarshalPKCS1PublicKey", - "MarshalPKCS8PrivateKey", - "MarshalPKIXPublicKey", - "NameConstraintsWithoutSANs", - "NameMismatch", - "NewCertPool", - "NotAuthorizedToSign", - "PEMCipher", - "PEMCipher3DES", - "PEMCipherAES128", - "PEMCipherAES192", - "PEMCipherAES256", - "PEMCipherDES", - "ParseCRL", - "ParseCertificate", - "ParseCertificateRequest", - "ParseCertificates", - "ParseDERCRL", - "ParseECPrivateKey", - "ParsePKCS1PrivateKey", - "ParsePKCS1PublicKey", - "ParsePKCS8PrivateKey", - "ParsePKIXPublicKey", - "ParseRevocationList", - "PublicKeyAlgorithm", - "PureEd25519", - "RSA", - "RevocationList", - "RevocationListEntry", - "SHA1WithRSA", - "SHA256WithRSA", - "SHA256WithRSAPSS", - "SHA384WithRSA", - "SHA384WithRSAPSS", - "SHA512WithRSA", - "SHA512WithRSAPSS", - "SetFallbackRoots", - "SignatureAlgorithm", - "SystemCertPool", - "SystemRootsError", - "TooManyConstraints", - "TooManyIntermediates", - "UnconstrainedName", - "UnhandledCriticalExtension", - "UnknownAuthorityError", - "UnknownPublicKeyAlgorithm", - "UnknownSignatureAlgorithm", - "VerifyOptions", - }, - "crypto/x509/pkix": { - "AlgorithmIdentifier", - "AttributeTypeAndValue", - "AttributeTypeAndValueSET", - "CertificateList", - "Extension", - "Name", - "RDNSequence", - "RelativeDistinguishedNameSET", - "RevokedCertificate", - "TBSCertificateList", - }, - "database/sql": { - "ColumnType", - "Conn", - "DB", - "DBStats", - "Drivers", - "ErrConnDone", - "ErrNoRows", - "ErrTxDone", - "IsolationLevel", - "LevelDefault", - "LevelLinearizable", - "LevelReadCommitted", - "LevelReadUncommitted", - "LevelRepeatableRead", - "LevelSerializable", - "LevelSnapshot", - "LevelWriteCommitted", - "Named", - "NamedArg", - "NullBool", - "NullByte", - "NullFloat64", - "NullInt16", - "NullInt32", - "NullInt64", - "NullString", - "NullTime", - "Open", - "OpenDB", - "Out", - "RawBytes", - "Register", - "Result", - "Row", - "Rows", - "Scanner", - "Stmt", - "Tx", - "TxOptions", - }, - "database/sql/driver": { - "Bool", - "ColumnConverter", - "Conn", - "ConnBeginTx", - "ConnPrepareContext", - "Connector", - "DefaultParameterConverter", - "Driver", - "DriverContext", - "ErrBadConn", - "ErrRemoveArgument", - "ErrSkip", - "Execer", - "ExecerContext", - "Int32", - "IsScanValue", - "IsValue", - "IsolationLevel", - "NamedValue", - "NamedValueChecker", - "NotNull", - "Null", - "Pinger", - "Queryer", - "QueryerContext", - "Result", - "ResultNoRows", - "Rows", - "RowsAffected", - "RowsColumnTypeDatabaseTypeName", - "RowsColumnTypeLength", - "RowsColumnTypeNullable", - "RowsColumnTypePrecisionScale", - "RowsColumnTypeScanType", - "RowsNextResultSet", - "SessionResetter", - "Stmt", - "StmtExecContext", - "StmtQueryContext", - "String", - "Tx", - "TxOptions", - "Validator", - "Value", - "ValueConverter", - "Valuer", - }, - "debug/buildinfo": { - "BuildInfo", - "Read", - "ReadFile", - }, - "debug/dwarf": { - "AddrType", - "ArrayType", - "Attr", - "AttrAbstractOrigin", - "AttrAccessibility", - "AttrAddrBase", - "AttrAddrClass", - "AttrAlignment", - "AttrAllocated", - "AttrArtificial", - "AttrAssociated", - "AttrBaseTypes", - "AttrBinaryScale", - "AttrBitOffset", - "AttrBitSize", - "AttrByteSize", - "AttrCallAllCalls", - "AttrCallAllSourceCalls", - "AttrCallAllTailCalls", - "AttrCallColumn", - "AttrCallDataLocation", - "AttrCallDataValue", - "AttrCallFile", - "AttrCallLine", - "AttrCallOrigin", - "AttrCallPC", - "AttrCallParameter", - "AttrCallReturnPC", - "AttrCallTailCall", - "AttrCallTarget", - "AttrCallTargetClobbered", - "AttrCallValue", - "AttrCalling", - "AttrCommonRef", - "AttrCompDir", - "AttrConstExpr", - "AttrConstValue", - "AttrContainingType", - "AttrCount", - "AttrDataBitOffset", - "AttrDataLocation", - "AttrDataMemberLoc", - "AttrDecimalScale", - "AttrDecimalSign", - "AttrDeclColumn", - "AttrDeclFile", - "AttrDeclLine", - "AttrDeclaration", - "AttrDefaultValue", - "AttrDefaulted", - "AttrDeleted", - "AttrDescription", - "AttrDigitCount", - "AttrDiscr", - "AttrDiscrList", - "AttrDiscrValue", - "AttrDwoName", - "AttrElemental", - "AttrEncoding", - "AttrEndianity", - "AttrEntrypc", - "AttrEnumClass", - "AttrExplicit", - "AttrExportSymbols", - "AttrExtension", - "AttrExternal", - "AttrFrameBase", - "AttrFriend", - "AttrHighpc", - "AttrIdentifierCase", - "AttrImport", - "AttrInline", - "AttrIsOptional", - "AttrLanguage", - "AttrLinkageName", - "AttrLocation", - "AttrLoclistsBase", - "AttrLowerBound", - "AttrLowpc", - "AttrMacroInfo", - "AttrMacros", - "AttrMainSubprogram", - "AttrMutable", - "AttrName", - "AttrNamelistItem", - "AttrNoreturn", - "AttrObjectPointer", - "AttrOrdering", - "AttrPictureString", - "AttrPriority", - "AttrProducer", - "AttrPrototyped", - "AttrPure", - "AttrRanges", - "AttrRank", - "AttrRecursive", - "AttrReference", - "AttrReturnAddr", - "AttrRnglistsBase", - "AttrRvalueReference", - "AttrSegment", - "AttrSibling", - "AttrSignature", - "AttrSmall", - "AttrSpecification", - "AttrStartScope", - "AttrStaticLink", - "AttrStmtList", - "AttrStrOffsetsBase", - "AttrStride", - "AttrStrideSize", - "AttrStringLength", - "AttrStringLengthBitSize", - "AttrStringLengthByteSize", - "AttrThreadsScaled", - "AttrTrampoline", - "AttrType", - "AttrUpperBound", - "AttrUseLocation", - "AttrUseUTF8", - "AttrVarParam", - "AttrVirtuality", - "AttrVisibility", - "AttrVtableElemLoc", - "BasicType", - "BoolType", - "CharType", - "Class", - "ClassAddrPtr", - "ClassAddress", - "ClassBlock", - "ClassConstant", - "ClassExprLoc", - "ClassFlag", - "ClassLinePtr", - "ClassLocList", - "ClassLocListPtr", - "ClassMacPtr", - "ClassRangeListPtr", - "ClassReference", - "ClassReferenceAlt", - "ClassReferenceSig", - "ClassRngList", - "ClassRngListsPtr", - "ClassStrOffsetsPtr", - "ClassString", - "ClassStringAlt", - "ClassUnknown", - "CommonType", - "ComplexType", - "Data", - "DecodeError", - "DotDotDotType", - "Entry", - "EnumType", - "EnumValue", - "ErrUnknownPC", - "Field", - "FloatType", - "FuncType", - "IntType", - "LineEntry", - "LineFile", - "LineReader", - "LineReaderPos", - "New", - "Offset", - "PtrType", - "QualType", - "Reader", - "StructField", - "StructType", - "Tag", - "TagAccessDeclaration", - "TagArrayType", - "TagAtomicType", - "TagBaseType", - "TagCallSite", - "TagCallSiteParameter", - "TagCatchDwarfBlock", - "TagClassType", - "TagCoarrayType", - "TagCommonDwarfBlock", - "TagCommonInclusion", - "TagCompileUnit", - "TagCondition", - "TagConstType", - "TagConstant", - "TagDwarfProcedure", - "TagDynamicType", - "TagEntryPoint", - "TagEnumerationType", - "TagEnumerator", - "TagFileType", - "TagFormalParameter", - "TagFriend", - "TagGenericSubrange", - "TagImmutableType", - "TagImportedDeclaration", - "TagImportedModule", - "TagImportedUnit", - "TagInheritance", - "TagInlinedSubroutine", - "TagInterfaceType", - "TagLabel", - "TagLexDwarfBlock", - "TagMember", - "TagModule", - "TagMutableType", - "TagNamelist", - "TagNamelistItem", - "TagNamespace", - "TagPackedType", - "TagPartialUnit", - "TagPointerType", - "TagPtrToMemberType", - "TagReferenceType", - "TagRestrictType", - "TagRvalueReferenceType", - "TagSetType", - "TagSharedType", - "TagSkeletonUnit", - "TagStringType", - "TagStructType", - "TagSubprogram", - "TagSubrangeType", - "TagSubroutineType", - "TagTemplateAlias", - "TagTemplateTypeParameter", - "TagTemplateValueParameter", - "TagThrownType", - "TagTryDwarfBlock", - "TagTypeUnit", - "TagTypedef", - "TagUnionType", - "TagUnspecifiedParameters", - "TagUnspecifiedType", - "TagVariable", - "TagVariant", - "TagVariantPart", - "TagVolatileType", - "TagWithStmt", - "Type", - "TypedefType", - "UcharType", - "UintType", - "UnspecifiedType", - "UnsupportedType", - "VoidType", - }, - "debug/elf": { - "ARM_MAGIC_TRAMP_NUMBER", - "COMPRESS_HIOS", - "COMPRESS_HIPROC", - "COMPRESS_LOOS", - "COMPRESS_LOPROC", - "COMPRESS_ZLIB", - "COMPRESS_ZSTD", - "Chdr32", - "Chdr64", - "Class", - "CompressionType", - "DF_1_CONFALT", - "DF_1_DIRECT", - "DF_1_DISPRELDNE", - "DF_1_DISPRELPND", - "DF_1_EDITED", - "DF_1_ENDFILTEE", - "DF_1_GLOBAL", - "DF_1_GLOBAUDIT", - "DF_1_GROUP", - "DF_1_IGNMULDEF", - "DF_1_INITFIRST", - "DF_1_INTERPOSE", - "DF_1_KMOD", - "DF_1_LOADFLTR", - "DF_1_NOCOMMON", - "DF_1_NODEFLIB", - "DF_1_NODELETE", - "DF_1_NODIRECT", - "DF_1_NODUMP", - "DF_1_NOHDR", - "DF_1_NOKSYMS", - "DF_1_NOOPEN", - "DF_1_NORELOC", - "DF_1_NOW", - "DF_1_ORIGIN", - "DF_1_PIE", - "DF_1_SINGLETON", - "DF_1_STUB", - "DF_1_SYMINTPOSE", - "DF_1_TRANS", - "DF_1_WEAKFILTER", - "DF_BIND_NOW", - "DF_ORIGIN", - "DF_STATIC_TLS", - "DF_SYMBOLIC", - "DF_TEXTREL", - "DT_ADDRRNGHI", - "DT_ADDRRNGLO", - "DT_AUDIT", - "DT_AUXILIARY", - "DT_BIND_NOW", - "DT_CHECKSUM", - "DT_CONFIG", - "DT_DEBUG", - "DT_DEPAUDIT", - "DT_ENCODING", - "DT_FEATURE", - "DT_FILTER", - "DT_FINI", - "DT_FINI_ARRAY", - "DT_FINI_ARRAYSZ", - "DT_FLAGS", - "DT_FLAGS_1", - "DT_GNU_CONFLICT", - "DT_GNU_CONFLICTSZ", - "DT_GNU_HASH", - "DT_GNU_LIBLIST", - "DT_GNU_LIBLISTSZ", - "DT_GNU_PRELINKED", - "DT_HASH", - "DT_HIOS", - "DT_HIPROC", - "DT_INIT", - "DT_INIT_ARRAY", - "DT_INIT_ARRAYSZ", - "DT_JMPREL", - "DT_LOOS", - "DT_LOPROC", - "DT_MIPS_AUX_DYNAMIC", - "DT_MIPS_BASE_ADDRESS", - "DT_MIPS_COMPACT_SIZE", - "DT_MIPS_CONFLICT", - "DT_MIPS_CONFLICTNO", - "DT_MIPS_CXX_FLAGS", - "DT_MIPS_DELTA_CLASS", - "DT_MIPS_DELTA_CLASSSYM", - "DT_MIPS_DELTA_CLASSSYM_NO", - "DT_MIPS_DELTA_CLASS_NO", - "DT_MIPS_DELTA_INSTANCE", - "DT_MIPS_DELTA_INSTANCE_NO", - "DT_MIPS_DELTA_RELOC", - "DT_MIPS_DELTA_RELOC_NO", - "DT_MIPS_DELTA_SYM", - "DT_MIPS_DELTA_SYM_NO", - "DT_MIPS_DYNSTR_ALIGN", - "DT_MIPS_FLAGS", - "DT_MIPS_GOTSYM", - "DT_MIPS_GP_VALUE", - "DT_MIPS_HIDDEN_GOTIDX", - "DT_MIPS_HIPAGENO", - "DT_MIPS_ICHECKSUM", - "DT_MIPS_INTERFACE", - "DT_MIPS_INTERFACE_SIZE", - "DT_MIPS_IVERSION", - "DT_MIPS_LIBLIST", - "DT_MIPS_LIBLISTNO", - "DT_MIPS_LOCALPAGE_GOTIDX", - "DT_MIPS_LOCAL_GOTIDX", - "DT_MIPS_LOCAL_GOTNO", - "DT_MIPS_MSYM", - "DT_MIPS_OPTIONS", - "DT_MIPS_PERF_SUFFIX", - "DT_MIPS_PIXIE_INIT", - "DT_MIPS_PLTGOT", - "DT_MIPS_PROTECTED_GOTIDX", - "DT_MIPS_RLD_MAP", - "DT_MIPS_RLD_MAP_REL", - "DT_MIPS_RLD_TEXT_RESOLVE_ADDR", - "DT_MIPS_RLD_VERSION", - "DT_MIPS_RWPLT", - "DT_MIPS_SYMBOL_LIB", - "DT_MIPS_SYMTABNO", - "DT_MIPS_TIME_STAMP", - "DT_MIPS_UNREFEXTNO", - "DT_MOVEENT", - "DT_MOVESZ", - "DT_MOVETAB", - "DT_NEEDED", - "DT_NULL", - "DT_PLTGOT", - "DT_PLTPAD", - "DT_PLTPADSZ", - "DT_PLTREL", - "DT_PLTRELSZ", - "DT_POSFLAG_1", - "DT_PPC64_GLINK", - "DT_PPC64_OPD", - "DT_PPC64_OPDSZ", - "DT_PPC64_OPT", - "DT_PPC_GOT", - "DT_PPC_OPT", - "DT_PREINIT_ARRAY", - "DT_PREINIT_ARRAYSZ", - "DT_REL", - "DT_RELA", - "DT_RELACOUNT", - "DT_RELAENT", - "DT_RELASZ", - "DT_RELCOUNT", - "DT_RELENT", - "DT_RELSZ", - "DT_RPATH", - "DT_RUNPATH", - "DT_SONAME", - "DT_SPARC_REGISTER", - "DT_STRSZ", - "DT_STRTAB", - "DT_SYMBOLIC", - "DT_SYMENT", - "DT_SYMINENT", - "DT_SYMINFO", - "DT_SYMINSZ", - "DT_SYMTAB", - "DT_SYMTAB_SHNDX", - "DT_TEXTREL", - "DT_TLSDESC_GOT", - "DT_TLSDESC_PLT", - "DT_USED", - "DT_VALRNGHI", - "DT_VALRNGLO", - "DT_VERDEF", - "DT_VERDEFNUM", - "DT_VERNEED", - "DT_VERNEEDNUM", - "DT_VERSYM", - "Data", - "Dyn32", - "Dyn64", - "DynFlag", - "DynFlag1", - "DynTag", - "EI_ABIVERSION", - "EI_CLASS", - "EI_DATA", - "EI_NIDENT", - "EI_OSABI", - "EI_PAD", - "EI_VERSION", - "ELFCLASS32", - "ELFCLASS64", - "ELFCLASSNONE", - "ELFDATA2LSB", - "ELFDATA2MSB", - "ELFDATANONE", - "ELFMAG", - "ELFOSABI_86OPEN", - "ELFOSABI_AIX", - "ELFOSABI_ARM", - "ELFOSABI_AROS", - "ELFOSABI_CLOUDABI", - "ELFOSABI_FENIXOS", - "ELFOSABI_FREEBSD", - "ELFOSABI_HPUX", - "ELFOSABI_HURD", - "ELFOSABI_IRIX", - "ELFOSABI_LINUX", - "ELFOSABI_MODESTO", - "ELFOSABI_NETBSD", - "ELFOSABI_NONE", - "ELFOSABI_NSK", - "ELFOSABI_OPENBSD", - "ELFOSABI_OPENVMS", - "ELFOSABI_SOLARIS", - "ELFOSABI_STANDALONE", - "ELFOSABI_TRU64", - "EM_386", - "EM_486", - "EM_56800EX", - "EM_68HC05", - "EM_68HC08", - "EM_68HC11", - "EM_68HC12", - "EM_68HC16", - "EM_68K", - "EM_78KOR", - "EM_8051", - "EM_860", - "EM_88K", - "EM_960", - "EM_AARCH64", - "EM_ALPHA", - "EM_ALPHA_STD", - "EM_ALTERA_NIOS2", - "EM_AMDGPU", - "EM_ARC", - "EM_ARCA", - "EM_ARC_COMPACT", - "EM_ARC_COMPACT2", - "EM_ARM", - "EM_AVR", - "EM_AVR32", - "EM_BA1", - "EM_BA2", - "EM_BLACKFIN", - "EM_BPF", - "EM_C166", - "EM_CDP", - "EM_CE", - "EM_CLOUDSHIELD", - "EM_COGE", - "EM_COLDFIRE", - "EM_COOL", - "EM_COREA_1ST", - "EM_COREA_2ND", - "EM_CR", - "EM_CR16", - "EM_CRAYNV2", - "EM_CRIS", - "EM_CRX", - "EM_CSR_KALIMBA", - "EM_CUDA", - "EM_CYPRESS_M8C", - "EM_D10V", - "EM_D30V", - "EM_DSP24", - "EM_DSPIC30F", - "EM_DXP", - "EM_ECOG1", - "EM_ECOG16", - "EM_ECOG1X", - "EM_ECOG2", - "EM_ETPU", - "EM_EXCESS", - "EM_F2MC16", - "EM_FIREPATH", - "EM_FR20", - "EM_FR30", - "EM_FT32", - "EM_FX66", - "EM_H8S", - "EM_H8_300", - "EM_H8_300H", - "EM_H8_500", - "EM_HUANY", - "EM_IA_64", - "EM_INTEL205", - "EM_INTEL206", - "EM_INTEL207", - "EM_INTEL208", - "EM_INTEL209", - "EM_IP2K", - "EM_JAVELIN", - "EM_K10M", - "EM_KM32", - "EM_KMX16", - "EM_KMX32", - "EM_KMX8", - "EM_KVARC", - "EM_L10M", - "EM_LANAI", - "EM_LATTICEMICO32", - "EM_LOONGARCH", - "EM_M16C", - "EM_M32", - "EM_M32C", - "EM_M32R", - "EM_MANIK", - "EM_MAX", - "EM_MAXQ30", - "EM_MCHP_PIC", - "EM_MCST_ELBRUS", - "EM_ME16", - "EM_METAG", - "EM_MICROBLAZE", - "EM_MIPS", - "EM_MIPS_RS3_LE", - "EM_MIPS_RS4_BE", - "EM_MIPS_X", - "EM_MMA", - "EM_MMDSP_PLUS", - "EM_MMIX", - "EM_MN10200", - "EM_MN10300", - "EM_MOXIE", - "EM_MSP430", - "EM_NCPU", - "EM_NDR1", - "EM_NDS32", - "EM_NONE", - "EM_NORC", - "EM_NS32K", - "EM_OPEN8", - "EM_OPENRISC", - "EM_PARISC", - "EM_PCP", - "EM_PDP10", - "EM_PDP11", - "EM_PDSP", - "EM_PJ", - "EM_PPC", - "EM_PPC64", - "EM_PRISM", - "EM_QDSP6", - "EM_R32C", - "EM_RCE", - "EM_RH32", - "EM_RISCV", - "EM_RL78", - "EM_RS08", - "EM_RX", - "EM_S370", - "EM_S390", - "EM_SCORE7", - "EM_SEP", - "EM_SE_C17", - "EM_SE_C33", - "EM_SH", - "EM_SHARC", - "EM_SLE9X", - "EM_SNP1K", - "EM_SPARC", - "EM_SPARC32PLUS", - "EM_SPARCV9", - "EM_ST100", - "EM_ST19", - "EM_ST200", - "EM_ST7", - "EM_ST9PLUS", - "EM_STARCORE", - "EM_STM8", - "EM_STXP7X", - "EM_SVX", - "EM_TILE64", - "EM_TILEGX", - "EM_TILEPRO", - "EM_TINYJ", - "EM_TI_ARP32", - "EM_TI_C2000", - "EM_TI_C5500", - "EM_TI_C6000", - "EM_TI_PRU", - "EM_TMM_GPP", - "EM_TPC", - "EM_TRICORE", - "EM_TRIMEDIA", - "EM_TSK3000", - "EM_UNICORE", - "EM_V800", - "EM_V850", - "EM_VAX", - "EM_VIDEOCORE", - "EM_VIDEOCORE3", - "EM_VIDEOCORE5", - "EM_VISIUM", - "EM_VPP500", - "EM_X86_64", - "EM_XCORE", - "EM_XGATE", - "EM_XIMO16", - "EM_XTENSA", - "EM_Z80", - "EM_ZSP", - "ET_CORE", - "ET_DYN", - "ET_EXEC", - "ET_HIOS", - "ET_HIPROC", - "ET_LOOS", - "ET_LOPROC", - "ET_NONE", - "ET_REL", - "EV_CURRENT", - "EV_NONE", - "ErrNoSymbols", - "File", - "FileHeader", - "FormatError", - "Header32", - "Header64", - "ImportedSymbol", - "Machine", - "NT_FPREGSET", - "NT_PRPSINFO", - "NT_PRSTATUS", - "NType", - "NewFile", - "OSABI", - "Open", - "PF_MASKOS", - "PF_MASKPROC", - "PF_R", - "PF_W", - "PF_X", - "PT_AARCH64_ARCHEXT", - "PT_AARCH64_UNWIND", - "PT_ARM_ARCHEXT", - "PT_ARM_EXIDX", - "PT_DYNAMIC", - "PT_GNU_EH_FRAME", - "PT_GNU_MBIND_HI", - "PT_GNU_MBIND_LO", - "PT_GNU_PROPERTY", - "PT_GNU_RELRO", - "PT_GNU_STACK", - "PT_HIOS", - "PT_HIPROC", - "PT_INTERP", - "PT_LOAD", - "PT_LOOS", - "PT_LOPROC", - "PT_MIPS_ABIFLAGS", - "PT_MIPS_OPTIONS", - "PT_MIPS_REGINFO", - "PT_MIPS_RTPROC", - "PT_NOTE", - "PT_NULL", - "PT_OPENBSD_BOOTDATA", - "PT_OPENBSD_RANDOMIZE", - "PT_OPENBSD_WXNEEDED", - "PT_PAX_FLAGS", - "PT_PHDR", - "PT_S390_PGSTE", - "PT_SHLIB", - "PT_SUNWSTACK", - "PT_SUNW_EH_FRAME", - "PT_TLS", - "Prog", - "Prog32", - "Prog64", - "ProgFlag", - "ProgHeader", - "ProgType", - "R_386", - "R_386_16", - "R_386_32", - "R_386_32PLT", - "R_386_8", - "R_386_COPY", - "R_386_GLOB_DAT", - "R_386_GOT32", - "R_386_GOT32X", - "R_386_GOTOFF", - "R_386_GOTPC", - "R_386_IRELATIVE", - "R_386_JMP_SLOT", - "R_386_NONE", - "R_386_PC16", - "R_386_PC32", - "R_386_PC8", - "R_386_PLT32", - "R_386_RELATIVE", - "R_386_SIZE32", - "R_386_TLS_DESC", - "R_386_TLS_DESC_CALL", - "R_386_TLS_DTPMOD32", - "R_386_TLS_DTPOFF32", - "R_386_TLS_GD", - "R_386_TLS_GD_32", - "R_386_TLS_GD_CALL", - "R_386_TLS_GD_POP", - "R_386_TLS_GD_PUSH", - "R_386_TLS_GOTDESC", - "R_386_TLS_GOTIE", - "R_386_TLS_IE", - "R_386_TLS_IE_32", - "R_386_TLS_LDM", - "R_386_TLS_LDM_32", - "R_386_TLS_LDM_CALL", - "R_386_TLS_LDM_POP", - "R_386_TLS_LDM_PUSH", - "R_386_TLS_LDO_32", - "R_386_TLS_LE", - "R_386_TLS_LE_32", - "R_386_TLS_TPOFF", - "R_386_TLS_TPOFF32", - "R_390", - "R_390_12", - "R_390_16", - "R_390_20", - "R_390_32", - "R_390_64", - "R_390_8", - "R_390_COPY", - "R_390_GLOB_DAT", - "R_390_GOT12", - "R_390_GOT16", - "R_390_GOT20", - "R_390_GOT32", - "R_390_GOT64", - "R_390_GOTENT", - "R_390_GOTOFF", - "R_390_GOTOFF16", - "R_390_GOTOFF64", - "R_390_GOTPC", - "R_390_GOTPCDBL", - "R_390_GOTPLT12", - "R_390_GOTPLT16", - "R_390_GOTPLT20", - "R_390_GOTPLT32", - "R_390_GOTPLT64", - "R_390_GOTPLTENT", - "R_390_GOTPLTOFF16", - "R_390_GOTPLTOFF32", - "R_390_GOTPLTOFF64", - "R_390_JMP_SLOT", - "R_390_NONE", - "R_390_PC16", - "R_390_PC16DBL", - "R_390_PC32", - "R_390_PC32DBL", - "R_390_PC64", - "R_390_PLT16DBL", - "R_390_PLT32", - "R_390_PLT32DBL", - "R_390_PLT64", - "R_390_RELATIVE", - "R_390_TLS_DTPMOD", - "R_390_TLS_DTPOFF", - "R_390_TLS_GD32", - "R_390_TLS_GD64", - "R_390_TLS_GDCALL", - "R_390_TLS_GOTIE12", - "R_390_TLS_GOTIE20", - "R_390_TLS_GOTIE32", - "R_390_TLS_GOTIE64", - "R_390_TLS_IE32", - "R_390_TLS_IE64", - "R_390_TLS_IEENT", - "R_390_TLS_LDCALL", - "R_390_TLS_LDM32", - "R_390_TLS_LDM64", - "R_390_TLS_LDO32", - "R_390_TLS_LDO64", - "R_390_TLS_LE32", - "R_390_TLS_LE64", - "R_390_TLS_LOAD", - "R_390_TLS_TPOFF", - "R_AARCH64", - "R_AARCH64_ABS16", - "R_AARCH64_ABS32", - "R_AARCH64_ABS64", - "R_AARCH64_ADD_ABS_LO12_NC", - "R_AARCH64_ADR_GOT_PAGE", - "R_AARCH64_ADR_PREL_LO21", - "R_AARCH64_ADR_PREL_PG_HI21", - "R_AARCH64_ADR_PREL_PG_HI21_NC", - "R_AARCH64_CALL26", - "R_AARCH64_CONDBR19", - "R_AARCH64_COPY", - "R_AARCH64_GLOB_DAT", - "R_AARCH64_GOT_LD_PREL19", - "R_AARCH64_IRELATIVE", - "R_AARCH64_JUMP26", - "R_AARCH64_JUMP_SLOT", - "R_AARCH64_LD64_GOTOFF_LO15", - "R_AARCH64_LD64_GOTPAGE_LO15", - "R_AARCH64_LD64_GOT_LO12_NC", - "R_AARCH64_LDST128_ABS_LO12_NC", - "R_AARCH64_LDST16_ABS_LO12_NC", - "R_AARCH64_LDST32_ABS_LO12_NC", - "R_AARCH64_LDST64_ABS_LO12_NC", - "R_AARCH64_LDST8_ABS_LO12_NC", - "R_AARCH64_LD_PREL_LO19", - "R_AARCH64_MOVW_SABS_G0", - "R_AARCH64_MOVW_SABS_G1", - "R_AARCH64_MOVW_SABS_G2", - "R_AARCH64_MOVW_UABS_G0", - "R_AARCH64_MOVW_UABS_G0_NC", - "R_AARCH64_MOVW_UABS_G1", - "R_AARCH64_MOVW_UABS_G1_NC", - "R_AARCH64_MOVW_UABS_G2", - "R_AARCH64_MOVW_UABS_G2_NC", - "R_AARCH64_MOVW_UABS_G3", - "R_AARCH64_NONE", - "R_AARCH64_NULL", - "R_AARCH64_P32_ABS16", - "R_AARCH64_P32_ABS32", - "R_AARCH64_P32_ADD_ABS_LO12_NC", - "R_AARCH64_P32_ADR_GOT_PAGE", - "R_AARCH64_P32_ADR_PREL_LO21", - "R_AARCH64_P32_ADR_PREL_PG_HI21", - "R_AARCH64_P32_CALL26", - "R_AARCH64_P32_CONDBR19", - "R_AARCH64_P32_COPY", - "R_AARCH64_P32_GLOB_DAT", - "R_AARCH64_P32_GOT_LD_PREL19", - "R_AARCH64_P32_IRELATIVE", - "R_AARCH64_P32_JUMP26", - "R_AARCH64_P32_JUMP_SLOT", - "R_AARCH64_P32_LD32_GOT_LO12_NC", - "R_AARCH64_P32_LDST128_ABS_LO12_NC", - "R_AARCH64_P32_LDST16_ABS_LO12_NC", - "R_AARCH64_P32_LDST32_ABS_LO12_NC", - "R_AARCH64_P32_LDST64_ABS_LO12_NC", - "R_AARCH64_P32_LDST8_ABS_LO12_NC", - "R_AARCH64_P32_LD_PREL_LO19", - "R_AARCH64_P32_MOVW_SABS_G0", - "R_AARCH64_P32_MOVW_UABS_G0", - "R_AARCH64_P32_MOVW_UABS_G0_NC", - "R_AARCH64_P32_MOVW_UABS_G1", - "R_AARCH64_P32_PREL16", - "R_AARCH64_P32_PREL32", - "R_AARCH64_P32_RELATIVE", - "R_AARCH64_P32_TLSDESC", - "R_AARCH64_P32_TLSDESC_ADD_LO12_NC", - "R_AARCH64_P32_TLSDESC_ADR_PAGE21", - "R_AARCH64_P32_TLSDESC_ADR_PREL21", - "R_AARCH64_P32_TLSDESC_CALL", - "R_AARCH64_P32_TLSDESC_LD32_LO12_NC", - "R_AARCH64_P32_TLSDESC_LD_PREL19", - "R_AARCH64_P32_TLSGD_ADD_LO12_NC", - "R_AARCH64_P32_TLSGD_ADR_PAGE21", - "R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21", - "R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC", - "R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19", - "R_AARCH64_P32_TLSLE_ADD_TPREL_HI12", - "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12", - "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC", - "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0", - "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC", - "R_AARCH64_P32_TLSLE_MOVW_TPREL_G1", - "R_AARCH64_P32_TLS_DTPMOD", - "R_AARCH64_P32_TLS_DTPREL", - "R_AARCH64_P32_TLS_TPREL", - "R_AARCH64_P32_TSTBR14", - "R_AARCH64_PREL16", - "R_AARCH64_PREL32", - "R_AARCH64_PREL64", - "R_AARCH64_RELATIVE", - "R_AARCH64_TLSDESC", - "R_AARCH64_TLSDESC_ADD", - "R_AARCH64_TLSDESC_ADD_LO12_NC", - "R_AARCH64_TLSDESC_ADR_PAGE21", - "R_AARCH64_TLSDESC_ADR_PREL21", - "R_AARCH64_TLSDESC_CALL", - "R_AARCH64_TLSDESC_LD64_LO12_NC", - "R_AARCH64_TLSDESC_LDR", - "R_AARCH64_TLSDESC_LD_PREL19", - "R_AARCH64_TLSDESC_OFF_G0_NC", - "R_AARCH64_TLSDESC_OFF_G1", - "R_AARCH64_TLSGD_ADD_LO12_NC", - "R_AARCH64_TLSGD_ADR_PAGE21", - "R_AARCH64_TLSGD_ADR_PREL21", - "R_AARCH64_TLSGD_MOVW_G0_NC", - "R_AARCH64_TLSGD_MOVW_G1", - "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21", - "R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", - "R_AARCH64_TLSIE_LD_GOTTPREL_PREL19", - "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC", - "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1", - "R_AARCH64_TLSLD_ADR_PAGE21", - "R_AARCH64_TLSLD_ADR_PREL21", - "R_AARCH64_TLSLD_LDST128_DTPREL_LO12", - "R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC", - "R_AARCH64_TLSLE_ADD_TPREL_HI12", - "R_AARCH64_TLSLE_ADD_TPREL_LO12", - "R_AARCH64_TLSLE_ADD_TPREL_LO12_NC", - "R_AARCH64_TLSLE_LDST128_TPREL_LO12", - "R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC", - "R_AARCH64_TLSLE_MOVW_TPREL_G0", - "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC", - "R_AARCH64_TLSLE_MOVW_TPREL_G1", - "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC", - "R_AARCH64_TLSLE_MOVW_TPREL_G2", - "R_AARCH64_TLS_DTPMOD64", - "R_AARCH64_TLS_DTPREL64", - "R_AARCH64_TLS_TPREL64", - "R_AARCH64_TSTBR14", - "R_ALPHA", - "R_ALPHA_BRADDR", - "R_ALPHA_COPY", - "R_ALPHA_GLOB_DAT", - "R_ALPHA_GPDISP", - "R_ALPHA_GPREL32", - "R_ALPHA_GPRELHIGH", - "R_ALPHA_GPRELLOW", - "R_ALPHA_GPVALUE", - "R_ALPHA_HINT", - "R_ALPHA_IMMED_BR_HI32", - "R_ALPHA_IMMED_GP_16", - "R_ALPHA_IMMED_GP_HI32", - "R_ALPHA_IMMED_LO32", - "R_ALPHA_IMMED_SCN_HI32", - "R_ALPHA_JMP_SLOT", - "R_ALPHA_LITERAL", - "R_ALPHA_LITUSE", - "R_ALPHA_NONE", - "R_ALPHA_OP_PRSHIFT", - "R_ALPHA_OP_PSUB", - "R_ALPHA_OP_PUSH", - "R_ALPHA_OP_STORE", - "R_ALPHA_REFLONG", - "R_ALPHA_REFQUAD", - "R_ALPHA_RELATIVE", - "R_ALPHA_SREL16", - "R_ALPHA_SREL32", - "R_ALPHA_SREL64", - "R_ARM", - "R_ARM_ABS12", - "R_ARM_ABS16", - "R_ARM_ABS32", - "R_ARM_ABS32_NOI", - "R_ARM_ABS8", - "R_ARM_ALU_PCREL_15_8", - "R_ARM_ALU_PCREL_23_15", - "R_ARM_ALU_PCREL_7_0", - "R_ARM_ALU_PC_G0", - "R_ARM_ALU_PC_G0_NC", - "R_ARM_ALU_PC_G1", - "R_ARM_ALU_PC_G1_NC", - "R_ARM_ALU_PC_G2", - "R_ARM_ALU_SBREL_19_12_NC", - "R_ARM_ALU_SBREL_27_20_CK", - "R_ARM_ALU_SB_G0", - "R_ARM_ALU_SB_G0_NC", - "R_ARM_ALU_SB_G1", - "R_ARM_ALU_SB_G1_NC", - "R_ARM_ALU_SB_G2", - "R_ARM_AMP_VCALL9", - "R_ARM_BASE_ABS", - "R_ARM_CALL", - "R_ARM_COPY", - "R_ARM_GLOB_DAT", - "R_ARM_GNU_VTENTRY", - "R_ARM_GNU_VTINHERIT", - "R_ARM_GOT32", - "R_ARM_GOTOFF", - "R_ARM_GOTOFF12", - "R_ARM_GOTPC", - "R_ARM_GOTRELAX", - "R_ARM_GOT_ABS", - "R_ARM_GOT_BREL12", - "R_ARM_GOT_PREL", - "R_ARM_IRELATIVE", - "R_ARM_JUMP24", - "R_ARM_JUMP_SLOT", - "R_ARM_LDC_PC_G0", - "R_ARM_LDC_PC_G1", - "R_ARM_LDC_PC_G2", - "R_ARM_LDC_SB_G0", - "R_ARM_LDC_SB_G1", - "R_ARM_LDC_SB_G2", - "R_ARM_LDRS_PC_G0", - "R_ARM_LDRS_PC_G1", - "R_ARM_LDRS_PC_G2", - "R_ARM_LDRS_SB_G0", - "R_ARM_LDRS_SB_G1", - "R_ARM_LDRS_SB_G2", - "R_ARM_LDR_PC_G1", - "R_ARM_LDR_PC_G2", - "R_ARM_LDR_SBREL_11_10_NC", - "R_ARM_LDR_SB_G0", - "R_ARM_LDR_SB_G1", - "R_ARM_LDR_SB_G2", - "R_ARM_ME_TOO", - "R_ARM_MOVT_ABS", - "R_ARM_MOVT_BREL", - "R_ARM_MOVT_PREL", - "R_ARM_MOVW_ABS_NC", - "R_ARM_MOVW_BREL", - "R_ARM_MOVW_BREL_NC", - "R_ARM_MOVW_PREL_NC", - "R_ARM_NONE", - "R_ARM_PC13", - "R_ARM_PC24", - "R_ARM_PLT32", - "R_ARM_PLT32_ABS", - "R_ARM_PREL31", - "R_ARM_PRIVATE_0", - "R_ARM_PRIVATE_1", - "R_ARM_PRIVATE_10", - "R_ARM_PRIVATE_11", - "R_ARM_PRIVATE_12", - "R_ARM_PRIVATE_13", - "R_ARM_PRIVATE_14", - "R_ARM_PRIVATE_15", - "R_ARM_PRIVATE_2", - "R_ARM_PRIVATE_3", - "R_ARM_PRIVATE_4", - "R_ARM_PRIVATE_5", - "R_ARM_PRIVATE_6", - "R_ARM_PRIVATE_7", - "R_ARM_PRIVATE_8", - "R_ARM_PRIVATE_9", - "R_ARM_RABS32", - "R_ARM_RBASE", - "R_ARM_REL32", - "R_ARM_REL32_NOI", - "R_ARM_RELATIVE", - "R_ARM_RPC24", - "R_ARM_RREL32", - "R_ARM_RSBREL32", - "R_ARM_RXPC25", - "R_ARM_SBREL31", - "R_ARM_SBREL32", - "R_ARM_SWI24", - "R_ARM_TARGET1", - "R_ARM_TARGET2", - "R_ARM_THM_ABS5", - "R_ARM_THM_ALU_ABS_G0_NC", - "R_ARM_THM_ALU_ABS_G1_NC", - "R_ARM_THM_ALU_ABS_G2_NC", - "R_ARM_THM_ALU_ABS_G3", - "R_ARM_THM_ALU_PREL_11_0", - "R_ARM_THM_GOT_BREL12", - "R_ARM_THM_JUMP11", - "R_ARM_THM_JUMP19", - "R_ARM_THM_JUMP24", - "R_ARM_THM_JUMP6", - "R_ARM_THM_JUMP8", - "R_ARM_THM_MOVT_ABS", - "R_ARM_THM_MOVT_BREL", - "R_ARM_THM_MOVT_PREL", - "R_ARM_THM_MOVW_ABS_NC", - "R_ARM_THM_MOVW_BREL", - "R_ARM_THM_MOVW_BREL_NC", - "R_ARM_THM_MOVW_PREL_NC", - "R_ARM_THM_PC12", - "R_ARM_THM_PC22", - "R_ARM_THM_PC8", - "R_ARM_THM_RPC22", - "R_ARM_THM_SWI8", - "R_ARM_THM_TLS_CALL", - "R_ARM_THM_TLS_DESCSEQ16", - "R_ARM_THM_TLS_DESCSEQ32", - "R_ARM_THM_XPC22", - "R_ARM_TLS_CALL", - "R_ARM_TLS_DESCSEQ", - "R_ARM_TLS_DTPMOD32", - "R_ARM_TLS_DTPOFF32", - "R_ARM_TLS_GD32", - "R_ARM_TLS_GOTDESC", - "R_ARM_TLS_IE12GP", - "R_ARM_TLS_IE32", - "R_ARM_TLS_LDM32", - "R_ARM_TLS_LDO12", - "R_ARM_TLS_LDO32", - "R_ARM_TLS_LE12", - "R_ARM_TLS_LE32", - "R_ARM_TLS_TPOFF32", - "R_ARM_V4BX", - "R_ARM_XPC25", - "R_INFO", - "R_INFO32", - "R_LARCH", - "R_LARCH_32", - "R_LARCH_32_PCREL", - "R_LARCH_64", - "R_LARCH_ABS64_HI12", - "R_LARCH_ABS64_LO20", - "R_LARCH_ABS_HI20", - "R_LARCH_ABS_LO12", - "R_LARCH_ADD16", - "R_LARCH_ADD24", - "R_LARCH_ADD32", - "R_LARCH_ADD64", - "R_LARCH_ADD8", - "R_LARCH_B16", - "R_LARCH_B21", - "R_LARCH_B26", - "R_LARCH_COPY", - "R_LARCH_GNU_VTENTRY", - "R_LARCH_GNU_VTINHERIT", - "R_LARCH_GOT64_HI12", - "R_LARCH_GOT64_LO20", - "R_LARCH_GOT64_PC_HI12", - "R_LARCH_GOT64_PC_LO20", - "R_LARCH_GOT_HI20", - "R_LARCH_GOT_LO12", - "R_LARCH_GOT_PC_HI20", - "R_LARCH_GOT_PC_LO12", - "R_LARCH_IRELATIVE", - "R_LARCH_JUMP_SLOT", - "R_LARCH_MARK_LA", - "R_LARCH_MARK_PCREL", - "R_LARCH_NONE", - "R_LARCH_PCALA64_HI12", - "R_LARCH_PCALA64_LO20", - "R_LARCH_PCALA_HI20", - "R_LARCH_PCALA_LO12", - "R_LARCH_RELATIVE", - "R_LARCH_RELAX", - "R_LARCH_SOP_ADD", - "R_LARCH_SOP_AND", - "R_LARCH_SOP_ASSERT", - "R_LARCH_SOP_IF_ELSE", - "R_LARCH_SOP_NOT", - "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", - "R_LARCH_SOP_POP_32_S_0_5_10_16_S2", - "R_LARCH_SOP_POP_32_S_10_12", - "R_LARCH_SOP_POP_32_S_10_16", - "R_LARCH_SOP_POP_32_S_10_16_S2", - "R_LARCH_SOP_POP_32_S_10_5", - "R_LARCH_SOP_POP_32_S_5_20", - "R_LARCH_SOP_POP_32_U", - "R_LARCH_SOP_POP_32_U_10_12", - "R_LARCH_SOP_PUSH_ABSOLUTE", - "R_LARCH_SOP_PUSH_DUP", - "R_LARCH_SOP_PUSH_GPREL", - "R_LARCH_SOP_PUSH_PCREL", - "R_LARCH_SOP_PUSH_PLT_PCREL", - "R_LARCH_SOP_PUSH_TLS_GD", - "R_LARCH_SOP_PUSH_TLS_GOT", - "R_LARCH_SOP_PUSH_TLS_TPREL", - "R_LARCH_SOP_SL", - "R_LARCH_SOP_SR", - "R_LARCH_SOP_SUB", - "R_LARCH_SUB16", - "R_LARCH_SUB24", - "R_LARCH_SUB32", - "R_LARCH_SUB64", - "R_LARCH_SUB8", - "R_LARCH_TLS_DTPMOD32", - "R_LARCH_TLS_DTPMOD64", - "R_LARCH_TLS_DTPREL32", - "R_LARCH_TLS_DTPREL64", - "R_LARCH_TLS_GD_HI20", - "R_LARCH_TLS_GD_PC_HI20", - "R_LARCH_TLS_IE64_HI12", - "R_LARCH_TLS_IE64_LO20", - "R_LARCH_TLS_IE64_PC_HI12", - "R_LARCH_TLS_IE64_PC_LO20", - "R_LARCH_TLS_IE_HI20", - "R_LARCH_TLS_IE_LO12", - "R_LARCH_TLS_IE_PC_HI20", - "R_LARCH_TLS_IE_PC_LO12", - "R_LARCH_TLS_LD_HI20", - "R_LARCH_TLS_LD_PC_HI20", - "R_LARCH_TLS_LE64_HI12", - "R_LARCH_TLS_LE64_LO20", - "R_LARCH_TLS_LE_HI20", - "R_LARCH_TLS_LE_LO12", - "R_LARCH_TLS_TPREL32", - "R_LARCH_TLS_TPREL64", - "R_MIPS", - "R_MIPS_16", - "R_MIPS_26", - "R_MIPS_32", - "R_MIPS_64", - "R_MIPS_ADD_IMMEDIATE", - "R_MIPS_CALL16", - "R_MIPS_CALL_HI16", - "R_MIPS_CALL_LO16", - "R_MIPS_DELETE", - "R_MIPS_GOT16", - "R_MIPS_GOT_DISP", - "R_MIPS_GOT_HI16", - "R_MIPS_GOT_LO16", - "R_MIPS_GOT_OFST", - "R_MIPS_GOT_PAGE", - "R_MIPS_GPREL16", - "R_MIPS_GPREL32", - "R_MIPS_HI16", - "R_MIPS_HIGHER", - "R_MIPS_HIGHEST", - "R_MIPS_INSERT_A", - "R_MIPS_INSERT_B", - "R_MIPS_JALR", - "R_MIPS_LITERAL", - "R_MIPS_LO16", - "R_MIPS_NONE", - "R_MIPS_PC16", - "R_MIPS_PJUMP", - "R_MIPS_REL16", - "R_MIPS_REL32", - "R_MIPS_RELGOT", - "R_MIPS_SCN_DISP", - "R_MIPS_SHIFT5", - "R_MIPS_SHIFT6", - "R_MIPS_SUB", - "R_MIPS_TLS_DTPMOD32", - "R_MIPS_TLS_DTPMOD64", - "R_MIPS_TLS_DTPREL32", - "R_MIPS_TLS_DTPREL64", - "R_MIPS_TLS_DTPREL_HI16", - "R_MIPS_TLS_DTPREL_LO16", - "R_MIPS_TLS_GD", - "R_MIPS_TLS_GOTTPREL", - "R_MIPS_TLS_LDM", - "R_MIPS_TLS_TPREL32", - "R_MIPS_TLS_TPREL64", - "R_MIPS_TLS_TPREL_HI16", - "R_MIPS_TLS_TPREL_LO16", - "R_PPC", - "R_PPC64", - "R_PPC64_ADDR14", - "R_PPC64_ADDR14_BRNTAKEN", - "R_PPC64_ADDR14_BRTAKEN", - "R_PPC64_ADDR16", - "R_PPC64_ADDR16_DS", - "R_PPC64_ADDR16_HA", - "R_PPC64_ADDR16_HI", - "R_PPC64_ADDR16_HIGH", - "R_PPC64_ADDR16_HIGHA", - "R_PPC64_ADDR16_HIGHER", - "R_PPC64_ADDR16_HIGHER34", - "R_PPC64_ADDR16_HIGHERA", - "R_PPC64_ADDR16_HIGHERA34", - "R_PPC64_ADDR16_HIGHEST", - "R_PPC64_ADDR16_HIGHEST34", - "R_PPC64_ADDR16_HIGHESTA", - "R_PPC64_ADDR16_HIGHESTA34", - "R_PPC64_ADDR16_LO", - "R_PPC64_ADDR16_LO_DS", - "R_PPC64_ADDR24", - "R_PPC64_ADDR32", - "R_PPC64_ADDR64", - "R_PPC64_ADDR64_LOCAL", - "R_PPC64_COPY", - "R_PPC64_D28", - "R_PPC64_D34", - "R_PPC64_D34_HA30", - "R_PPC64_D34_HI30", - "R_PPC64_D34_LO", - "R_PPC64_DTPMOD64", - "R_PPC64_DTPREL16", - "R_PPC64_DTPREL16_DS", - "R_PPC64_DTPREL16_HA", - "R_PPC64_DTPREL16_HI", - "R_PPC64_DTPREL16_HIGH", - "R_PPC64_DTPREL16_HIGHA", - "R_PPC64_DTPREL16_HIGHER", - "R_PPC64_DTPREL16_HIGHERA", - "R_PPC64_DTPREL16_HIGHEST", - "R_PPC64_DTPREL16_HIGHESTA", - "R_PPC64_DTPREL16_LO", - "R_PPC64_DTPREL16_LO_DS", - "R_PPC64_DTPREL34", - "R_PPC64_DTPREL64", - "R_PPC64_ENTRY", - "R_PPC64_GLOB_DAT", - "R_PPC64_GNU_VTENTRY", - "R_PPC64_GNU_VTINHERIT", - "R_PPC64_GOT16", - "R_PPC64_GOT16_DS", - "R_PPC64_GOT16_HA", - "R_PPC64_GOT16_HI", - "R_PPC64_GOT16_LO", - "R_PPC64_GOT16_LO_DS", - "R_PPC64_GOT_DTPREL16_DS", - "R_PPC64_GOT_DTPREL16_HA", - "R_PPC64_GOT_DTPREL16_HI", - "R_PPC64_GOT_DTPREL16_LO_DS", - "R_PPC64_GOT_DTPREL_PCREL34", - "R_PPC64_GOT_PCREL34", - "R_PPC64_GOT_TLSGD16", - "R_PPC64_GOT_TLSGD16_HA", - "R_PPC64_GOT_TLSGD16_HI", - "R_PPC64_GOT_TLSGD16_LO", - "R_PPC64_GOT_TLSGD_PCREL34", - "R_PPC64_GOT_TLSLD16", - "R_PPC64_GOT_TLSLD16_HA", - "R_PPC64_GOT_TLSLD16_HI", - "R_PPC64_GOT_TLSLD16_LO", - "R_PPC64_GOT_TLSLD_PCREL34", - "R_PPC64_GOT_TPREL16_DS", - "R_PPC64_GOT_TPREL16_HA", - "R_PPC64_GOT_TPREL16_HI", - "R_PPC64_GOT_TPREL16_LO_DS", - "R_PPC64_GOT_TPREL_PCREL34", - "R_PPC64_IRELATIVE", - "R_PPC64_JMP_IREL", - "R_PPC64_JMP_SLOT", - "R_PPC64_NONE", - "R_PPC64_PCREL28", - "R_PPC64_PCREL34", - "R_PPC64_PCREL_OPT", - "R_PPC64_PLT16_HA", - "R_PPC64_PLT16_HI", - "R_PPC64_PLT16_LO", - "R_PPC64_PLT16_LO_DS", - "R_PPC64_PLT32", - "R_PPC64_PLT64", - "R_PPC64_PLTCALL", - "R_PPC64_PLTCALL_NOTOC", - "R_PPC64_PLTGOT16", - "R_PPC64_PLTGOT16_DS", - "R_PPC64_PLTGOT16_HA", - "R_PPC64_PLTGOT16_HI", - "R_PPC64_PLTGOT16_LO", - "R_PPC64_PLTGOT_LO_DS", - "R_PPC64_PLTREL32", - "R_PPC64_PLTREL64", - "R_PPC64_PLTSEQ", - "R_PPC64_PLTSEQ_NOTOC", - "R_PPC64_PLT_PCREL34", - "R_PPC64_PLT_PCREL34_NOTOC", - "R_PPC64_REL14", - "R_PPC64_REL14_BRNTAKEN", - "R_PPC64_REL14_BRTAKEN", - "R_PPC64_REL16", - "R_PPC64_REL16DX_HA", - "R_PPC64_REL16_HA", - "R_PPC64_REL16_HI", - "R_PPC64_REL16_HIGH", - "R_PPC64_REL16_HIGHA", - "R_PPC64_REL16_HIGHER", - "R_PPC64_REL16_HIGHER34", - "R_PPC64_REL16_HIGHERA", - "R_PPC64_REL16_HIGHERA34", - "R_PPC64_REL16_HIGHEST", - "R_PPC64_REL16_HIGHEST34", - "R_PPC64_REL16_HIGHESTA", - "R_PPC64_REL16_HIGHESTA34", - "R_PPC64_REL16_LO", - "R_PPC64_REL24", - "R_PPC64_REL24_NOTOC", - "R_PPC64_REL24_P9NOTOC", - "R_PPC64_REL30", - "R_PPC64_REL32", - "R_PPC64_REL64", - "R_PPC64_RELATIVE", - "R_PPC64_SECTOFF", - "R_PPC64_SECTOFF_DS", - "R_PPC64_SECTOFF_HA", - "R_PPC64_SECTOFF_HI", - "R_PPC64_SECTOFF_LO", - "R_PPC64_SECTOFF_LO_DS", - "R_PPC64_TLS", - "R_PPC64_TLSGD", - "R_PPC64_TLSLD", - "R_PPC64_TOC", - "R_PPC64_TOC16", - "R_PPC64_TOC16_DS", - "R_PPC64_TOC16_HA", - "R_PPC64_TOC16_HI", - "R_PPC64_TOC16_LO", - "R_PPC64_TOC16_LO_DS", - "R_PPC64_TOCSAVE", - "R_PPC64_TPREL16", - "R_PPC64_TPREL16_DS", - "R_PPC64_TPREL16_HA", - "R_PPC64_TPREL16_HI", - "R_PPC64_TPREL16_HIGH", - "R_PPC64_TPREL16_HIGHA", - "R_PPC64_TPREL16_HIGHER", - "R_PPC64_TPREL16_HIGHERA", - "R_PPC64_TPREL16_HIGHEST", - "R_PPC64_TPREL16_HIGHESTA", - "R_PPC64_TPREL16_LO", - "R_PPC64_TPREL16_LO_DS", - "R_PPC64_TPREL34", - "R_PPC64_TPREL64", - "R_PPC64_UADDR16", - "R_PPC64_UADDR32", - "R_PPC64_UADDR64", - "R_PPC_ADDR14", - "R_PPC_ADDR14_BRNTAKEN", - "R_PPC_ADDR14_BRTAKEN", - "R_PPC_ADDR16", - "R_PPC_ADDR16_HA", - "R_PPC_ADDR16_HI", - "R_PPC_ADDR16_LO", - "R_PPC_ADDR24", - "R_PPC_ADDR32", - "R_PPC_COPY", - "R_PPC_DTPMOD32", - "R_PPC_DTPREL16", - "R_PPC_DTPREL16_HA", - "R_PPC_DTPREL16_HI", - "R_PPC_DTPREL16_LO", - "R_PPC_DTPREL32", - "R_PPC_EMB_BIT_FLD", - "R_PPC_EMB_MRKREF", - "R_PPC_EMB_NADDR16", - "R_PPC_EMB_NADDR16_HA", - "R_PPC_EMB_NADDR16_HI", - "R_PPC_EMB_NADDR16_LO", - "R_PPC_EMB_NADDR32", - "R_PPC_EMB_RELSDA", - "R_PPC_EMB_RELSEC16", - "R_PPC_EMB_RELST_HA", - "R_PPC_EMB_RELST_HI", - "R_PPC_EMB_RELST_LO", - "R_PPC_EMB_SDA21", - "R_PPC_EMB_SDA2I16", - "R_PPC_EMB_SDA2REL", - "R_PPC_EMB_SDAI16", - "R_PPC_GLOB_DAT", - "R_PPC_GOT16", - "R_PPC_GOT16_HA", - "R_PPC_GOT16_HI", - "R_PPC_GOT16_LO", - "R_PPC_GOT_TLSGD16", - "R_PPC_GOT_TLSGD16_HA", - "R_PPC_GOT_TLSGD16_HI", - "R_PPC_GOT_TLSGD16_LO", - "R_PPC_GOT_TLSLD16", - "R_PPC_GOT_TLSLD16_HA", - "R_PPC_GOT_TLSLD16_HI", - "R_PPC_GOT_TLSLD16_LO", - "R_PPC_GOT_TPREL16", - "R_PPC_GOT_TPREL16_HA", - "R_PPC_GOT_TPREL16_HI", - "R_PPC_GOT_TPREL16_LO", - "R_PPC_JMP_SLOT", - "R_PPC_LOCAL24PC", - "R_PPC_NONE", - "R_PPC_PLT16_HA", - "R_PPC_PLT16_HI", - "R_PPC_PLT16_LO", - "R_PPC_PLT32", - "R_PPC_PLTREL24", - "R_PPC_PLTREL32", - "R_PPC_REL14", - "R_PPC_REL14_BRNTAKEN", - "R_PPC_REL14_BRTAKEN", - "R_PPC_REL24", - "R_PPC_REL32", - "R_PPC_RELATIVE", - "R_PPC_SDAREL16", - "R_PPC_SECTOFF", - "R_PPC_SECTOFF_HA", - "R_PPC_SECTOFF_HI", - "R_PPC_SECTOFF_LO", - "R_PPC_TLS", - "R_PPC_TPREL16", - "R_PPC_TPREL16_HA", - "R_PPC_TPREL16_HI", - "R_PPC_TPREL16_LO", - "R_PPC_TPREL32", - "R_PPC_UADDR16", - "R_PPC_UADDR32", - "R_RISCV", - "R_RISCV_32", - "R_RISCV_32_PCREL", - "R_RISCV_64", - "R_RISCV_ADD16", - "R_RISCV_ADD32", - "R_RISCV_ADD64", - "R_RISCV_ADD8", - "R_RISCV_ALIGN", - "R_RISCV_BRANCH", - "R_RISCV_CALL", - "R_RISCV_CALL_PLT", - "R_RISCV_COPY", - "R_RISCV_GNU_VTENTRY", - "R_RISCV_GNU_VTINHERIT", - "R_RISCV_GOT_HI20", - "R_RISCV_GPREL_I", - "R_RISCV_GPREL_S", - "R_RISCV_HI20", - "R_RISCV_JAL", - "R_RISCV_JUMP_SLOT", - "R_RISCV_LO12_I", - "R_RISCV_LO12_S", - "R_RISCV_NONE", - "R_RISCV_PCREL_HI20", - "R_RISCV_PCREL_LO12_I", - "R_RISCV_PCREL_LO12_S", - "R_RISCV_RELATIVE", - "R_RISCV_RELAX", - "R_RISCV_RVC_BRANCH", - "R_RISCV_RVC_JUMP", - "R_RISCV_RVC_LUI", - "R_RISCV_SET16", - "R_RISCV_SET32", - "R_RISCV_SET6", - "R_RISCV_SET8", - "R_RISCV_SUB16", - "R_RISCV_SUB32", - "R_RISCV_SUB6", - "R_RISCV_SUB64", - "R_RISCV_SUB8", - "R_RISCV_TLS_DTPMOD32", - "R_RISCV_TLS_DTPMOD64", - "R_RISCV_TLS_DTPREL32", - "R_RISCV_TLS_DTPREL64", - "R_RISCV_TLS_GD_HI20", - "R_RISCV_TLS_GOT_HI20", - "R_RISCV_TLS_TPREL32", - "R_RISCV_TLS_TPREL64", - "R_RISCV_TPREL_ADD", - "R_RISCV_TPREL_HI20", - "R_RISCV_TPREL_I", - "R_RISCV_TPREL_LO12_I", - "R_RISCV_TPREL_LO12_S", - "R_RISCV_TPREL_S", - "R_SPARC", - "R_SPARC_10", - "R_SPARC_11", - "R_SPARC_13", - "R_SPARC_16", - "R_SPARC_22", - "R_SPARC_32", - "R_SPARC_5", - "R_SPARC_6", - "R_SPARC_64", - "R_SPARC_7", - "R_SPARC_8", - "R_SPARC_COPY", - "R_SPARC_DISP16", - "R_SPARC_DISP32", - "R_SPARC_DISP64", - "R_SPARC_DISP8", - "R_SPARC_GLOB_DAT", - "R_SPARC_GLOB_JMP", - "R_SPARC_GOT10", - "R_SPARC_GOT13", - "R_SPARC_GOT22", - "R_SPARC_H44", - "R_SPARC_HH22", - "R_SPARC_HI22", - "R_SPARC_HIPLT22", - "R_SPARC_HIX22", - "R_SPARC_HM10", - "R_SPARC_JMP_SLOT", - "R_SPARC_L44", - "R_SPARC_LM22", - "R_SPARC_LO10", - "R_SPARC_LOPLT10", - "R_SPARC_LOX10", - "R_SPARC_M44", - "R_SPARC_NONE", - "R_SPARC_OLO10", - "R_SPARC_PC10", - "R_SPARC_PC22", - "R_SPARC_PCPLT10", - "R_SPARC_PCPLT22", - "R_SPARC_PCPLT32", - "R_SPARC_PC_HH22", - "R_SPARC_PC_HM10", - "R_SPARC_PC_LM22", - "R_SPARC_PLT32", - "R_SPARC_PLT64", - "R_SPARC_REGISTER", - "R_SPARC_RELATIVE", - "R_SPARC_UA16", - "R_SPARC_UA32", - "R_SPARC_UA64", - "R_SPARC_WDISP16", - "R_SPARC_WDISP19", - "R_SPARC_WDISP22", - "R_SPARC_WDISP30", - "R_SPARC_WPLT30", - "R_SYM32", - "R_SYM64", - "R_TYPE32", - "R_TYPE64", - "R_X86_64", - "R_X86_64_16", - "R_X86_64_32", - "R_X86_64_32S", - "R_X86_64_64", - "R_X86_64_8", - "R_X86_64_COPY", - "R_X86_64_DTPMOD64", - "R_X86_64_DTPOFF32", - "R_X86_64_DTPOFF64", - "R_X86_64_GLOB_DAT", - "R_X86_64_GOT32", - "R_X86_64_GOT64", - "R_X86_64_GOTOFF64", - "R_X86_64_GOTPC32", - "R_X86_64_GOTPC32_TLSDESC", - "R_X86_64_GOTPC64", - "R_X86_64_GOTPCREL", - "R_X86_64_GOTPCREL64", - "R_X86_64_GOTPCRELX", - "R_X86_64_GOTPLT64", - "R_X86_64_GOTTPOFF", - "R_X86_64_IRELATIVE", - "R_X86_64_JMP_SLOT", - "R_X86_64_NONE", - "R_X86_64_PC16", - "R_X86_64_PC32", - "R_X86_64_PC32_BND", - "R_X86_64_PC64", - "R_X86_64_PC8", - "R_X86_64_PLT32", - "R_X86_64_PLT32_BND", - "R_X86_64_PLTOFF64", - "R_X86_64_RELATIVE", - "R_X86_64_RELATIVE64", - "R_X86_64_REX_GOTPCRELX", - "R_X86_64_SIZE32", - "R_X86_64_SIZE64", - "R_X86_64_TLSDESC", - "R_X86_64_TLSDESC_CALL", - "R_X86_64_TLSGD", - "R_X86_64_TLSLD", - "R_X86_64_TPOFF32", - "R_X86_64_TPOFF64", - "Rel32", - "Rel64", - "Rela32", - "Rela64", - "SHF_ALLOC", - "SHF_COMPRESSED", - "SHF_EXECINSTR", - "SHF_GROUP", - "SHF_INFO_LINK", - "SHF_LINK_ORDER", - "SHF_MASKOS", - "SHF_MASKPROC", - "SHF_MERGE", - "SHF_OS_NONCONFORMING", - "SHF_STRINGS", - "SHF_TLS", - "SHF_WRITE", - "SHN_ABS", - "SHN_COMMON", - "SHN_HIOS", - "SHN_HIPROC", - "SHN_HIRESERVE", - "SHN_LOOS", - "SHN_LOPROC", - "SHN_LORESERVE", - "SHN_UNDEF", - "SHN_XINDEX", - "SHT_DYNAMIC", - "SHT_DYNSYM", - "SHT_FINI_ARRAY", - "SHT_GNU_ATTRIBUTES", - "SHT_GNU_HASH", - "SHT_GNU_LIBLIST", - "SHT_GNU_VERDEF", - "SHT_GNU_VERNEED", - "SHT_GNU_VERSYM", - "SHT_GROUP", - "SHT_HASH", - "SHT_HIOS", - "SHT_HIPROC", - "SHT_HIUSER", - "SHT_INIT_ARRAY", - "SHT_LOOS", - "SHT_LOPROC", - "SHT_LOUSER", - "SHT_MIPS_ABIFLAGS", - "SHT_NOBITS", - "SHT_NOTE", - "SHT_NULL", - "SHT_PREINIT_ARRAY", - "SHT_PROGBITS", - "SHT_REL", - "SHT_RELA", - "SHT_SHLIB", - "SHT_STRTAB", - "SHT_SYMTAB", - "SHT_SYMTAB_SHNDX", - "STB_GLOBAL", - "STB_HIOS", - "STB_HIPROC", - "STB_LOCAL", - "STB_LOOS", - "STB_LOPROC", - "STB_WEAK", - "STT_COMMON", - "STT_FILE", - "STT_FUNC", - "STT_HIOS", - "STT_HIPROC", - "STT_LOOS", - "STT_LOPROC", - "STT_NOTYPE", - "STT_OBJECT", - "STT_SECTION", - "STT_TLS", - "STV_DEFAULT", - "STV_HIDDEN", - "STV_INTERNAL", - "STV_PROTECTED", - "ST_BIND", - "ST_INFO", - "ST_TYPE", - "ST_VISIBILITY", - "Section", - "Section32", - "Section64", - "SectionFlag", - "SectionHeader", - "SectionIndex", - "SectionType", - "Sym32", - "Sym32Size", - "Sym64", - "Sym64Size", - "SymBind", - "SymType", - "SymVis", - "Symbol", - "Type", - "Version", - }, - "debug/gosym": { - "DecodingError", - "Func", - "LineTable", - "NewLineTable", - "NewTable", - "Obj", - "Sym", - "Table", - "UnknownFileError", - "UnknownLineError", - }, - "debug/macho": { - "ARM64_RELOC_ADDEND", - "ARM64_RELOC_BRANCH26", - "ARM64_RELOC_GOT_LOAD_PAGE21", - "ARM64_RELOC_GOT_LOAD_PAGEOFF12", - "ARM64_RELOC_PAGE21", - "ARM64_RELOC_PAGEOFF12", - "ARM64_RELOC_POINTER_TO_GOT", - "ARM64_RELOC_SUBTRACTOR", - "ARM64_RELOC_TLVP_LOAD_PAGE21", - "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", - "ARM64_RELOC_UNSIGNED", - "ARM_RELOC_BR24", - "ARM_RELOC_HALF", - "ARM_RELOC_HALF_SECTDIFF", - "ARM_RELOC_LOCAL_SECTDIFF", - "ARM_RELOC_PAIR", - "ARM_RELOC_PB_LA_PTR", - "ARM_RELOC_SECTDIFF", - "ARM_RELOC_VANILLA", - "ARM_THUMB_32BIT_BRANCH", - "ARM_THUMB_RELOC_BR22", - "Cpu", - "Cpu386", - "CpuAmd64", - "CpuArm", - "CpuArm64", - "CpuPpc", - "CpuPpc64", - "Dylib", - "DylibCmd", - "Dysymtab", - "DysymtabCmd", - "ErrNotFat", - "FatArch", - "FatArchHeader", - "FatFile", - "File", - "FileHeader", - "FlagAllModsBound", - "FlagAllowStackExecution", - "FlagAppExtensionSafe", - "FlagBindAtLoad", - "FlagBindsToWeak", - "FlagCanonical", - "FlagDeadStrippableDylib", - "FlagDyldLink", - "FlagForceFlat", - "FlagHasTLVDescriptors", - "FlagIncrLink", - "FlagLazyInit", - "FlagNoFixPrebinding", - "FlagNoHeapExecution", - "FlagNoMultiDefs", - "FlagNoReexportedDylibs", - "FlagNoUndefs", - "FlagPIE", - "FlagPrebindable", - "FlagPrebound", - "FlagRootSafe", - "FlagSetuidSafe", - "FlagSplitSegs", - "FlagSubsectionsViaSymbols", - "FlagTwoLevel", - "FlagWeakDefines", - "FormatError", - "GENERIC_RELOC_LOCAL_SECTDIFF", - "GENERIC_RELOC_PAIR", - "GENERIC_RELOC_PB_LA_PTR", - "GENERIC_RELOC_SECTDIFF", - "GENERIC_RELOC_TLV", - "GENERIC_RELOC_VANILLA", - "Load", - "LoadBytes", - "LoadCmd", - "LoadCmdDylib", - "LoadCmdDylinker", - "LoadCmdDysymtab", - "LoadCmdRpath", - "LoadCmdSegment", - "LoadCmdSegment64", - "LoadCmdSymtab", - "LoadCmdThread", - "LoadCmdUnixThread", - "Magic32", - "Magic64", - "MagicFat", - "NewFatFile", - "NewFile", - "Nlist32", - "Nlist64", - "Open", - "OpenFat", - "Regs386", - "RegsAMD64", - "Reloc", - "RelocTypeARM", - "RelocTypeARM64", - "RelocTypeGeneric", - "RelocTypeX86_64", - "Rpath", - "RpathCmd", - "Section", - "Section32", - "Section64", - "SectionHeader", - "Segment", - "Segment32", - "Segment64", - "SegmentHeader", - "Symbol", - "Symtab", - "SymtabCmd", - "Thread", - "Type", - "TypeBundle", - "TypeDylib", - "TypeExec", - "TypeObj", - "X86_64_RELOC_BRANCH", - "X86_64_RELOC_GOT", - "X86_64_RELOC_GOT_LOAD", - "X86_64_RELOC_SIGNED", - "X86_64_RELOC_SIGNED_1", - "X86_64_RELOC_SIGNED_2", - "X86_64_RELOC_SIGNED_4", - "X86_64_RELOC_SUBTRACTOR", - "X86_64_RELOC_TLV", - "X86_64_RELOC_UNSIGNED", - }, - "debug/pe": { - "COFFSymbol", - "COFFSymbolAuxFormat5", - "COFFSymbolSize", - "DataDirectory", - "File", - "FileHeader", - "FormatError", - "IMAGE_COMDAT_SELECT_ANY", - "IMAGE_COMDAT_SELECT_ASSOCIATIVE", - "IMAGE_COMDAT_SELECT_EXACT_MATCH", - "IMAGE_COMDAT_SELECT_LARGEST", - "IMAGE_COMDAT_SELECT_NODUPLICATES", - "IMAGE_COMDAT_SELECT_SAME_SIZE", - "IMAGE_DIRECTORY_ENTRY_ARCHITECTURE", - "IMAGE_DIRECTORY_ENTRY_BASERELOC", - "IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", - "IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", - "IMAGE_DIRECTORY_ENTRY_DEBUG", - "IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", - "IMAGE_DIRECTORY_ENTRY_EXCEPTION", - "IMAGE_DIRECTORY_ENTRY_EXPORT", - "IMAGE_DIRECTORY_ENTRY_GLOBALPTR", - "IMAGE_DIRECTORY_ENTRY_IAT", - "IMAGE_DIRECTORY_ENTRY_IMPORT", - "IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", - "IMAGE_DIRECTORY_ENTRY_RESOURCE", - "IMAGE_DIRECTORY_ENTRY_SECURITY", - "IMAGE_DIRECTORY_ENTRY_TLS", - "IMAGE_DLLCHARACTERISTICS_APPCONTAINER", - "IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE", - "IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY", - "IMAGE_DLLCHARACTERISTICS_GUARD_CF", - "IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA", - "IMAGE_DLLCHARACTERISTICS_NO_BIND", - "IMAGE_DLLCHARACTERISTICS_NO_ISOLATION", - "IMAGE_DLLCHARACTERISTICS_NO_SEH", - "IMAGE_DLLCHARACTERISTICS_NX_COMPAT", - "IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE", - "IMAGE_DLLCHARACTERISTICS_WDM_DRIVER", - "IMAGE_FILE_32BIT_MACHINE", - "IMAGE_FILE_AGGRESIVE_WS_TRIM", - "IMAGE_FILE_BYTES_REVERSED_HI", - "IMAGE_FILE_BYTES_REVERSED_LO", - "IMAGE_FILE_DEBUG_STRIPPED", - "IMAGE_FILE_DLL", - "IMAGE_FILE_EXECUTABLE_IMAGE", - "IMAGE_FILE_LARGE_ADDRESS_AWARE", - "IMAGE_FILE_LINE_NUMS_STRIPPED", - "IMAGE_FILE_LOCAL_SYMS_STRIPPED", - "IMAGE_FILE_MACHINE_AM33", - "IMAGE_FILE_MACHINE_AMD64", - "IMAGE_FILE_MACHINE_ARM", - "IMAGE_FILE_MACHINE_ARM64", - "IMAGE_FILE_MACHINE_ARMNT", - "IMAGE_FILE_MACHINE_EBC", - "IMAGE_FILE_MACHINE_I386", - "IMAGE_FILE_MACHINE_IA64", - "IMAGE_FILE_MACHINE_LOONGARCH32", - "IMAGE_FILE_MACHINE_LOONGARCH64", - "IMAGE_FILE_MACHINE_M32R", - "IMAGE_FILE_MACHINE_MIPS16", - "IMAGE_FILE_MACHINE_MIPSFPU", - "IMAGE_FILE_MACHINE_MIPSFPU16", - "IMAGE_FILE_MACHINE_POWERPC", - "IMAGE_FILE_MACHINE_POWERPCFP", - "IMAGE_FILE_MACHINE_R4000", - "IMAGE_FILE_MACHINE_RISCV128", - "IMAGE_FILE_MACHINE_RISCV32", - "IMAGE_FILE_MACHINE_RISCV64", - "IMAGE_FILE_MACHINE_SH3", - "IMAGE_FILE_MACHINE_SH3DSP", - "IMAGE_FILE_MACHINE_SH4", - "IMAGE_FILE_MACHINE_SH5", - "IMAGE_FILE_MACHINE_THUMB", - "IMAGE_FILE_MACHINE_UNKNOWN", - "IMAGE_FILE_MACHINE_WCEMIPSV2", - "IMAGE_FILE_NET_RUN_FROM_SWAP", - "IMAGE_FILE_RELOCS_STRIPPED", - "IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP", - "IMAGE_FILE_SYSTEM", - "IMAGE_FILE_UP_SYSTEM_ONLY", - "IMAGE_SCN_CNT_CODE", - "IMAGE_SCN_CNT_INITIALIZED_DATA", - "IMAGE_SCN_CNT_UNINITIALIZED_DATA", - "IMAGE_SCN_LNK_COMDAT", - "IMAGE_SCN_MEM_DISCARDABLE", - "IMAGE_SCN_MEM_EXECUTE", - "IMAGE_SCN_MEM_READ", - "IMAGE_SCN_MEM_WRITE", - "IMAGE_SUBSYSTEM_EFI_APPLICATION", - "IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER", - "IMAGE_SUBSYSTEM_EFI_ROM", - "IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER", - "IMAGE_SUBSYSTEM_NATIVE", - "IMAGE_SUBSYSTEM_NATIVE_WINDOWS", - "IMAGE_SUBSYSTEM_OS2_CUI", - "IMAGE_SUBSYSTEM_POSIX_CUI", - "IMAGE_SUBSYSTEM_UNKNOWN", - "IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION", - "IMAGE_SUBSYSTEM_WINDOWS_CE_GUI", - "IMAGE_SUBSYSTEM_WINDOWS_CUI", - "IMAGE_SUBSYSTEM_WINDOWS_GUI", - "IMAGE_SUBSYSTEM_XBOX", - "ImportDirectory", - "NewFile", - "Open", - "OptionalHeader32", - "OptionalHeader64", - "Reloc", - "Section", - "SectionHeader", - "SectionHeader32", - "StringTable", - "Symbol", - }, - "debug/plan9obj": { - "ErrNoSymbols", - "File", - "FileHeader", - "Magic386", - "Magic64", - "MagicAMD64", - "MagicARM", - "NewFile", - "Open", - "Section", - "SectionHeader", - "Sym", - }, - "embed": { - "FS", - }, - "encoding": { - "BinaryMarshaler", - "BinaryUnmarshaler", - "TextMarshaler", - "TextUnmarshaler", - }, - "encoding/ascii85": { - "CorruptInputError", - "Decode", - "Encode", - "MaxEncodedLen", - "NewDecoder", - "NewEncoder", - }, - "encoding/asn1": { - "BitString", - "ClassApplication", - "ClassContextSpecific", - "ClassPrivate", - "ClassUniversal", - "Enumerated", - "Flag", - "Marshal", - "MarshalWithParams", - "NullBytes", - "NullRawValue", - "ObjectIdentifier", - "RawContent", - "RawValue", - "StructuralError", - "SyntaxError", - "TagBMPString", - "TagBitString", - "TagBoolean", - "TagEnum", - "TagGeneralString", - "TagGeneralizedTime", - "TagIA5String", - "TagInteger", - "TagNull", - "TagNumericString", - "TagOID", - "TagOctetString", - "TagPrintableString", - "TagSequence", - "TagSet", - "TagT61String", - "TagUTCTime", - "TagUTF8String", - "Unmarshal", - "UnmarshalWithParams", - }, - "encoding/base32": { - "CorruptInputError", - "Encoding", - "HexEncoding", - "NewDecoder", - "NewEncoder", - "NewEncoding", - "NoPadding", - "StdEncoding", - "StdPadding", - }, - "encoding/base64": { - "CorruptInputError", - "Encoding", - "NewDecoder", - "NewEncoder", - "NewEncoding", - "NoPadding", - "RawStdEncoding", - "RawURLEncoding", - "StdEncoding", - "StdPadding", - "URLEncoding", - }, - "encoding/binary": { - "AppendByteOrder", - "AppendUvarint", - "AppendVarint", - "BigEndian", - "ByteOrder", - "LittleEndian", - "MaxVarintLen16", - "MaxVarintLen32", - "MaxVarintLen64", - "NativeEndian", - "PutUvarint", - "PutVarint", - "Read", - "ReadUvarint", - "ReadVarint", - "Size", - "Uvarint", - "Varint", - "Write", - }, - "encoding/csv": { - "ErrBareQuote", - "ErrFieldCount", - "ErrQuote", - "ErrTrailingComma", - "NewReader", - "NewWriter", - "ParseError", - "Reader", - "Writer", - }, - "encoding/gob": { - "CommonType", - "Decoder", - "Encoder", - "GobDecoder", - "GobEncoder", - "NewDecoder", - "NewEncoder", - "Register", - "RegisterName", - }, - "encoding/hex": { - "Decode", - "DecodeString", - "DecodedLen", - "Dump", - "Dumper", - "Encode", - "EncodeToString", - "EncodedLen", - "ErrLength", - "InvalidByteError", - "NewDecoder", - "NewEncoder", - }, - "encoding/json": { - "Compact", - "Decoder", - "Delim", - "Encoder", - "HTMLEscape", - "Indent", - "InvalidUTF8Error", - "InvalidUnmarshalError", - "Marshal", - "MarshalIndent", - "Marshaler", - "MarshalerError", - "NewDecoder", - "NewEncoder", - "Number", - "RawMessage", - "SyntaxError", - "Token", - "Unmarshal", - "UnmarshalFieldError", - "UnmarshalTypeError", - "Unmarshaler", - "UnsupportedTypeError", - "UnsupportedValueError", - "Valid", - }, - "encoding/pem": { - "Block", - "Decode", - "Encode", - "EncodeToMemory", - }, - "encoding/xml": { - "Attr", - "CharData", - "Comment", - "CopyToken", - "Decoder", - "Directive", - "Encoder", - "EndElement", - "Escape", - "EscapeText", - "HTMLAutoClose", - "HTMLEntity", - "Header", - "Marshal", - "MarshalIndent", - "Marshaler", - "MarshalerAttr", - "Name", - "NewDecoder", - "NewEncoder", - "NewTokenDecoder", - "ProcInst", - "StartElement", - "SyntaxError", - "TagPathError", - "Token", - "TokenReader", - "Unmarshal", - "UnmarshalError", - "Unmarshaler", - "UnmarshalerAttr", - "UnsupportedTypeError", - }, - "errors": { - "As", - "ErrUnsupported", - "Is", - "Join", - "New", - "Unwrap", - }, - "expvar": { - "Do", - "Float", - "Func", - "Get", - "Handler", - "Int", - "KeyValue", - "Map", - "NewFloat", - "NewInt", - "NewMap", - "NewString", - "Publish", - "String", - "Var", - }, - "flag": { - "Arg", - "Args", - "Bool", - "BoolFunc", - "BoolVar", - "CommandLine", - "ContinueOnError", - "Duration", - "DurationVar", - "ErrHelp", - "ErrorHandling", - "ExitOnError", - "Flag", - "FlagSet", - "Float64", - "Float64Var", - "Func", - "Getter", - "Int", - "Int64", - "Int64Var", - "IntVar", - "Lookup", - "NArg", - "NFlag", - "NewFlagSet", - "PanicOnError", - "Parse", - "Parsed", - "PrintDefaults", - "Set", - "String", - "StringVar", - "TextVar", - "Uint", - "Uint64", - "Uint64Var", - "UintVar", - "UnquoteUsage", - "Usage", - "Value", - "Var", - "Visit", - "VisitAll", - }, - "fmt": { - "Append", - "Appendf", - "Appendln", - "Errorf", - "FormatString", - "Formatter", - "Fprint", - "Fprintf", - "Fprintln", - "Fscan", - "Fscanf", - "Fscanln", - "GoStringer", - "Print", - "Printf", - "Println", - "Scan", - "ScanState", - "Scanf", - "Scanln", - "Scanner", - "Sprint", - "Sprintf", - "Sprintln", - "Sscan", - "Sscanf", - "Sscanln", - "State", - "Stringer", - }, - "go/ast": { - "ArrayType", - "AssignStmt", - "Bad", - "BadDecl", - "BadExpr", - "BadStmt", - "BasicLit", - "BinaryExpr", - "BlockStmt", - "BranchStmt", - "CallExpr", - "CaseClause", - "ChanDir", - "ChanType", - "CommClause", - "Comment", - "CommentGroup", - "CommentMap", - "CompositeLit", - "Con", - "Decl", - "DeclStmt", - "DeferStmt", - "Ellipsis", - "EmptyStmt", - "Expr", - "ExprStmt", - "Field", - "FieldFilter", - "FieldList", - "File", - "FileExports", - "Filter", - "FilterDecl", - "FilterFile", - "FilterFuncDuplicates", - "FilterImportDuplicates", - "FilterPackage", - "FilterUnassociatedComments", - "ForStmt", - "Fprint", - "Fun", - "FuncDecl", - "FuncLit", - "FuncType", - "GenDecl", - "GoStmt", - "Ident", - "IfStmt", - "ImportSpec", - "Importer", - "IncDecStmt", - "IndexExpr", - "IndexListExpr", - "Inspect", - "InterfaceType", - "IsExported", - "IsGenerated", - "KeyValueExpr", - "LabeledStmt", - "Lbl", - "MapType", - "MergeMode", - "MergePackageFiles", - "NewCommentMap", - "NewIdent", - "NewObj", - "NewPackage", - "NewScope", - "Node", - "NotNilFilter", - "ObjKind", - "Object", - "Package", - "PackageExports", - "ParenExpr", - "Pkg", - "Print", - "RECV", - "RangeStmt", - "ReturnStmt", - "SEND", - "Scope", - "SelectStmt", - "SelectorExpr", - "SendStmt", - "SliceExpr", - "SortImports", - "Spec", - "StarExpr", - "Stmt", - "StructType", - "SwitchStmt", - "Typ", - "TypeAssertExpr", - "TypeSpec", - "TypeSwitchStmt", - "UnaryExpr", - "ValueSpec", - "Var", - "Visitor", - "Walk", - }, - "go/build": { - "AllowBinary", - "ArchChar", - "Context", - "Default", - "Directive", - "FindOnly", - "IgnoreVendor", - "Import", - "ImportComment", - "ImportDir", - "ImportMode", - "IsLocalImport", - "MultiplePackageError", - "NoGoError", - "Package", - "ToolDir", - }, - "go/build/constraint": { - "AndExpr", - "Expr", - "GoVersion", - "IsGoBuild", - "IsPlusBuild", - "NotExpr", - "OrExpr", - "Parse", - "PlusBuildLines", - "SyntaxError", - "TagExpr", - }, - "go/constant": { - "BinaryOp", - "BitLen", - "Bool", - "BoolVal", - "Bytes", - "Compare", - "Complex", - "Denom", - "Float", - "Float32Val", - "Float64Val", - "Imag", - "Int", - "Int64Val", - "Kind", - "Make", - "MakeBool", - "MakeFloat64", - "MakeFromBytes", - "MakeFromLiteral", - "MakeImag", - "MakeInt64", - "MakeString", - "MakeUint64", - "MakeUnknown", - "Num", - "Real", - "Shift", - "Sign", - "String", - "StringVal", - "ToComplex", - "ToFloat", - "ToInt", - "Uint64Val", - "UnaryOp", - "Unknown", - "Val", - "Value", - }, - "go/doc": { - "AllDecls", - "AllMethods", - "Example", - "Examples", - "Filter", - "Func", - "IllegalPrefixes", - "IsPredeclared", - "Mode", - "New", - "NewFromFiles", - "Note", - "Package", - "PreserveAST", - "Synopsis", - "ToHTML", - "ToText", - "Type", - "Value", - }, - "go/doc/comment": { - "Block", - "Code", - "DefaultLookupPackage", - "Doc", - "DocLink", - "Heading", - "Italic", - "Link", - "LinkDef", - "List", - "ListItem", - "Paragraph", - "Parser", - "Plain", - "Printer", - "Text", - }, - "go/format": { - "Node", - "Source", - }, - "go/importer": { - "Default", - "For", - "ForCompiler", - "Lookup", - }, - "go/parser": { - "AllErrors", - "DeclarationErrors", - "ImportsOnly", - "Mode", - "PackageClauseOnly", - "ParseComments", - "ParseDir", - "ParseExpr", - "ParseExprFrom", - "ParseFile", - "SkipObjectResolution", - "SpuriousErrors", - "Trace", - }, - "go/printer": { - "CommentedNode", - "Config", - "Fprint", - "Mode", - "RawFormat", - "SourcePos", - "TabIndent", - "UseSpaces", - }, - "go/scanner": { - "Error", - "ErrorHandler", - "ErrorList", - "Mode", - "PrintError", - "ScanComments", - "Scanner", - }, - "go/token": { - "ADD", - "ADD_ASSIGN", - "AND", - "AND_ASSIGN", - "AND_NOT", - "AND_NOT_ASSIGN", - "ARROW", - "ASSIGN", - "BREAK", - "CASE", - "CHAN", - "CHAR", - "COLON", - "COMMA", - "COMMENT", - "CONST", - "CONTINUE", - "DEC", - "DEFAULT", - "DEFER", - "DEFINE", - "ELLIPSIS", - "ELSE", - "EOF", - "EQL", - "FALLTHROUGH", - "FLOAT", - "FOR", - "FUNC", - "File", - "FileSet", - "GEQ", - "GO", - "GOTO", - "GTR", - "HighestPrec", - "IDENT", - "IF", - "ILLEGAL", - "IMAG", - "IMPORT", - "INC", - "INT", - "INTERFACE", - "IsExported", - "IsIdentifier", - "IsKeyword", - "LAND", - "LBRACE", - "LBRACK", - "LEQ", - "LOR", - "LPAREN", - "LSS", - "Lookup", - "LowestPrec", - "MAP", - "MUL", - "MUL_ASSIGN", - "NEQ", - "NOT", - "NewFileSet", - "NoPos", - "OR", - "OR_ASSIGN", - "PACKAGE", - "PERIOD", - "Pos", - "Position", - "QUO", - "QUO_ASSIGN", - "RANGE", - "RBRACE", - "RBRACK", - "REM", - "REM_ASSIGN", - "RETURN", - "RPAREN", - "SELECT", - "SEMICOLON", - "SHL", - "SHL_ASSIGN", - "SHR", - "SHR_ASSIGN", - "STRING", - "STRUCT", - "SUB", - "SUB_ASSIGN", - "SWITCH", - "TILDE", - "TYPE", - "Token", - "UnaryPrec", - "VAR", - "XOR", - "XOR_ASSIGN", - }, - "go/types": { - "ArgumentError", - "Array", - "AssertableTo", - "AssignableTo", - "Basic", - "BasicInfo", - "BasicKind", - "Bool", - "Builtin", - "Byte", - "Chan", - "ChanDir", - "CheckExpr", - "Checker", - "Comparable", - "Complex128", - "Complex64", - "Config", - "Const", - "Context", - "ConvertibleTo", - "DefPredeclaredTestFuncs", - "Default", - "Error", - "Eval", - "ExprString", - "FieldVal", - "Float32", - "Float64", - "Func", - "Id", - "Identical", - "IdenticalIgnoreTags", - "Implements", - "ImportMode", - "Importer", - "ImporterFrom", - "Info", - "Initializer", - "Instance", - "Instantiate", - "Int", - "Int16", - "Int32", - "Int64", - "Int8", - "Interface", - "Invalid", - "IsBoolean", - "IsComplex", - "IsConstType", - "IsFloat", - "IsInteger", - "IsInterface", - "IsNumeric", - "IsOrdered", - "IsString", - "IsUnsigned", - "IsUntyped", - "Label", - "LookupFieldOrMethod", - "Map", - "MethodExpr", - "MethodSet", - "MethodVal", - "MissingMethod", - "Named", - "NewArray", - "NewChan", - "NewChecker", - "NewConst", - "NewContext", - "NewField", - "NewFunc", - "NewInterface", - "NewInterfaceType", - "NewLabel", - "NewMap", - "NewMethodSet", - "NewNamed", - "NewPackage", - "NewParam", - "NewPkgName", - "NewPointer", - "NewScope", - "NewSignature", - "NewSignatureType", - "NewSlice", - "NewStruct", - "NewTerm", - "NewTuple", - "NewTypeName", - "NewTypeParam", - "NewUnion", - "NewVar", - "Nil", - "Object", - "ObjectString", - "Package", - "PkgName", - "Pointer", - "Qualifier", - "RecvOnly", - "RelativeTo", - "Rune", - "Satisfies", - "Scope", - "Selection", - "SelectionKind", - "SelectionString", - "SendOnly", - "SendRecv", - "Signature", - "Sizes", - "SizesFor", - "Slice", - "StdSizes", - "String", - "Struct", - "Term", - "Tuple", - "Typ", - "Type", - "TypeAndValue", - "TypeList", - "TypeName", - "TypeParam", - "TypeParamList", - "TypeString", - "Uint", - "Uint16", - "Uint32", - "Uint64", - "Uint8", - "Uintptr", - "Union", - "Universe", - "Unsafe", - "UnsafePointer", - "UntypedBool", - "UntypedComplex", - "UntypedFloat", - "UntypedInt", - "UntypedNil", - "UntypedRune", - "UntypedString", - "Var", - "WriteExpr", - "WriteSignature", - "WriteType", - }, - "hash": { - "Hash", - "Hash32", - "Hash64", - }, - "hash/adler32": { - "Checksum", - "New", - "Size", - }, - "hash/crc32": { - "Castagnoli", - "Checksum", - "ChecksumIEEE", - "IEEE", - "IEEETable", - "Koopman", - "MakeTable", - "New", - "NewIEEE", - "Size", - "Table", - "Update", - }, - "hash/crc64": { - "Checksum", - "ECMA", - "ISO", - "MakeTable", - "New", - "Size", - "Table", - "Update", - }, - "hash/fnv": { - "New128", - "New128a", - "New32", - "New32a", - "New64", - "New64a", - }, - "hash/maphash": { - "Bytes", - "Hash", - "MakeSeed", - "Seed", - "String", - }, - "html": { - "EscapeString", - "UnescapeString", - }, - "html/template": { - "CSS", - "ErrAmbigContext", - "ErrBadHTML", - "ErrBranchEnd", - "ErrEndContext", - "ErrJSTemplate", - "ErrNoSuchTemplate", - "ErrOutputContext", - "ErrPartialCharset", - "ErrPartialEscape", - "ErrPredefinedEscaper", - "ErrRangeLoopReentry", - "ErrSlashAmbig", - "Error", - "ErrorCode", - "FuncMap", - "HTML", - "HTMLAttr", - "HTMLEscape", - "HTMLEscapeString", - "HTMLEscaper", - "IsTrue", - "JS", - "JSEscape", - "JSEscapeString", - "JSEscaper", - "JSStr", - "Must", - "New", - "OK", - "ParseFS", - "ParseFiles", - "ParseGlob", - "Srcset", - "Template", - "URL", - "URLQueryEscaper", - }, - "image": { - "Alpha", - "Alpha16", - "Black", - "CMYK", - "Config", - "Decode", - "DecodeConfig", - "ErrFormat", - "Gray", - "Gray16", - "Image", - "NRGBA", - "NRGBA64", - "NYCbCrA", - "NewAlpha", - "NewAlpha16", - "NewCMYK", - "NewGray", - "NewGray16", - "NewNRGBA", - "NewNRGBA64", - "NewNYCbCrA", - "NewPaletted", - "NewRGBA", - "NewRGBA64", - "NewUniform", - "NewYCbCr", - "Opaque", - "Paletted", - "PalettedImage", - "Point", - "Pt", - "RGBA", - "RGBA64", - "RGBA64Image", - "Rect", - "Rectangle", - "RegisterFormat", - "Transparent", - "Uniform", - "White", - "YCbCr", - "YCbCrSubsampleRatio", - "YCbCrSubsampleRatio410", - "YCbCrSubsampleRatio411", - "YCbCrSubsampleRatio420", - "YCbCrSubsampleRatio422", - "YCbCrSubsampleRatio440", - "YCbCrSubsampleRatio444", - "ZP", - "ZR", - }, - "image/color": { - "Alpha", - "Alpha16", - "Alpha16Model", - "AlphaModel", - "Black", - "CMYK", - "CMYKModel", - "CMYKToRGB", - "Color", - "Gray", - "Gray16", - "Gray16Model", - "GrayModel", - "Model", - "ModelFunc", - "NRGBA", - "NRGBA64", - "NRGBA64Model", - "NRGBAModel", - "NYCbCrA", - "NYCbCrAModel", - "Opaque", - "Palette", - "RGBA", - "RGBA64", - "RGBA64Model", - "RGBAModel", - "RGBToCMYK", - "RGBToYCbCr", - "Transparent", - "White", - "YCbCr", - "YCbCrModel", - "YCbCrToRGB", - }, - "image/color/palette": { - "Plan9", - "WebSafe", - }, - "image/draw": { - "Draw", - "DrawMask", - "Drawer", - "FloydSteinberg", - "Image", - "Op", - "Over", - "Quantizer", - "RGBA64Image", - "Src", - }, - "image/gif": { - "Decode", - "DecodeAll", - "DecodeConfig", - "DisposalBackground", - "DisposalNone", - "DisposalPrevious", - "Encode", - "EncodeAll", - "GIF", - "Options", - }, - "image/jpeg": { - "Decode", - "DecodeConfig", - "DefaultQuality", - "Encode", - "FormatError", - "Options", - "Reader", - "UnsupportedError", - }, - "image/png": { - "BestCompression", - "BestSpeed", - "CompressionLevel", - "Decode", - "DecodeConfig", - "DefaultCompression", - "Encode", - "Encoder", - "EncoderBuffer", - "EncoderBufferPool", - "FormatError", - "NoCompression", - "UnsupportedError", - }, - "index/suffixarray": { - "Index", - "New", - }, - "io": { - "ByteReader", - "ByteScanner", - "ByteWriter", - "Closer", - "Copy", - "CopyBuffer", - "CopyN", - "Discard", - "EOF", - "ErrClosedPipe", - "ErrNoProgress", - "ErrShortBuffer", - "ErrShortWrite", - "ErrUnexpectedEOF", - "LimitReader", - "LimitedReader", - "MultiReader", - "MultiWriter", - "NewOffsetWriter", - "NewSectionReader", - "NopCloser", - "OffsetWriter", - "Pipe", - "PipeReader", - "PipeWriter", - "ReadAll", - "ReadAtLeast", - "ReadCloser", - "ReadFull", - "ReadSeekCloser", - "ReadSeeker", - "ReadWriteCloser", - "ReadWriteSeeker", - "ReadWriter", - "Reader", - "ReaderAt", - "ReaderFrom", - "RuneReader", - "RuneScanner", - "SectionReader", - "SeekCurrent", - "SeekEnd", - "SeekStart", - "Seeker", - "StringWriter", - "TeeReader", - "WriteCloser", - "WriteSeeker", - "WriteString", - "Writer", - "WriterAt", - "WriterTo", - }, - "io/fs": { - "DirEntry", - "ErrClosed", - "ErrExist", - "ErrInvalid", - "ErrNotExist", - "ErrPermission", - "FS", - "File", - "FileInfo", - "FileInfoToDirEntry", - "FileMode", - "FormatDirEntry", - "FormatFileInfo", - "Glob", - "GlobFS", - "ModeAppend", - "ModeCharDevice", - "ModeDevice", - "ModeDir", - "ModeExclusive", - "ModeIrregular", - "ModeNamedPipe", - "ModePerm", - "ModeSetgid", - "ModeSetuid", - "ModeSocket", - "ModeSticky", - "ModeSymlink", - "ModeTemporary", - "ModeType", - "PathError", - "ReadDir", - "ReadDirFS", - "ReadDirFile", - "ReadFile", - "ReadFileFS", - "SkipAll", - "SkipDir", - "Stat", - "StatFS", - "Sub", - "SubFS", - "ValidPath", - "WalkDir", - "WalkDirFunc", - }, - "io/ioutil": { - "Discard", - "NopCloser", - "ReadAll", - "ReadDir", - "ReadFile", - "TempDir", - "TempFile", - "WriteFile", - }, - "log": { - "Default", - "Fatal", - "Fatalf", - "Fatalln", - "Flags", - "LUTC", - "Ldate", - "Llongfile", - "Lmicroseconds", - "Lmsgprefix", - "Logger", - "Lshortfile", - "LstdFlags", - "Ltime", - "New", - "Output", - "Panic", - "Panicf", - "Panicln", - "Prefix", - "Print", - "Printf", - "Println", - "SetFlags", - "SetOutput", - "SetPrefix", - "Writer", - }, - "log/slog": { - "Any", - "AnyValue", - "Attr", - "Bool", - "BoolValue", - "Debug", - "DebugContext", - "Default", - "Duration", - "DurationValue", - "Error", - "ErrorContext", - "Float64", - "Float64Value", - "Group", - "GroupValue", - "Handler", - "HandlerOptions", - "Info", - "InfoContext", - "Int", - "Int64", - "Int64Value", - "IntValue", - "JSONHandler", - "Kind", - "KindAny", - "KindBool", - "KindDuration", - "KindFloat64", - "KindGroup", - "KindInt64", - "KindLogValuer", - "KindString", - "KindTime", - "KindUint64", - "Level", - "LevelDebug", - "LevelError", - "LevelInfo", - "LevelKey", - "LevelVar", - "LevelWarn", - "Leveler", - "Log", - "LogAttrs", - "LogValuer", - "Logger", - "MessageKey", - "New", - "NewJSONHandler", - "NewLogLogger", - "NewRecord", - "NewTextHandler", - "Record", - "SetDefault", - "Source", - "SourceKey", - "String", - "StringValue", - "TextHandler", - "Time", - "TimeKey", - "TimeValue", - "Uint64", - "Uint64Value", - "Value", - "Warn", - "WarnContext", - "With", - }, - "log/syslog": { - "Dial", - "LOG_ALERT", - "LOG_AUTH", - "LOG_AUTHPRIV", - "LOG_CRIT", - "LOG_CRON", - "LOG_DAEMON", - "LOG_DEBUG", - "LOG_EMERG", - "LOG_ERR", - "LOG_FTP", - "LOG_INFO", - "LOG_KERN", - "LOG_LOCAL0", - "LOG_LOCAL1", - "LOG_LOCAL2", - "LOG_LOCAL3", - "LOG_LOCAL4", - "LOG_LOCAL5", - "LOG_LOCAL6", - "LOG_LOCAL7", - "LOG_LPR", - "LOG_MAIL", - "LOG_NEWS", - "LOG_NOTICE", - "LOG_SYSLOG", - "LOG_USER", - "LOG_UUCP", - "LOG_WARNING", - "New", - "NewLogger", - "Priority", - "Writer", - }, - "maps": { - "Clone", - "Copy", - "DeleteFunc", - "Equal", - "EqualFunc", - }, - "math": { - "Abs", - "Acos", - "Acosh", - "Asin", - "Asinh", - "Atan", - "Atan2", - "Atanh", - "Cbrt", - "Ceil", - "Copysign", - "Cos", - "Cosh", - "Dim", - "E", - "Erf", - "Erfc", - "Erfcinv", - "Erfinv", - "Exp", - "Exp2", - "Expm1", - "FMA", - "Float32bits", - "Float32frombits", - "Float64bits", - "Float64frombits", - "Floor", - "Frexp", - "Gamma", - "Hypot", - "Ilogb", - "Inf", - "IsInf", - "IsNaN", - "J0", - "J1", - "Jn", - "Ldexp", - "Lgamma", - "Ln10", - "Ln2", - "Log", - "Log10", - "Log10E", - "Log1p", - "Log2", - "Log2E", - "Logb", - "Max", - "MaxFloat32", - "MaxFloat64", - "MaxInt", - "MaxInt16", - "MaxInt32", - "MaxInt64", - "MaxInt8", - "MaxUint", - "MaxUint16", - "MaxUint32", - "MaxUint64", - "MaxUint8", - "Min", - "MinInt", - "MinInt16", - "MinInt32", - "MinInt64", - "MinInt8", - "Mod", - "Modf", - "NaN", - "Nextafter", - "Nextafter32", - "Phi", - "Pi", - "Pow", - "Pow10", - "Remainder", - "Round", - "RoundToEven", - "Signbit", - "Sin", - "Sincos", - "Sinh", - "SmallestNonzeroFloat32", - "SmallestNonzeroFloat64", - "Sqrt", - "Sqrt2", - "SqrtE", - "SqrtPhi", - "SqrtPi", - "Tan", - "Tanh", - "Trunc", - "Y0", - "Y1", - "Yn", - }, - "math/big": { - "Above", - "Accuracy", - "AwayFromZero", - "Below", - "ErrNaN", - "Exact", - "Float", - "Int", - "Jacobi", - "MaxBase", - "MaxExp", - "MaxPrec", - "MinExp", - "NewFloat", - "NewInt", - "NewRat", - "ParseFloat", - "Rat", - "RoundingMode", - "ToNearestAway", - "ToNearestEven", - "ToNegativeInf", - "ToPositiveInf", - "ToZero", - "Word", - }, - "math/bits": { - "Add", - "Add32", - "Add64", - "Div", - "Div32", - "Div64", - "LeadingZeros", - "LeadingZeros16", - "LeadingZeros32", - "LeadingZeros64", - "LeadingZeros8", - "Len", - "Len16", - "Len32", - "Len64", - "Len8", - "Mul", - "Mul32", - "Mul64", - "OnesCount", - "OnesCount16", - "OnesCount32", - "OnesCount64", - "OnesCount8", - "Rem", - "Rem32", - "Rem64", - "Reverse", - "Reverse16", - "Reverse32", - "Reverse64", - "Reverse8", - "ReverseBytes", - "ReverseBytes16", - "ReverseBytes32", - "ReverseBytes64", - "RotateLeft", - "RotateLeft16", - "RotateLeft32", - "RotateLeft64", - "RotateLeft8", - "Sub", - "Sub32", - "Sub64", - "TrailingZeros", - "TrailingZeros16", - "TrailingZeros32", - "TrailingZeros64", - "TrailingZeros8", - "UintSize", - }, - "math/cmplx": { - "Abs", - "Acos", - "Acosh", - "Asin", - "Asinh", - "Atan", - "Atanh", - "Conj", - "Cos", - "Cosh", - "Cot", - "Exp", - "Inf", - "IsInf", - "IsNaN", - "Log", - "Log10", - "NaN", - "Phase", - "Polar", - "Pow", - "Rect", - "Sin", - "Sinh", - "Sqrt", - "Tan", - "Tanh", - }, - "math/rand": { - "ExpFloat64", - "Float32", - "Float64", - "Int", - "Int31", - "Int31n", - "Int63", - "Int63n", - "Intn", - "New", - "NewSource", - "NewZipf", - "NormFloat64", - "Perm", - "Rand", - "Read", - "Seed", - "Shuffle", - "Source", - "Source64", - "Uint32", - "Uint64", - "Zipf", - }, - "mime": { - "AddExtensionType", - "BEncoding", - "ErrInvalidMediaParameter", - "ExtensionsByType", - "FormatMediaType", - "ParseMediaType", - "QEncoding", - "TypeByExtension", - "WordDecoder", - "WordEncoder", - }, - "mime/multipart": { - "ErrMessageTooLarge", - "File", - "FileHeader", - "Form", - "NewReader", - "NewWriter", - "Part", - "Reader", - "Writer", - }, - "mime/quotedprintable": { - "NewReader", - "NewWriter", - "Reader", - "Writer", - }, - "net": { - "Addr", - "AddrError", - "Buffers", - "CIDRMask", - "Conn", - "DNSConfigError", - "DNSError", - "DefaultResolver", - "Dial", - "DialIP", - "DialTCP", - "DialTimeout", - "DialUDP", - "DialUnix", - "Dialer", - "ErrClosed", - "ErrWriteToConnected", - "Error", - "FileConn", - "FileListener", - "FilePacketConn", - "FlagBroadcast", - "FlagLoopback", - "FlagMulticast", - "FlagPointToPoint", - "FlagRunning", - "FlagUp", - "Flags", - "HardwareAddr", - "IP", - "IPAddr", - "IPConn", - "IPMask", - "IPNet", - "IPv4", - "IPv4Mask", - "IPv4allrouter", - "IPv4allsys", - "IPv4bcast", - "IPv4len", - "IPv4zero", - "IPv6interfacelocalallnodes", - "IPv6len", - "IPv6linklocalallnodes", - "IPv6linklocalallrouters", - "IPv6loopback", - "IPv6unspecified", - "IPv6zero", - "Interface", - "InterfaceAddrs", - "InterfaceByIndex", - "InterfaceByName", - "Interfaces", - "InvalidAddrError", - "JoinHostPort", - "Listen", - "ListenConfig", - "ListenIP", - "ListenMulticastUDP", - "ListenPacket", - "ListenTCP", - "ListenUDP", - "ListenUnix", - "ListenUnixgram", - "Listener", - "LookupAddr", - "LookupCNAME", - "LookupHost", - "LookupIP", - "LookupMX", - "LookupNS", - "LookupPort", - "LookupSRV", - "LookupTXT", - "MX", - "NS", - "OpError", - "PacketConn", - "ParseCIDR", - "ParseError", - "ParseIP", - "ParseMAC", - "Pipe", - "ResolveIPAddr", - "ResolveTCPAddr", - "ResolveUDPAddr", - "ResolveUnixAddr", - "Resolver", - "SRV", - "SplitHostPort", - "TCPAddr", - "TCPAddrFromAddrPort", - "TCPConn", - "TCPListener", - "UDPAddr", - "UDPAddrFromAddrPort", - "UDPConn", - "UnixAddr", - "UnixConn", - "UnixListener", - "UnknownNetworkError", - }, - "net/http": { - "AllowQuerySemicolons", - "CanonicalHeaderKey", - "Client", - "CloseNotifier", - "ConnState", - "Cookie", - "CookieJar", - "DefaultClient", - "DefaultMaxHeaderBytes", - "DefaultMaxIdleConnsPerHost", - "DefaultServeMux", - "DefaultTransport", - "DetectContentType", - "Dir", - "ErrAbortHandler", - "ErrBodyNotAllowed", - "ErrBodyReadAfterClose", - "ErrContentLength", - "ErrHandlerTimeout", - "ErrHeaderTooLong", - "ErrHijacked", - "ErrLineTooLong", - "ErrMissingBoundary", - "ErrMissingContentLength", - "ErrMissingFile", - "ErrNoCookie", - "ErrNoLocation", - "ErrNotMultipart", - "ErrNotSupported", - "ErrSchemeMismatch", - "ErrServerClosed", - "ErrShortBody", - "ErrSkipAltProtocol", - "ErrUnexpectedTrailer", - "ErrUseLastResponse", - "ErrWriteAfterFlush", - "Error", - "FS", - "File", - "FileServer", - "FileSystem", - "Flusher", - "Get", - "Handle", - "HandleFunc", - "Handler", - "HandlerFunc", - "Head", - "Header", - "Hijacker", - "ListenAndServe", - "ListenAndServeTLS", - "LocalAddrContextKey", - "MaxBytesError", - "MaxBytesHandler", - "MaxBytesReader", - "MethodConnect", - "MethodDelete", - "MethodGet", - "MethodHead", - "MethodOptions", - "MethodPatch", - "MethodPost", - "MethodPut", - "MethodTrace", - "NewFileTransport", - "NewRequest", - "NewRequestWithContext", - "NewResponseController", - "NewServeMux", - "NoBody", - "NotFound", - "NotFoundHandler", - "ParseHTTPVersion", - "ParseTime", - "Post", - "PostForm", - "ProtocolError", - "ProxyFromEnvironment", - "ProxyURL", - "PushOptions", - "Pusher", - "ReadRequest", - "ReadResponse", - "Redirect", - "RedirectHandler", - "Request", - "Response", - "ResponseController", - "ResponseWriter", - "RoundTripper", - "SameSite", - "SameSiteDefaultMode", - "SameSiteLaxMode", - "SameSiteNoneMode", - "SameSiteStrictMode", - "Serve", - "ServeContent", - "ServeFile", - "ServeMux", - "ServeTLS", - "Server", - "ServerContextKey", - "SetCookie", - "StateActive", - "StateClosed", - "StateHijacked", - "StateIdle", - "StateNew", - "StatusAccepted", - "StatusAlreadyReported", - "StatusBadGateway", - "StatusBadRequest", - "StatusConflict", - "StatusContinue", - "StatusCreated", - "StatusEarlyHints", - "StatusExpectationFailed", - "StatusFailedDependency", - "StatusForbidden", - "StatusFound", - "StatusGatewayTimeout", - "StatusGone", - "StatusHTTPVersionNotSupported", - "StatusIMUsed", - "StatusInsufficientStorage", - "StatusInternalServerError", - "StatusLengthRequired", - "StatusLocked", - "StatusLoopDetected", - "StatusMethodNotAllowed", - "StatusMisdirectedRequest", - "StatusMovedPermanently", - "StatusMultiStatus", - "StatusMultipleChoices", - "StatusNetworkAuthenticationRequired", - "StatusNoContent", - "StatusNonAuthoritativeInfo", - "StatusNotAcceptable", - "StatusNotExtended", - "StatusNotFound", - "StatusNotImplemented", - "StatusNotModified", - "StatusOK", - "StatusPartialContent", - "StatusPaymentRequired", - "StatusPermanentRedirect", - "StatusPreconditionFailed", - "StatusPreconditionRequired", - "StatusProcessing", - "StatusProxyAuthRequired", - "StatusRequestEntityTooLarge", - "StatusRequestHeaderFieldsTooLarge", - "StatusRequestTimeout", - "StatusRequestURITooLong", - "StatusRequestedRangeNotSatisfiable", - "StatusResetContent", - "StatusSeeOther", - "StatusServiceUnavailable", - "StatusSwitchingProtocols", - "StatusTeapot", - "StatusTemporaryRedirect", - "StatusText", - "StatusTooEarly", - "StatusTooManyRequests", - "StatusUnauthorized", - "StatusUnavailableForLegalReasons", - "StatusUnprocessableEntity", - "StatusUnsupportedMediaType", - "StatusUpgradeRequired", - "StatusUseProxy", - "StatusVariantAlsoNegotiates", - "StripPrefix", - "TimeFormat", - "TimeoutHandler", - "TrailerPrefix", - "Transport", - }, - "net/http/cgi": { - "Handler", - "Request", - "RequestFromMap", - "Serve", - }, - "net/http/cookiejar": { - "Jar", - "New", - "Options", - "PublicSuffixList", - }, - "net/http/fcgi": { - "ErrConnClosed", - "ErrRequestAborted", - "ProcessEnv", - "Serve", - }, - "net/http/httptest": { - "DefaultRemoteAddr", - "NewRecorder", - "NewRequest", - "NewServer", - "NewTLSServer", - "NewUnstartedServer", - "ResponseRecorder", - "Server", - }, - "net/http/httptrace": { - "ClientTrace", - "ContextClientTrace", - "DNSDoneInfo", - "DNSStartInfo", - "GotConnInfo", - "WithClientTrace", - "WroteRequestInfo", - }, - "net/http/httputil": { - "BufferPool", - "ClientConn", - "DumpRequest", - "DumpRequestOut", - "DumpResponse", - "ErrClosed", - "ErrLineTooLong", - "ErrPersistEOF", - "ErrPipeline", - "NewChunkedReader", - "NewChunkedWriter", - "NewClientConn", - "NewProxyClientConn", - "NewServerConn", - "NewSingleHostReverseProxy", - "ProxyRequest", - "ReverseProxy", - "ServerConn", - }, - "net/http/pprof": { - "Cmdline", - "Handler", - "Index", - "Profile", - "Symbol", - "Trace", - }, - "net/mail": { - "Address", - "AddressParser", - "ErrHeaderNotPresent", - "Header", - "Message", - "ParseAddress", - "ParseAddressList", - "ParseDate", - "ReadMessage", - }, - "net/netip": { - "Addr", - "AddrFrom16", - "AddrFrom4", - "AddrFromSlice", - "AddrPort", - "AddrPortFrom", - "IPv4Unspecified", - "IPv6LinkLocalAllNodes", - "IPv6LinkLocalAllRouters", - "IPv6Loopback", - "IPv6Unspecified", - "MustParseAddr", - "MustParseAddrPort", - "MustParsePrefix", - "ParseAddr", - "ParseAddrPort", - "ParsePrefix", - "Prefix", - "PrefixFrom", - }, - "net/rpc": { - "Accept", - "Call", - "Client", - "ClientCodec", - "DefaultDebugPath", - "DefaultRPCPath", - "DefaultServer", - "Dial", - "DialHTTP", - "DialHTTPPath", - "ErrShutdown", - "HandleHTTP", - "NewClient", - "NewClientWithCodec", - "NewServer", - "Register", - "RegisterName", - "Request", - "Response", - "ServeCodec", - "ServeConn", - "ServeRequest", - "Server", - "ServerCodec", - "ServerError", - }, - "net/rpc/jsonrpc": { - "Dial", - "NewClient", - "NewClientCodec", - "NewServerCodec", - "ServeConn", - }, - "net/smtp": { - "Auth", - "CRAMMD5Auth", - "Client", - "Dial", - "NewClient", - "PlainAuth", - "SendMail", - "ServerInfo", - }, - "net/textproto": { - "CanonicalMIMEHeaderKey", - "Conn", - "Dial", - "Error", - "MIMEHeader", - "NewConn", - "NewReader", - "NewWriter", - "Pipeline", - "ProtocolError", - "Reader", - "TrimBytes", - "TrimString", - "Writer", - }, - "net/url": { - "Error", - "EscapeError", - "InvalidHostError", - "JoinPath", - "Parse", - "ParseQuery", - "ParseRequestURI", - "PathEscape", - "PathUnescape", - "QueryEscape", - "QueryUnescape", - "URL", - "User", - "UserPassword", - "Userinfo", - "Values", - }, - "os": { - "Args", - "Chdir", - "Chmod", - "Chown", - "Chtimes", - "Clearenv", - "Create", - "CreateTemp", - "DevNull", - "DirEntry", - "DirFS", - "Environ", - "ErrClosed", - "ErrDeadlineExceeded", - "ErrExist", - "ErrInvalid", - "ErrNoDeadline", - "ErrNotExist", - "ErrPermission", - "ErrProcessDone", - "Executable", - "Exit", - "Expand", - "ExpandEnv", - "File", - "FileInfo", - "FileMode", - "FindProcess", - "Getegid", - "Getenv", - "Geteuid", - "Getgid", - "Getgroups", - "Getpagesize", - "Getpid", - "Getppid", - "Getuid", - "Getwd", - "Hostname", - "Interrupt", - "IsExist", - "IsNotExist", - "IsPathSeparator", - "IsPermission", - "IsTimeout", - "Kill", - "Lchown", - "Link", - "LinkError", - "LookupEnv", - "Lstat", - "Mkdir", - "MkdirAll", - "MkdirTemp", - "ModeAppend", - "ModeCharDevice", - "ModeDevice", - "ModeDir", - "ModeExclusive", - "ModeIrregular", - "ModeNamedPipe", - "ModePerm", - "ModeSetgid", - "ModeSetuid", - "ModeSocket", - "ModeSticky", - "ModeSymlink", - "ModeTemporary", - "ModeType", - "NewFile", - "NewSyscallError", - "O_APPEND", - "O_CREATE", - "O_EXCL", - "O_RDONLY", - "O_RDWR", - "O_SYNC", - "O_TRUNC", - "O_WRONLY", - "Open", - "OpenFile", - "PathError", - "PathListSeparator", - "PathSeparator", - "Pipe", - "ProcAttr", - "Process", - "ProcessState", - "ReadDir", - "ReadFile", - "Readlink", - "Remove", - "RemoveAll", - "Rename", - "SEEK_CUR", - "SEEK_END", - "SEEK_SET", - "SameFile", - "Setenv", - "Signal", - "StartProcess", - "Stat", - "Stderr", - "Stdin", - "Stdout", - "Symlink", - "SyscallError", - "TempDir", - "Truncate", - "Unsetenv", - "UserCacheDir", - "UserConfigDir", - "UserHomeDir", - "WriteFile", - }, - "os/exec": { - "Cmd", - "Command", - "CommandContext", - "ErrDot", - "ErrNotFound", - "ErrWaitDelay", - "Error", - "ExitError", - "LookPath", - }, - "os/signal": { - "Ignore", - "Ignored", - "Notify", - "NotifyContext", - "Reset", - "Stop", - }, - "os/user": { - "Current", - "Group", - "Lookup", - "LookupGroup", - "LookupGroupId", - "LookupId", - "UnknownGroupError", - "UnknownGroupIdError", - "UnknownUserError", - "UnknownUserIdError", - "User", - }, - "path": { - "Base", - "Clean", - "Dir", - "ErrBadPattern", - "Ext", - "IsAbs", - "Join", - "Match", - "Split", - }, - "path/filepath": { - "Abs", - "Base", - "Clean", - "Dir", - "ErrBadPattern", - "EvalSymlinks", - "Ext", - "FromSlash", - "Glob", - "HasPrefix", - "IsAbs", - "IsLocal", - "Join", - "ListSeparator", - "Match", - "Rel", - "Separator", - "SkipAll", - "SkipDir", - "Split", - "SplitList", - "ToSlash", - "VolumeName", - "Walk", - "WalkDir", - "WalkFunc", - }, - "plugin": { - "Open", - "Plugin", - "Symbol", - }, - "reflect": { - "Append", - "AppendSlice", - "Array", - "ArrayOf", - "Bool", - "BothDir", - "Chan", - "ChanDir", - "ChanOf", - "Complex128", - "Complex64", - "Copy", - "DeepEqual", - "Float32", - "Float64", - "Func", - "FuncOf", - "Indirect", - "Int", - "Int16", - "Int32", - "Int64", - "Int8", - "Interface", - "Invalid", - "Kind", - "MakeChan", - "MakeFunc", - "MakeMap", - "MakeMapWithSize", - "MakeSlice", - "Map", - "MapIter", - "MapOf", - "Method", - "New", - "NewAt", - "Pointer", - "PointerTo", - "Ptr", - "PtrTo", - "RecvDir", - "Select", - "SelectCase", - "SelectDefault", - "SelectDir", - "SelectRecv", - "SelectSend", - "SendDir", - "Slice", - "SliceHeader", - "SliceOf", - "String", - "StringHeader", - "Struct", - "StructField", - "StructOf", - "StructTag", - "Swapper", - "Type", - "TypeOf", - "Uint", - "Uint16", - "Uint32", - "Uint64", - "Uint8", - "Uintptr", - "UnsafePointer", - "Value", - "ValueError", - "ValueOf", - "VisibleFields", - "Zero", - }, - "regexp": { - "Compile", - "CompilePOSIX", - "Match", - "MatchReader", - "MatchString", - "MustCompile", - "MustCompilePOSIX", - "QuoteMeta", - "Regexp", - }, - "regexp/syntax": { - "ClassNL", - "Compile", - "DotNL", - "EmptyBeginLine", - "EmptyBeginText", - "EmptyEndLine", - "EmptyEndText", - "EmptyNoWordBoundary", - "EmptyOp", - "EmptyOpContext", - "EmptyWordBoundary", - "ErrInternalError", - "ErrInvalidCharClass", - "ErrInvalidCharRange", - "ErrInvalidEscape", - "ErrInvalidNamedCapture", - "ErrInvalidPerlOp", - "ErrInvalidRepeatOp", - "ErrInvalidRepeatSize", - "ErrInvalidUTF8", - "ErrLarge", - "ErrMissingBracket", - "ErrMissingParen", - "ErrMissingRepeatArgument", - "ErrNestingDepth", - "ErrTrailingBackslash", - "ErrUnexpectedParen", - "Error", - "ErrorCode", - "Flags", - "FoldCase", - "Inst", - "InstAlt", - "InstAltMatch", - "InstCapture", - "InstEmptyWidth", - "InstFail", - "InstMatch", - "InstNop", - "InstOp", - "InstRune", - "InstRune1", - "InstRuneAny", - "InstRuneAnyNotNL", - "IsWordChar", - "Literal", - "MatchNL", - "NonGreedy", - "OneLine", - "Op", - "OpAlternate", - "OpAnyChar", - "OpAnyCharNotNL", - "OpBeginLine", - "OpBeginText", - "OpCapture", - "OpCharClass", - "OpConcat", - "OpEmptyMatch", - "OpEndLine", - "OpEndText", - "OpLiteral", - "OpNoMatch", - "OpNoWordBoundary", - "OpPlus", - "OpQuest", - "OpRepeat", - "OpStar", - "OpWordBoundary", - "POSIX", - "Parse", - "Perl", - "PerlX", - "Prog", - "Regexp", - "Simple", - "UnicodeGroups", - "WasDollar", - }, - "runtime": { - "BlockProfile", - "BlockProfileRecord", - "Breakpoint", - "CPUProfile", - "Caller", - "Callers", - "CallersFrames", - "Compiler", - "Error", - "Frame", - "Frames", - "Func", - "FuncForPC", - "GC", - "GOARCH", - "GOMAXPROCS", - "GOOS", - "GOROOT", - "Goexit", - "GoroutineProfile", - "Gosched", - "KeepAlive", - "LockOSThread", - "MemProfile", - "MemProfileRate", - "MemProfileRecord", - "MemStats", - "MutexProfile", - "NumCPU", - "NumCgoCall", - "NumGoroutine", - "PanicNilError", - "Pinner", - "ReadMemStats", - "ReadTrace", - "SetBlockProfileRate", - "SetCPUProfileRate", - "SetCgoTraceback", - "SetFinalizer", - "SetMutexProfileFraction", - "Stack", - "StackRecord", - "StartTrace", - "StopTrace", - "ThreadCreateProfile", - "TypeAssertionError", - "UnlockOSThread", - "Version", - }, - "runtime/cgo": { - "Handle", - "Incomplete", - "NewHandle", - }, - "runtime/coverage": { - "ClearCounters", - "WriteCounters", - "WriteCountersDir", - "WriteMeta", - "WriteMetaDir", - }, - "runtime/debug": { - "BuildInfo", - "BuildSetting", - "FreeOSMemory", - "GCStats", - "Module", - "ParseBuildInfo", - "PrintStack", - "ReadBuildInfo", - "ReadGCStats", - "SetGCPercent", - "SetMaxStack", - "SetMaxThreads", - "SetMemoryLimit", - "SetPanicOnFault", - "SetTraceback", - "Stack", - "WriteHeapDump", - }, - "runtime/metrics": { - "All", - "Description", - "Float64Histogram", - "KindBad", - "KindFloat64", - "KindFloat64Histogram", - "KindUint64", - "Read", - "Sample", - "Value", - "ValueKind", - }, - "runtime/pprof": { - "Do", - "ForLabels", - "Label", - "LabelSet", - "Labels", - "Lookup", - "NewProfile", - "Profile", - "Profiles", - "SetGoroutineLabels", - "StartCPUProfile", - "StopCPUProfile", - "WithLabels", - "WriteHeapProfile", - }, - "runtime/trace": { - "IsEnabled", - "Log", - "Logf", - "NewTask", - "Region", - "Start", - "StartRegion", - "Stop", - "Task", - "WithRegion", - }, - "slices": { - "BinarySearch", - "BinarySearchFunc", - "Clip", - "Clone", - "Compact", - "CompactFunc", - "Compare", - "CompareFunc", - "Contains", - "ContainsFunc", - "Delete", - "DeleteFunc", - "Equal", - "EqualFunc", - "Grow", - "Index", - "IndexFunc", - "Insert", - "IsSorted", - "IsSortedFunc", - "Max", - "MaxFunc", - "Min", - "MinFunc", - "Replace", - "Reverse", - "Sort", - "SortFunc", - "SortStableFunc", - }, - "sort": { - "Find", - "Float64Slice", - "Float64s", - "Float64sAreSorted", - "IntSlice", - "Interface", - "Ints", - "IntsAreSorted", - "IsSorted", - "Reverse", - "Search", - "SearchFloat64s", - "SearchInts", - "SearchStrings", - "Slice", - "SliceIsSorted", - "SliceStable", - "Sort", - "Stable", - "StringSlice", - "Strings", - "StringsAreSorted", - }, - "strconv": { - "AppendBool", - "AppendFloat", - "AppendInt", - "AppendQuote", - "AppendQuoteRune", - "AppendQuoteRuneToASCII", - "AppendQuoteRuneToGraphic", - "AppendQuoteToASCII", - "AppendQuoteToGraphic", - "AppendUint", - "Atoi", - "CanBackquote", - "ErrRange", - "ErrSyntax", - "FormatBool", - "FormatComplex", - "FormatFloat", - "FormatInt", - "FormatUint", - "IntSize", - "IsGraphic", - "IsPrint", - "Itoa", - "NumError", - "ParseBool", - "ParseComplex", - "ParseFloat", - "ParseInt", - "ParseUint", - "Quote", - "QuoteRune", - "QuoteRuneToASCII", - "QuoteRuneToGraphic", - "QuoteToASCII", - "QuoteToGraphic", - "QuotedPrefix", - "Unquote", - "UnquoteChar", - }, - "strings": { - "Builder", - "Clone", - "Compare", - "Contains", - "ContainsAny", - "ContainsFunc", - "ContainsRune", - "Count", - "Cut", - "CutPrefix", - "CutSuffix", - "EqualFold", - "Fields", - "FieldsFunc", - "HasPrefix", - "HasSuffix", - "Index", - "IndexAny", - "IndexByte", - "IndexFunc", - "IndexRune", - "Join", - "LastIndex", - "LastIndexAny", - "LastIndexByte", - "LastIndexFunc", - "Map", - "NewReader", - "NewReplacer", - "Reader", - "Repeat", - "Replace", - "ReplaceAll", - "Replacer", - "Split", - "SplitAfter", - "SplitAfterN", - "SplitN", - "Title", - "ToLower", - "ToLowerSpecial", - "ToTitle", - "ToTitleSpecial", - "ToUpper", - "ToUpperSpecial", - "ToValidUTF8", - "Trim", - "TrimFunc", - "TrimLeft", - "TrimLeftFunc", - "TrimPrefix", - "TrimRight", - "TrimRightFunc", - "TrimSpace", - "TrimSuffix", - }, - "sync": { - "Cond", - "Locker", - "Map", - "Mutex", - "NewCond", - "Once", - "OnceFunc", - "OnceValue", - "OnceValues", - "Pool", - "RWMutex", - "WaitGroup", - }, - "sync/atomic": { - "AddInt32", - "AddInt64", - "AddUint32", - "AddUint64", - "AddUintptr", - "Bool", - "CompareAndSwapInt32", - "CompareAndSwapInt64", - "CompareAndSwapPointer", - "CompareAndSwapUint32", - "CompareAndSwapUint64", - "CompareAndSwapUintptr", - "Int32", - "Int64", - "LoadInt32", - "LoadInt64", - "LoadPointer", - "LoadUint32", - "LoadUint64", - "LoadUintptr", - "Pointer", - "StoreInt32", - "StoreInt64", - "StorePointer", - "StoreUint32", - "StoreUint64", - "StoreUintptr", - "SwapInt32", - "SwapInt64", - "SwapPointer", - "SwapUint32", - "SwapUint64", - "SwapUintptr", - "Uint32", - "Uint64", - "Uintptr", - "Value", - }, - "syscall": { - "AF_ALG", - "AF_APPLETALK", - "AF_ARP", - "AF_ASH", - "AF_ATM", - "AF_ATMPVC", - "AF_ATMSVC", - "AF_AX25", - "AF_BLUETOOTH", - "AF_BRIDGE", - "AF_CAIF", - "AF_CAN", - "AF_CCITT", - "AF_CHAOS", - "AF_CNT", - "AF_COIP", - "AF_DATAKIT", - "AF_DECnet", - "AF_DLI", - "AF_E164", - "AF_ECMA", - "AF_ECONET", - "AF_ENCAP", - "AF_FILE", - "AF_HYLINK", - "AF_IEEE80211", - "AF_IEEE802154", - "AF_IMPLINK", - "AF_INET", - "AF_INET6", - "AF_INET6_SDP", - "AF_INET_SDP", - "AF_IPX", - "AF_IRDA", - "AF_ISDN", - "AF_ISO", - "AF_IUCV", - "AF_KEY", - "AF_LAT", - "AF_LINK", - "AF_LLC", - "AF_LOCAL", - "AF_MAX", - "AF_MPLS", - "AF_NATM", - "AF_NDRV", - "AF_NETBEUI", - "AF_NETBIOS", - "AF_NETGRAPH", - "AF_NETLINK", - "AF_NETROM", - "AF_NS", - "AF_OROUTE", - "AF_OSI", - "AF_PACKET", - "AF_PHONET", - "AF_PPP", - "AF_PPPOX", - "AF_PUP", - "AF_RDS", - "AF_RESERVED_36", - "AF_ROSE", - "AF_ROUTE", - "AF_RXRPC", - "AF_SCLUSTER", - "AF_SECURITY", - "AF_SIP", - "AF_SLOW", - "AF_SNA", - "AF_SYSTEM", - "AF_TIPC", - "AF_UNIX", - "AF_UNSPEC", - "AF_UTUN", - "AF_VENDOR00", - "AF_VENDOR01", - "AF_VENDOR02", - "AF_VENDOR03", - "AF_VENDOR04", - "AF_VENDOR05", - "AF_VENDOR06", - "AF_VENDOR07", - "AF_VENDOR08", - "AF_VENDOR09", - "AF_VENDOR10", - "AF_VENDOR11", - "AF_VENDOR12", - "AF_VENDOR13", - "AF_VENDOR14", - "AF_VENDOR15", - "AF_VENDOR16", - "AF_VENDOR17", - "AF_VENDOR18", - "AF_VENDOR19", - "AF_VENDOR20", - "AF_VENDOR21", - "AF_VENDOR22", - "AF_VENDOR23", - "AF_VENDOR24", - "AF_VENDOR25", - "AF_VENDOR26", - "AF_VENDOR27", - "AF_VENDOR28", - "AF_VENDOR29", - "AF_VENDOR30", - "AF_VENDOR31", - "AF_VENDOR32", - "AF_VENDOR33", - "AF_VENDOR34", - "AF_VENDOR35", - "AF_VENDOR36", - "AF_VENDOR37", - "AF_VENDOR38", - "AF_VENDOR39", - "AF_VENDOR40", - "AF_VENDOR41", - "AF_VENDOR42", - "AF_VENDOR43", - "AF_VENDOR44", - "AF_VENDOR45", - "AF_VENDOR46", - "AF_VENDOR47", - "AF_WANPIPE", - "AF_X25", - "AI_CANONNAME", - "AI_NUMERICHOST", - "AI_PASSIVE", - "APPLICATION_ERROR", - "ARPHRD_ADAPT", - "ARPHRD_APPLETLK", - "ARPHRD_ARCNET", - "ARPHRD_ASH", - "ARPHRD_ATM", - "ARPHRD_AX25", - "ARPHRD_BIF", - "ARPHRD_CHAOS", - "ARPHRD_CISCO", - "ARPHRD_CSLIP", - "ARPHRD_CSLIP6", - "ARPHRD_DDCMP", - "ARPHRD_DLCI", - "ARPHRD_ECONET", - "ARPHRD_EETHER", - "ARPHRD_ETHER", - "ARPHRD_EUI64", - "ARPHRD_FCAL", - "ARPHRD_FCFABRIC", - "ARPHRD_FCPL", - "ARPHRD_FCPP", - "ARPHRD_FDDI", - "ARPHRD_FRAD", - "ARPHRD_FRELAY", - "ARPHRD_HDLC", - "ARPHRD_HIPPI", - "ARPHRD_HWX25", - "ARPHRD_IEEE1394", - "ARPHRD_IEEE802", - "ARPHRD_IEEE80211", - "ARPHRD_IEEE80211_PRISM", - "ARPHRD_IEEE80211_RADIOTAP", - "ARPHRD_IEEE802154", - "ARPHRD_IEEE802154_PHY", - "ARPHRD_IEEE802_TR", - "ARPHRD_INFINIBAND", - "ARPHRD_IPDDP", - "ARPHRD_IPGRE", - "ARPHRD_IRDA", - "ARPHRD_LAPB", - "ARPHRD_LOCALTLK", - "ARPHRD_LOOPBACK", - "ARPHRD_METRICOM", - "ARPHRD_NETROM", - "ARPHRD_NONE", - "ARPHRD_PIMREG", - "ARPHRD_PPP", - "ARPHRD_PRONET", - "ARPHRD_RAWHDLC", - "ARPHRD_ROSE", - "ARPHRD_RSRVD", - "ARPHRD_SIT", - "ARPHRD_SKIP", - "ARPHRD_SLIP", - "ARPHRD_SLIP6", - "ARPHRD_STRIP", - "ARPHRD_TUNNEL", - "ARPHRD_TUNNEL6", - "ARPHRD_VOID", - "ARPHRD_X25", - "AUTHTYPE_CLIENT", - "AUTHTYPE_SERVER", - "Accept", - "Accept4", - "AcceptEx", - "Access", - "Acct", - "AddrinfoW", - "Adjtime", - "Adjtimex", - "AllThreadsSyscall", - "AllThreadsSyscall6", - "AttachLsf", - "B0", - "B1000000", - "B110", - "B115200", - "B1152000", - "B1200", - "B134", - "B14400", - "B150", - "B1500000", - "B1800", - "B19200", - "B200", - "B2000000", - "B230400", - "B2400", - "B2500000", - "B28800", - "B300", - "B3000000", - "B3500000", - "B38400", - "B4000000", - "B460800", - "B4800", - "B50", - "B500000", - "B57600", - "B576000", - "B600", - "B7200", - "B75", - "B76800", - "B921600", - "B9600", - "BASE_PROTOCOL", - "BIOCFEEDBACK", - "BIOCFLUSH", - "BIOCGBLEN", - "BIOCGDIRECTION", - "BIOCGDIRFILT", - "BIOCGDLT", - "BIOCGDLTLIST", - "BIOCGETBUFMODE", - "BIOCGETIF", - "BIOCGETZMAX", - "BIOCGFEEDBACK", - "BIOCGFILDROP", - "BIOCGHDRCMPLT", - "BIOCGRSIG", - "BIOCGRTIMEOUT", - "BIOCGSEESENT", - "BIOCGSTATS", - "BIOCGSTATSOLD", - "BIOCGTSTAMP", - "BIOCIMMEDIATE", - "BIOCLOCK", - "BIOCPROMISC", - "BIOCROTZBUF", - "BIOCSBLEN", - "BIOCSDIRECTION", - "BIOCSDIRFILT", - "BIOCSDLT", - "BIOCSETBUFMODE", - "BIOCSETF", - "BIOCSETFNR", - "BIOCSETIF", - "BIOCSETWF", - "BIOCSETZBUF", - "BIOCSFEEDBACK", - "BIOCSFILDROP", - "BIOCSHDRCMPLT", - "BIOCSRSIG", - "BIOCSRTIMEOUT", - "BIOCSSEESENT", - "BIOCSTCPF", - "BIOCSTSTAMP", - "BIOCSUDPF", - "BIOCVERSION", - "BPF_A", - "BPF_ABS", - "BPF_ADD", - "BPF_ALIGNMENT", - "BPF_ALIGNMENT32", - "BPF_ALU", - "BPF_AND", - "BPF_B", - "BPF_BUFMODE_BUFFER", - "BPF_BUFMODE_ZBUF", - "BPF_DFLTBUFSIZE", - "BPF_DIRECTION_IN", - "BPF_DIRECTION_OUT", - "BPF_DIV", - "BPF_H", - "BPF_IMM", - "BPF_IND", - "BPF_JA", - "BPF_JEQ", - "BPF_JGE", - "BPF_JGT", - "BPF_JMP", - "BPF_JSET", - "BPF_K", - "BPF_LD", - "BPF_LDX", - "BPF_LEN", - "BPF_LSH", - "BPF_MAJOR_VERSION", - "BPF_MAXBUFSIZE", - "BPF_MAXINSNS", - "BPF_MEM", - "BPF_MEMWORDS", - "BPF_MINBUFSIZE", - "BPF_MINOR_VERSION", - "BPF_MISC", - "BPF_MSH", - "BPF_MUL", - "BPF_NEG", - "BPF_OR", - "BPF_RELEASE", - "BPF_RET", - "BPF_RSH", - "BPF_ST", - "BPF_STX", - "BPF_SUB", - "BPF_TAX", - "BPF_TXA", - "BPF_T_BINTIME", - "BPF_T_BINTIME_FAST", - "BPF_T_BINTIME_MONOTONIC", - "BPF_T_BINTIME_MONOTONIC_FAST", - "BPF_T_FAST", - "BPF_T_FLAG_MASK", - "BPF_T_FORMAT_MASK", - "BPF_T_MICROTIME", - "BPF_T_MICROTIME_FAST", - "BPF_T_MICROTIME_MONOTONIC", - "BPF_T_MICROTIME_MONOTONIC_FAST", - "BPF_T_MONOTONIC", - "BPF_T_MONOTONIC_FAST", - "BPF_T_NANOTIME", - "BPF_T_NANOTIME_FAST", - "BPF_T_NANOTIME_MONOTONIC", - "BPF_T_NANOTIME_MONOTONIC_FAST", - "BPF_T_NONE", - "BPF_T_NORMAL", - "BPF_W", - "BPF_X", - "BRKINT", - "Bind", - "BindToDevice", - "BpfBuflen", - "BpfDatalink", - "BpfHdr", - "BpfHeadercmpl", - "BpfInsn", - "BpfInterface", - "BpfJump", - "BpfProgram", - "BpfStat", - "BpfStats", - "BpfStmt", - "BpfTimeout", - "BpfTimeval", - "BpfVersion", - "BpfZbuf", - "BpfZbufHeader", - "ByHandleFileInformation", - "BytePtrFromString", - "ByteSliceFromString", - "CCR0_FLUSH", - "CERT_CHAIN_POLICY_AUTHENTICODE", - "CERT_CHAIN_POLICY_AUTHENTICODE_TS", - "CERT_CHAIN_POLICY_BASE", - "CERT_CHAIN_POLICY_BASIC_CONSTRAINTS", - "CERT_CHAIN_POLICY_EV", - "CERT_CHAIN_POLICY_MICROSOFT_ROOT", - "CERT_CHAIN_POLICY_NT_AUTH", - "CERT_CHAIN_POLICY_SSL", - "CERT_E_CN_NO_MATCH", - "CERT_E_EXPIRED", - "CERT_E_PURPOSE", - "CERT_E_ROLE", - "CERT_E_UNTRUSTEDROOT", - "CERT_STORE_ADD_ALWAYS", - "CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG", - "CERT_STORE_PROV_MEMORY", - "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", - "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT", - "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", - "CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT", - "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", - "CERT_TRUST_INVALID_BASIC_CONSTRAINTS", - "CERT_TRUST_INVALID_EXTENSION", - "CERT_TRUST_INVALID_NAME_CONSTRAINTS", - "CERT_TRUST_INVALID_POLICY_CONSTRAINTS", - "CERT_TRUST_IS_CYCLIC", - "CERT_TRUST_IS_EXPLICIT_DISTRUST", - "CERT_TRUST_IS_NOT_SIGNATURE_VALID", - "CERT_TRUST_IS_NOT_TIME_VALID", - "CERT_TRUST_IS_NOT_VALID_FOR_USAGE", - "CERT_TRUST_IS_OFFLINE_REVOCATION", - "CERT_TRUST_IS_REVOKED", - "CERT_TRUST_IS_UNTRUSTED_ROOT", - "CERT_TRUST_NO_ERROR", - "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", - "CERT_TRUST_REVOCATION_STATUS_UNKNOWN", - "CFLUSH", - "CLOCAL", - "CLONE_CHILD_CLEARTID", - "CLONE_CHILD_SETTID", - "CLONE_CLEAR_SIGHAND", - "CLONE_CSIGNAL", - "CLONE_DETACHED", - "CLONE_FILES", - "CLONE_FS", - "CLONE_INTO_CGROUP", - "CLONE_IO", - "CLONE_NEWCGROUP", - "CLONE_NEWIPC", - "CLONE_NEWNET", - "CLONE_NEWNS", - "CLONE_NEWPID", - "CLONE_NEWTIME", - "CLONE_NEWUSER", - "CLONE_NEWUTS", - "CLONE_PARENT", - "CLONE_PARENT_SETTID", - "CLONE_PID", - "CLONE_PIDFD", - "CLONE_PTRACE", - "CLONE_SETTLS", - "CLONE_SIGHAND", - "CLONE_SYSVSEM", - "CLONE_THREAD", - "CLONE_UNTRACED", - "CLONE_VFORK", - "CLONE_VM", - "CPUID_CFLUSH", - "CREAD", - "CREATE_ALWAYS", - "CREATE_NEW", - "CREATE_NEW_PROCESS_GROUP", - "CREATE_UNICODE_ENVIRONMENT", - "CRYPT_DEFAULT_CONTAINER_OPTIONAL", - "CRYPT_DELETEKEYSET", - "CRYPT_MACHINE_KEYSET", - "CRYPT_NEWKEYSET", - "CRYPT_SILENT", - "CRYPT_VERIFYCONTEXT", - "CS5", - "CS6", - "CS7", - "CS8", - "CSIZE", - "CSTART", - "CSTATUS", - "CSTOP", - "CSTOPB", - "CSUSP", - "CTL_MAXNAME", - "CTL_NET", - "CTL_QUERY", - "CTRL_BREAK_EVENT", - "CTRL_CLOSE_EVENT", - "CTRL_C_EVENT", - "CTRL_LOGOFF_EVENT", - "CTRL_SHUTDOWN_EVENT", - "CancelIo", - "CancelIoEx", - "CertAddCertificateContextToStore", - "CertChainContext", - "CertChainElement", - "CertChainPara", - "CertChainPolicyPara", - "CertChainPolicyStatus", - "CertCloseStore", - "CertContext", - "CertCreateCertificateContext", - "CertEnhKeyUsage", - "CertEnumCertificatesInStore", - "CertFreeCertificateChain", - "CertFreeCertificateContext", - "CertGetCertificateChain", - "CertInfo", - "CertOpenStore", - "CertOpenSystemStore", - "CertRevocationCrlInfo", - "CertRevocationInfo", - "CertSimpleChain", - "CertTrustListInfo", - "CertTrustStatus", - "CertUsageMatch", - "CertVerifyCertificateChainPolicy", - "Chdir", - "CheckBpfVersion", - "Chflags", - "Chmod", - "Chown", - "Chroot", - "Clearenv", - "Close", - "CloseHandle", - "CloseOnExec", - "Closesocket", - "CmsgLen", - "CmsgSpace", - "Cmsghdr", - "CommandLineToArgv", - "ComputerName", - "Conn", - "Connect", - "ConnectEx", - "ConvertSidToStringSid", - "ConvertStringSidToSid", - "CopySid", - "Creat", - "CreateDirectory", - "CreateFile", - "CreateFileMapping", - "CreateHardLink", - "CreateIoCompletionPort", - "CreatePipe", - "CreateProcess", - "CreateProcessAsUser", - "CreateSymbolicLink", - "CreateToolhelp32Snapshot", - "Credential", - "CryptAcquireContext", - "CryptGenRandom", - "CryptReleaseContext", - "DIOCBSFLUSH", - "DIOCOSFPFLUSH", - "DLL", - "DLLError", - "DLT_A429", - "DLT_A653_ICM", - "DLT_AIRONET_HEADER", - "DLT_AOS", - "DLT_APPLE_IP_OVER_IEEE1394", - "DLT_ARCNET", - "DLT_ARCNET_LINUX", - "DLT_ATM_CLIP", - "DLT_ATM_RFC1483", - "DLT_AURORA", - "DLT_AX25", - "DLT_AX25_KISS", - "DLT_BACNET_MS_TP", - "DLT_BLUETOOTH_HCI_H4", - "DLT_BLUETOOTH_HCI_H4_WITH_PHDR", - "DLT_CAN20B", - "DLT_CAN_SOCKETCAN", - "DLT_CHAOS", - "DLT_CHDLC", - "DLT_CISCO_IOS", - "DLT_C_HDLC", - "DLT_C_HDLC_WITH_DIR", - "DLT_DBUS", - "DLT_DECT", - "DLT_DOCSIS", - "DLT_DVB_CI", - "DLT_ECONET", - "DLT_EN10MB", - "DLT_EN3MB", - "DLT_ENC", - "DLT_ERF", - "DLT_ERF_ETH", - "DLT_ERF_POS", - "DLT_FC_2", - "DLT_FC_2_WITH_FRAME_DELIMS", - "DLT_FDDI", - "DLT_FLEXRAY", - "DLT_FRELAY", - "DLT_FRELAY_WITH_DIR", - "DLT_GCOM_SERIAL", - "DLT_GCOM_T1E1", - "DLT_GPF_F", - "DLT_GPF_T", - "DLT_GPRS_LLC", - "DLT_GSMTAP_ABIS", - "DLT_GSMTAP_UM", - "DLT_HDLC", - "DLT_HHDLC", - "DLT_HIPPI", - "DLT_IBM_SN", - "DLT_IBM_SP", - "DLT_IEEE802", - "DLT_IEEE802_11", - "DLT_IEEE802_11_RADIO", - "DLT_IEEE802_11_RADIO_AVS", - "DLT_IEEE802_15_4", - "DLT_IEEE802_15_4_LINUX", - "DLT_IEEE802_15_4_NOFCS", - "DLT_IEEE802_15_4_NONASK_PHY", - "DLT_IEEE802_16_MAC_CPS", - "DLT_IEEE802_16_MAC_CPS_RADIO", - "DLT_IPFILTER", - "DLT_IPMB", - "DLT_IPMB_LINUX", - "DLT_IPNET", - "DLT_IPOIB", - "DLT_IPV4", - "DLT_IPV6", - "DLT_IP_OVER_FC", - "DLT_JUNIPER_ATM1", - "DLT_JUNIPER_ATM2", - "DLT_JUNIPER_ATM_CEMIC", - "DLT_JUNIPER_CHDLC", - "DLT_JUNIPER_ES", - "DLT_JUNIPER_ETHER", - "DLT_JUNIPER_FIBRECHANNEL", - "DLT_JUNIPER_FRELAY", - "DLT_JUNIPER_GGSN", - "DLT_JUNIPER_ISM", - "DLT_JUNIPER_MFR", - "DLT_JUNIPER_MLFR", - "DLT_JUNIPER_MLPPP", - "DLT_JUNIPER_MONITOR", - "DLT_JUNIPER_PIC_PEER", - "DLT_JUNIPER_PPP", - "DLT_JUNIPER_PPPOE", - "DLT_JUNIPER_PPPOE_ATM", - "DLT_JUNIPER_SERVICES", - "DLT_JUNIPER_SRX_E2E", - "DLT_JUNIPER_ST", - "DLT_JUNIPER_VP", - "DLT_JUNIPER_VS", - "DLT_LAPB_WITH_DIR", - "DLT_LAPD", - "DLT_LIN", - "DLT_LINUX_EVDEV", - "DLT_LINUX_IRDA", - "DLT_LINUX_LAPD", - "DLT_LINUX_PPP_WITHDIRECTION", - "DLT_LINUX_SLL", - "DLT_LOOP", - "DLT_LTALK", - "DLT_MATCHING_MAX", - "DLT_MATCHING_MIN", - "DLT_MFR", - "DLT_MOST", - "DLT_MPEG_2_TS", - "DLT_MPLS", - "DLT_MTP2", - "DLT_MTP2_WITH_PHDR", - "DLT_MTP3", - "DLT_MUX27010", - "DLT_NETANALYZER", - "DLT_NETANALYZER_TRANSPARENT", - "DLT_NFC_LLCP", - "DLT_NFLOG", - "DLT_NG40", - "DLT_NULL", - "DLT_PCI_EXP", - "DLT_PFLOG", - "DLT_PFSYNC", - "DLT_PPI", - "DLT_PPP", - "DLT_PPP_BSDOS", - "DLT_PPP_ETHER", - "DLT_PPP_PPPD", - "DLT_PPP_SERIAL", - "DLT_PPP_WITH_DIR", - "DLT_PPP_WITH_DIRECTION", - "DLT_PRISM_HEADER", - "DLT_PRONET", - "DLT_RAIF1", - "DLT_RAW", - "DLT_RAWAF_MASK", - "DLT_RIO", - "DLT_SCCP", - "DLT_SITA", - "DLT_SLIP", - "DLT_SLIP_BSDOS", - "DLT_STANAG_5066_D_PDU", - "DLT_SUNATM", - "DLT_SYMANTEC_FIREWALL", - "DLT_TZSP", - "DLT_USB", - "DLT_USB_LINUX", - "DLT_USB_LINUX_MMAPPED", - "DLT_USER0", - "DLT_USER1", - "DLT_USER10", - "DLT_USER11", - "DLT_USER12", - "DLT_USER13", - "DLT_USER14", - "DLT_USER15", - "DLT_USER2", - "DLT_USER3", - "DLT_USER4", - "DLT_USER5", - "DLT_USER6", - "DLT_USER7", - "DLT_USER8", - "DLT_USER9", - "DLT_WIHART", - "DLT_X2E_SERIAL", - "DLT_X2E_XORAYA", - "DNSMXData", - "DNSPTRData", - "DNSRecord", - "DNSSRVData", - "DNSTXTData", - "DNS_INFO_NO_RECORDS", - "DNS_TYPE_A", - "DNS_TYPE_A6", - "DNS_TYPE_AAAA", - "DNS_TYPE_ADDRS", - "DNS_TYPE_AFSDB", - "DNS_TYPE_ALL", - "DNS_TYPE_ANY", - "DNS_TYPE_ATMA", - "DNS_TYPE_AXFR", - "DNS_TYPE_CERT", - "DNS_TYPE_CNAME", - "DNS_TYPE_DHCID", - "DNS_TYPE_DNAME", - "DNS_TYPE_DNSKEY", - "DNS_TYPE_DS", - "DNS_TYPE_EID", - "DNS_TYPE_GID", - "DNS_TYPE_GPOS", - "DNS_TYPE_HINFO", - "DNS_TYPE_ISDN", - "DNS_TYPE_IXFR", - "DNS_TYPE_KEY", - "DNS_TYPE_KX", - "DNS_TYPE_LOC", - "DNS_TYPE_MAILA", - "DNS_TYPE_MAILB", - "DNS_TYPE_MB", - "DNS_TYPE_MD", - "DNS_TYPE_MF", - "DNS_TYPE_MG", - "DNS_TYPE_MINFO", - "DNS_TYPE_MR", - "DNS_TYPE_MX", - "DNS_TYPE_NAPTR", - "DNS_TYPE_NBSTAT", - "DNS_TYPE_NIMLOC", - "DNS_TYPE_NS", - "DNS_TYPE_NSAP", - "DNS_TYPE_NSAPPTR", - "DNS_TYPE_NSEC", - "DNS_TYPE_NULL", - "DNS_TYPE_NXT", - "DNS_TYPE_OPT", - "DNS_TYPE_PTR", - "DNS_TYPE_PX", - "DNS_TYPE_RP", - "DNS_TYPE_RRSIG", - "DNS_TYPE_RT", - "DNS_TYPE_SIG", - "DNS_TYPE_SINK", - "DNS_TYPE_SOA", - "DNS_TYPE_SRV", - "DNS_TYPE_TEXT", - "DNS_TYPE_TKEY", - "DNS_TYPE_TSIG", - "DNS_TYPE_UID", - "DNS_TYPE_UINFO", - "DNS_TYPE_UNSPEC", - "DNS_TYPE_WINS", - "DNS_TYPE_WINSR", - "DNS_TYPE_WKS", - "DNS_TYPE_X25", - "DT_BLK", - "DT_CHR", - "DT_DIR", - "DT_FIFO", - "DT_LNK", - "DT_REG", - "DT_SOCK", - "DT_UNKNOWN", - "DT_WHT", - "DUPLICATE_CLOSE_SOURCE", - "DUPLICATE_SAME_ACCESS", - "DeleteFile", - "DetachLsf", - "DeviceIoControl", - "Dirent", - "DnsNameCompare", - "DnsQuery", - "DnsRecordListFree", - "DnsSectionAdditional", - "DnsSectionAnswer", - "DnsSectionAuthority", - "DnsSectionQuestion", - "Dup", - "Dup2", - "Dup3", - "DuplicateHandle", - "E2BIG", - "EACCES", - "EADDRINUSE", - "EADDRNOTAVAIL", - "EADV", - "EAFNOSUPPORT", - "EAGAIN", - "EALREADY", - "EAUTH", - "EBADARCH", - "EBADE", - "EBADEXEC", - "EBADF", - "EBADFD", - "EBADMACHO", - "EBADMSG", - "EBADR", - "EBADRPC", - "EBADRQC", - "EBADSLT", - "EBFONT", - "EBUSY", - "ECANCELED", - "ECAPMODE", - "ECHILD", - "ECHO", - "ECHOCTL", - "ECHOE", - "ECHOK", - "ECHOKE", - "ECHONL", - "ECHOPRT", - "ECHRNG", - "ECOMM", - "ECONNABORTED", - "ECONNREFUSED", - "ECONNRESET", - "EDEADLK", - "EDEADLOCK", - "EDESTADDRREQ", - "EDEVERR", - "EDOM", - "EDOOFUS", - "EDOTDOT", - "EDQUOT", - "EEXIST", - "EFAULT", - "EFBIG", - "EFER_LMA", - "EFER_LME", - "EFER_NXE", - "EFER_SCE", - "EFTYPE", - "EHOSTDOWN", - "EHOSTUNREACH", - "EHWPOISON", - "EIDRM", - "EILSEQ", - "EINPROGRESS", - "EINTR", - "EINVAL", - "EIO", - "EIPSEC", - "EISCONN", - "EISDIR", - "EISNAM", - "EKEYEXPIRED", - "EKEYREJECTED", - "EKEYREVOKED", - "EL2HLT", - "EL2NSYNC", - "EL3HLT", - "EL3RST", - "ELAST", - "ELF_NGREG", - "ELF_PRARGSZ", - "ELIBACC", - "ELIBBAD", - "ELIBEXEC", - "ELIBMAX", - "ELIBSCN", - "ELNRNG", - "ELOOP", - "EMEDIUMTYPE", - "EMFILE", - "EMLINK", - "EMSGSIZE", - "EMT_TAGOVF", - "EMULTIHOP", - "EMUL_ENABLED", - "EMUL_LINUX", - "EMUL_LINUX32", - "EMUL_MAXID", - "EMUL_NATIVE", - "ENAMETOOLONG", - "ENAVAIL", - "ENDRUNDISC", - "ENEEDAUTH", - "ENETDOWN", - "ENETRESET", - "ENETUNREACH", - "ENFILE", - "ENOANO", - "ENOATTR", - "ENOBUFS", - "ENOCSI", - "ENODATA", - "ENODEV", - "ENOENT", - "ENOEXEC", - "ENOKEY", - "ENOLCK", - "ENOLINK", - "ENOMEDIUM", - "ENOMEM", - "ENOMSG", - "ENONET", - "ENOPKG", - "ENOPOLICY", - "ENOPROTOOPT", - "ENOSPC", - "ENOSR", - "ENOSTR", - "ENOSYS", - "ENOTBLK", - "ENOTCAPABLE", - "ENOTCONN", - "ENOTDIR", - "ENOTEMPTY", - "ENOTNAM", - "ENOTRECOVERABLE", - "ENOTSOCK", - "ENOTSUP", - "ENOTTY", - "ENOTUNIQ", - "ENXIO", - "EN_SW_CTL_INF", - "EN_SW_CTL_PREC", - "EN_SW_CTL_ROUND", - "EN_SW_DATACHAIN", - "EN_SW_DENORM", - "EN_SW_INVOP", - "EN_SW_OVERFLOW", - "EN_SW_PRECLOSS", - "EN_SW_UNDERFLOW", - "EN_SW_ZERODIV", - "EOPNOTSUPP", - "EOVERFLOW", - "EOWNERDEAD", - "EPERM", - "EPFNOSUPPORT", - "EPIPE", - "EPOLLERR", - "EPOLLET", - "EPOLLHUP", - "EPOLLIN", - "EPOLLMSG", - "EPOLLONESHOT", - "EPOLLOUT", - "EPOLLPRI", - "EPOLLRDBAND", - "EPOLLRDHUP", - "EPOLLRDNORM", - "EPOLLWRBAND", - "EPOLLWRNORM", - "EPOLL_CLOEXEC", - "EPOLL_CTL_ADD", - "EPOLL_CTL_DEL", - "EPOLL_CTL_MOD", - "EPOLL_NONBLOCK", - "EPROCLIM", - "EPROCUNAVAIL", - "EPROGMISMATCH", - "EPROGUNAVAIL", - "EPROTO", - "EPROTONOSUPPORT", - "EPROTOTYPE", - "EPWROFF", - "EQFULL", - "ERANGE", - "EREMCHG", - "EREMOTE", - "EREMOTEIO", - "ERESTART", - "ERFKILL", - "EROFS", - "ERPCMISMATCH", - "ERROR_ACCESS_DENIED", - "ERROR_ALREADY_EXISTS", - "ERROR_BROKEN_PIPE", - "ERROR_BUFFER_OVERFLOW", - "ERROR_DIR_NOT_EMPTY", - "ERROR_ENVVAR_NOT_FOUND", - "ERROR_FILE_EXISTS", - "ERROR_FILE_NOT_FOUND", - "ERROR_HANDLE_EOF", - "ERROR_INSUFFICIENT_BUFFER", - "ERROR_IO_PENDING", - "ERROR_MOD_NOT_FOUND", - "ERROR_MORE_DATA", - "ERROR_NETNAME_DELETED", - "ERROR_NOT_FOUND", - "ERROR_NO_MORE_FILES", - "ERROR_OPERATION_ABORTED", - "ERROR_PATH_NOT_FOUND", - "ERROR_PRIVILEGE_NOT_HELD", - "ERROR_PROC_NOT_FOUND", - "ESHLIBVERS", - "ESHUTDOWN", - "ESOCKTNOSUPPORT", - "ESPIPE", - "ESRCH", - "ESRMNT", - "ESTALE", - "ESTRPIPE", - "ETHERCAP_JUMBO_MTU", - "ETHERCAP_VLAN_HWTAGGING", - "ETHERCAP_VLAN_MTU", - "ETHERMIN", - "ETHERMTU", - "ETHERMTU_JUMBO", - "ETHERTYPE_8023", - "ETHERTYPE_AARP", - "ETHERTYPE_ACCTON", - "ETHERTYPE_AEONIC", - "ETHERTYPE_ALPHA", - "ETHERTYPE_AMBER", - "ETHERTYPE_AMOEBA", - "ETHERTYPE_AOE", - "ETHERTYPE_APOLLO", - "ETHERTYPE_APOLLODOMAIN", - "ETHERTYPE_APPLETALK", - "ETHERTYPE_APPLITEK", - "ETHERTYPE_ARGONAUT", - "ETHERTYPE_ARP", - "ETHERTYPE_AT", - "ETHERTYPE_ATALK", - "ETHERTYPE_ATOMIC", - "ETHERTYPE_ATT", - "ETHERTYPE_ATTSTANFORD", - "ETHERTYPE_AUTOPHON", - "ETHERTYPE_AXIS", - "ETHERTYPE_BCLOOP", - "ETHERTYPE_BOFL", - "ETHERTYPE_CABLETRON", - "ETHERTYPE_CHAOS", - "ETHERTYPE_COMDESIGN", - "ETHERTYPE_COMPUGRAPHIC", - "ETHERTYPE_COUNTERPOINT", - "ETHERTYPE_CRONUS", - "ETHERTYPE_CRONUSVLN", - "ETHERTYPE_DCA", - "ETHERTYPE_DDE", - "ETHERTYPE_DEBNI", - "ETHERTYPE_DECAM", - "ETHERTYPE_DECCUST", - "ETHERTYPE_DECDIAG", - "ETHERTYPE_DECDNS", - "ETHERTYPE_DECDTS", - "ETHERTYPE_DECEXPER", - "ETHERTYPE_DECLAST", - "ETHERTYPE_DECLTM", - "ETHERTYPE_DECMUMPS", - "ETHERTYPE_DECNETBIOS", - "ETHERTYPE_DELTACON", - "ETHERTYPE_DIDDLE", - "ETHERTYPE_DLOG1", - "ETHERTYPE_DLOG2", - "ETHERTYPE_DN", - "ETHERTYPE_DOGFIGHT", - "ETHERTYPE_DSMD", - "ETHERTYPE_ECMA", - "ETHERTYPE_ENCRYPT", - "ETHERTYPE_ES", - "ETHERTYPE_EXCELAN", - "ETHERTYPE_EXPERDATA", - "ETHERTYPE_FLIP", - "ETHERTYPE_FLOWCONTROL", - "ETHERTYPE_FRARP", - "ETHERTYPE_GENDYN", - "ETHERTYPE_HAYES", - "ETHERTYPE_HIPPI_FP", - "ETHERTYPE_HITACHI", - "ETHERTYPE_HP", - "ETHERTYPE_IEEEPUP", - "ETHERTYPE_IEEEPUPAT", - "ETHERTYPE_IMLBL", - "ETHERTYPE_IMLBLDIAG", - "ETHERTYPE_IP", - "ETHERTYPE_IPAS", - "ETHERTYPE_IPV6", - "ETHERTYPE_IPX", - "ETHERTYPE_IPXNEW", - "ETHERTYPE_KALPANA", - "ETHERTYPE_LANBRIDGE", - "ETHERTYPE_LANPROBE", - "ETHERTYPE_LAT", - "ETHERTYPE_LBACK", - "ETHERTYPE_LITTLE", - "ETHERTYPE_LLDP", - "ETHERTYPE_LOGICRAFT", - "ETHERTYPE_LOOPBACK", - "ETHERTYPE_MATRA", - "ETHERTYPE_MAX", - "ETHERTYPE_MERIT", - "ETHERTYPE_MICP", - "ETHERTYPE_MOPDL", - "ETHERTYPE_MOPRC", - "ETHERTYPE_MOTOROLA", - "ETHERTYPE_MPLS", - "ETHERTYPE_MPLS_MCAST", - "ETHERTYPE_MUMPS", - "ETHERTYPE_NBPCC", - "ETHERTYPE_NBPCLAIM", - "ETHERTYPE_NBPCLREQ", - "ETHERTYPE_NBPCLRSP", - "ETHERTYPE_NBPCREQ", - "ETHERTYPE_NBPCRSP", - "ETHERTYPE_NBPDG", - "ETHERTYPE_NBPDGB", - "ETHERTYPE_NBPDLTE", - "ETHERTYPE_NBPRAR", - "ETHERTYPE_NBPRAS", - "ETHERTYPE_NBPRST", - "ETHERTYPE_NBPSCD", - "ETHERTYPE_NBPVCD", - "ETHERTYPE_NBS", - "ETHERTYPE_NCD", - "ETHERTYPE_NESTAR", - "ETHERTYPE_NETBEUI", - "ETHERTYPE_NOVELL", - "ETHERTYPE_NS", - "ETHERTYPE_NSAT", - "ETHERTYPE_NSCOMPAT", - "ETHERTYPE_NTRAILER", - "ETHERTYPE_OS9", - "ETHERTYPE_OS9NET", - "ETHERTYPE_PACER", - "ETHERTYPE_PAE", - "ETHERTYPE_PCS", - "ETHERTYPE_PLANNING", - "ETHERTYPE_PPP", - "ETHERTYPE_PPPOE", - "ETHERTYPE_PPPOEDISC", - "ETHERTYPE_PRIMENTS", - "ETHERTYPE_PUP", - "ETHERTYPE_PUPAT", - "ETHERTYPE_QINQ", - "ETHERTYPE_RACAL", - "ETHERTYPE_RATIONAL", - "ETHERTYPE_RAWFR", - "ETHERTYPE_RCL", - "ETHERTYPE_RDP", - "ETHERTYPE_RETIX", - "ETHERTYPE_REVARP", - "ETHERTYPE_SCA", - "ETHERTYPE_SECTRA", - "ETHERTYPE_SECUREDATA", - "ETHERTYPE_SGITW", - "ETHERTYPE_SG_BOUNCE", - "ETHERTYPE_SG_DIAG", - "ETHERTYPE_SG_NETGAMES", - "ETHERTYPE_SG_RESV", - "ETHERTYPE_SIMNET", - "ETHERTYPE_SLOW", - "ETHERTYPE_SLOWPROTOCOLS", - "ETHERTYPE_SNA", - "ETHERTYPE_SNMP", - "ETHERTYPE_SONIX", - "ETHERTYPE_SPIDER", - "ETHERTYPE_SPRITE", - "ETHERTYPE_STP", - "ETHERTYPE_TALARIS", - "ETHERTYPE_TALARISMC", - "ETHERTYPE_TCPCOMP", - "ETHERTYPE_TCPSM", - "ETHERTYPE_TEC", - "ETHERTYPE_TIGAN", - "ETHERTYPE_TRAIL", - "ETHERTYPE_TRANSETHER", - "ETHERTYPE_TYMSHARE", - "ETHERTYPE_UBBST", - "ETHERTYPE_UBDEBUG", - "ETHERTYPE_UBDIAGLOOP", - "ETHERTYPE_UBDL", - "ETHERTYPE_UBNIU", - "ETHERTYPE_UBNMC", - "ETHERTYPE_VALID", - "ETHERTYPE_VARIAN", - "ETHERTYPE_VAXELN", - "ETHERTYPE_VEECO", - "ETHERTYPE_VEXP", - "ETHERTYPE_VGLAB", - "ETHERTYPE_VINES", - "ETHERTYPE_VINESECHO", - "ETHERTYPE_VINESLOOP", - "ETHERTYPE_VITAL", - "ETHERTYPE_VLAN", - "ETHERTYPE_VLTLMAN", - "ETHERTYPE_VPROD", - "ETHERTYPE_VURESERVED", - "ETHERTYPE_WATERLOO", - "ETHERTYPE_WELLFLEET", - "ETHERTYPE_X25", - "ETHERTYPE_X75", - "ETHERTYPE_XNSSM", - "ETHERTYPE_XTP", - "ETHER_ADDR_LEN", - "ETHER_ALIGN", - "ETHER_CRC_LEN", - "ETHER_CRC_POLY_BE", - "ETHER_CRC_POLY_LE", - "ETHER_HDR_LEN", - "ETHER_MAX_DIX_LEN", - "ETHER_MAX_LEN", - "ETHER_MAX_LEN_JUMBO", - "ETHER_MIN_LEN", - "ETHER_PPPOE_ENCAP_LEN", - "ETHER_TYPE_LEN", - "ETHER_VLAN_ENCAP_LEN", - "ETH_P_1588", - "ETH_P_8021Q", - "ETH_P_802_2", - "ETH_P_802_3", - "ETH_P_AARP", - "ETH_P_ALL", - "ETH_P_AOE", - "ETH_P_ARCNET", - "ETH_P_ARP", - "ETH_P_ATALK", - "ETH_P_ATMFATE", - "ETH_P_ATMMPOA", - "ETH_P_AX25", - "ETH_P_BPQ", - "ETH_P_CAIF", - "ETH_P_CAN", - "ETH_P_CONTROL", - "ETH_P_CUST", - "ETH_P_DDCMP", - "ETH_P_DEC", - "ETH_P_DIAG", - "ETH_P_DNA_DL", - "ETH_P_DNA_RC", - "ETH_P_DNA_RT", - "ETH_P_DSA", - "ETH_P_ECONET", - "ETH_P_EDSA", - "ETH_P_FCOE", - "ETH_P_FIP", - "ETH_P_HDLC", - "ETH_P_IEEE802154", - "ETH_P_IEEEPUP", - "ETH_P_IEEEPUPAT", - "ETH_P_IP", - "ETH_P_IPV6", - "ETH_P_IPX", - "ETH_P_IRDA", - "ETH_P_LAT", - "ETH_P_LINK_CTL", - "ETH_P_LOCALTALK", - "ETH_P_LOOP", - "ETH_P_MOBITEX", - "ETH_P_MPLS_MC", - "ETH_P_MPLS_UC", - "ETH_P_PAE", - "ETH_P_PAUSE", - "ETH_P_PHONET", - "ETH_P_PPPTALK", - "ETH_P_PPP_DISC", - "ETH_P_PPP_MP", - "ETH_P_PPP_SES", - "ETH_P_PUP", - "ETH_P_PUPAT", - "ETH_P_RARP", - "ETH_P_SCA", - "ETH_P_SLOW", - "ETH_P_SNAP", - "ETH_P_TEB", - "ETH_P_TIPC", - "ETH_P_TRAILER", - "ETH_P_TR_802_2", - "ETH_P_WAN_PPP", - "ETH_P_WCCP", - "ETH_P_X25", - "ETIME", - "ETIMEDOUT", - "ETOOMANYREFS", - "ETXTBSY", - "EUCLEAN", - "EUNATCH", - "EUSERS", - "EVFILT_AIO", - "EVFILT_FS", - "EVFILT_LIO", - "EVFILT_MACHPORT", - "EVFILT_PROC", - "EVFILT_READ", - "EVFILT_SIGNAL", - "EVFILT_SYSCOUNT", - "EVFILT_THREADMARKER", - "EVFILT_TIMER", - "EVFILT_USER", - "EVFILT_VM", - "EVFILT_VNODE", - "EVFILT_WRITE", - "EV_ADD", - "EV_CLEAR", - "EV_DELETE", - "EV_DISABLE", - "EV_DISPATCH", - "EV_DROP", - "EV_ENABLE", - "EV_EOF", - "EV_ERROR", - "EV_FLAG0", - "EV_FLAG1", - "EV_ONESHOT", - "EV_OOBAND", - "EV_POLL", - "EV_RECEIPT", - "EV_SYSFLAGS", - "EWINDOWS", - "EWOULDBLOCK", - "EXDEV", - "EXFULL", - "EXTA", - "EXTB", - "EXTPROC", - "Environ", - "EpollCreate", - "EpollCreate1", - "EpollCtl", - "EpollEvent", - "EpollWait", - "Errno", - "EscapeArg", - "Exchangedata", - "Exec", - "Exit", - "ExitProcess", - "FD_CLOEXEC", - "FD_SETSIZE", - "FILE_ACTION_ADDED", - "FILE_ACTION_MODIFIED", - "FILE_ACTION_REMOVED", - "FILE_ACTION_RENAMED_NEW_NAME", - "FILE_ACTION_RENAMED_OLD_NAME", - "FILE_APPEND_DATA", - "FILE_ATTRIBUTE_ARCHIVE", - "FILE_ATTRIBUTE_DIRECTORY", - "FILE_ATTRIBUTE_HIDDEN", - "FILE_ATTRIBUTE_NORMAL", - "FILE_ATTRIBUTE_READONLY", - "FILE_ATTRIBUTE_REPARSE_POINT", - "FILE_ATTRIBUTE_SYSTEM", - "FILE_BEGIN", - "FILE_CURRENT", - "FILE_END", - "FILE_FLAG_BACKUP_SEMANTICS", - "FILE_FLAG_OPEN_REPARSE_POINT", - "FILE_FLAG_OVERLAPPED", - "FILE_LIST_DIRECTORY", - "FILE_MAP_COPY", - "FILE_MAP_EXECUTE", - "FILE_MAP_READ", - "FILE_MAP_WRITE", - "FILE_NOTIFY_CHANGE_ATTRIBUTES", - "FILE_NOTIFY_CHANGE_CREATION", - "FILE_NOTIFY_CHANGE_DIR_NAME", - "FILE_NOTIFY_CHANGE_FILE_NAME", - "FILE_NOTIFY_CHANGE_LAST_ACCESS", - "FILE_NOTIFY_CHANGE_LAST_WRITE", - "FILE_NOTIFY_CHANGE_SIZE", - "FILE_SHARE_DELETE", - "FILE_SHARE_READ", - "FILE_SHARE_WRITE", - "FILE_SKIP_COMPLETION_PORT_ON_SUCCESS", - "FILE_SKIP_SET_EVENT_ON_HANDLE", - "FILE_TYPE_CHAR", - "FILE_TYPE_DISK", - "FILE_TYPE_PIPE", - "FILE_TYPE_REMOTE", - "FILE_TYPE_UNKNOWN", - "FILE_WRITE_ATTRIBUTES", - "FLUSHO", - "FORMAT_MESSAGE_ALLOCATE_BUFFER", - "FORMAT_MESSAGE_ARGUMENT_ARRAY", - "FORMAT_MESSAGE_FROM_HMODULE", - "FORMAT_MESSAGE_FROM_STRING", - "FORMAT_MESSAGE_FROM_SYSTEM", - "FORMAT_MESSAGE_IGNORE_INSERTS", - "FORMAT_MESSAGE_MAX_WIDTH_MASK", - "FSCTL_GET_REPARSE_POINT", - "F_ADDFILESIGS", - "F_ADDSIGS", - "F_ALLOCATEALL", - "F_ALLOCATECONTIG", - "F_CANCEL", - "F_CHKCLEAN", - "F_CLOSEM", - "F_DUP2FD", - "F_DUP2FD_CLOEXEC", - "F_DUPFD", - "F_DUPFD_CLOEXEC", - "F_EXLCK", - "F_FINDSIGS", - "F_FLUSH_DATA", - "F_FREEZE_FS", - "F_FSCTL", - "F_FSDIRMASK", - "F_FSIN", - "F_FSINOUT", - "F_FSOUT", - "F_FSPRIV", - "F_FSVOID", - "F_FULLFSYNC", - "F_GETCODEDIR", - "F_GETFD", - "F_GETFL", - "F_GETLEASE", - "F_GETLK", - "F_GETLK64", - "F_GETLKPID", - "F_GETNOSIGPIPE", - "F_GETOWN", - "F_GETOWN_EX", - "F_GETPATH", - "F_GETPATH_MTMINFO", - "F_GETPIPE_SZ", - "F_GETPROTECTIONCLASS", - "F_GETPROTECTIONLEVEL", - "F_GETSIG", - "F_GLOBAL_NOCACHE", - "F_LOCK", - "F_LOG2PHYS", - "F_LOG2PHYS_EXT", - "F_MARKDEPENDENCY", - "F_MAXFD", - "F_NOCACHE", - "F_NODIRECT", - "F_NOTIFY", - "F_OGETLK", - "F_OK", - "F_OSETLK", - "F_OSETLKW", - "F_PARAM_MASK", - "F_PARAM_MAX", - "F_PATHPKG_CHECK", - "F_PEOFPOSMODE", - "F_PREALLOCATE", - "F_RDADVISE", - "F_RDAHEAD", - "F_RDLCK", - "F_READAHEAD", - "F_READBOOTSTRAP", - "F_SETBACKINGSTORE", - "F_SETFD", - "F_SETFL", - "F_SETLEASE", - "F_SETLK", - "F_SETLK64", - "F_SETLKW", - "F_SETLKW64", - "F_SETLKWTIMEOUT", - "F_SETLK_REMOTE", - "F_SETNOSIGPIPE", - "F_SETOWN", - "F_SETOWN_EX", - "F_SETPIPE_SZ", - "F_SETPROTECTIONCLASS", - "F_SETSIG", - "F_SETSIZE", - "F_SHLCK", - "F_SINGLE_WRITER", - "F_TEST", - "F_THAW_FS", - "F_TLOCK", - "F_TRANSCODEKEY", - "F_ULOCK", - "F_UNLCK", - "F_UNLCKSYS", - "F_VOLPOSMODE", - "F_WRITEBOOTSTRAP", - "F_WRLCK", - "Faccessat", - "Fallocate", - "Fbootstraptransfer_t", - "Fchdir", - "Fchflags", - "Fchmod", - "Fchmodat", - "Fchown", - "Fchownat", - "FcntlFlock", - "FdSet", - "Fdatasync", - "FileNotifyInformation", - "Filetime", - "FindClose", - "FindFirstFile", - "FindNextFile", - "Flock", - "Flock_t", - "FlushBpf", - "FlushFileBuffers", - "FlushViewOfFile", - "ForkExec", - "ForkLock", - "FormatMessage", - "Fpathconf", - "FreeAddrInfoW", - "FreeEnvironmentStrings", - "FreeLibrary", - "Fsid", - "Fstat", - "Fstatat", - "Fstatfs", - "Fstore_t", - "Fsync", - "Ftruncate", - "FullPath", - "Futimes", - "Futimesat", - "GENERIC_ALL", - "GENERIC_EXECUTE", - "GENERIC_READ", - "GENERIC_WRITE", - "GUID", - "GetAcceptExSockaddrs", - "GetAdaptersInfo", - "GetAddrInfoW", - "GetCommandLine", - "GetComputerName", - "GetConsoleMode", - "GetCurrentDirectory", - "GetCurrentProcess", - "GetEnvironmentStrings", - "GetEnvironmentVariable", - "GetExitCodeProcess", - "GetFileAttributes", - "GetFileAttributesEx", - "GetFileExInfoStandard", - "GetFileExMaxInfoLevel", - "GetFileInformationByHandle", - "GetFileType", - "GetFullPathName", - "GetHostByName", - "GetIfEntry", - "GetLastError", - "GetLengthSid", - "GetLongPathName", - "GetProcAddress", - "GetProcessTimes", - "GetProtoByName", - "GetQueuedCompletionStatus", - "GetServByName", - "GetShortPathName", - "GetStartupInfo", - "GetStdHandle", - "GetSystemTimeAsFileTime", - "GetTempPath", - "GetTimeZoneInformation", - "GetTokenInformation", - "GetUserNameEx", - "GetUserProfileDirectory", - "GetVersion", - "Getcwd", - "Getdents", - "Getdirentries", - "Getdtablesize", - "Getegid", - "Getenv", - "Geteuid", - "Getfsstat", - "Getgid", - "Getgroups", - "Getpagesize", - "Getpeername", - "Getpgid", - "Getpgrp", - "Getpid", - "Getppid", - "Getpriority", - "Getrlimit", - "Getrusage", - "Getsid", - "Getsockname", - "Getsockopt", - "GetsockoptByte", - "GetsockoptICMPv6Filter", - "GetsockoptIPMreq", - "GetsockoptIPMreqn", - "GetsockoptIPv6MTUInfo", - "GetsockoptIPv6Mreq", - "GetsockoptInet4Addr", - "GetsockoptInt", - "GetsockoptUcred", - "Gettid", - "Gettimeofday", - "Getuid", - "Getwd", - "Getxattr", - "HANDLE_FLAG_INHERIT", - "HKEY_CLASSES_ROOT", - "HKEY_CURRENT_CONFIG", - "HKEY_CURRENT_USER", - "HKEY_DYN_DATA", - "HKEY_LOCAL_MACHINE", - "HKEY_PERFORMANCE_DATA", - "HKEY_USERS", - "HUPCL", - "Handle", - "Hostent", - "ICANON", - "ICMP6_FILTER", - "ICMPV6_FILTER", - "ICMPv6Filter", - "ICRNL", - "IEXTEN", - "IFAN_ARRIVAL", - "IFAN_DEPARTURE", - "IFA_ADDRESS", - "IFA_ANYCAST", - "IFA_BROADCAST", - "IFA_CACHEINFO", - "IFA_F_DADFAILED", - "IFA_F_DEPRECATED", - "IFA_F_HOMEADDRESS", - "IFA_F_NODAD", - "IFA_F_OPTIMISTIC", - "IFA_F_PERMANENT", - "IFA_F_SECONDARY", - "IFA_F_TEMPORARY", - "IFA_F_TENTATIVE", - "IFA_LABEL", - "IFA_LOCAL", - "IFA_MAX", - "IFA_MULTICAST", - "IFA_ROUTE", - "IFA_UNSPEC", - "IFF_ALLMULTI", - "IFF_ALTPHYS", - "IFF_AUTOMEDIA", - "IFF_BROADCAST", - "IFF_CANTCHANGE", - "IFF_CANTCONFIG", - "IFF_DEBUG", - "IFF_DRV_OACTIVE", - "IFF_DRV_RUNNING", - "IFF_DYING", - "IFF_DYNAMIC", - "IFF_LINK0", - "IFF_LINK1", - "IFF_LINK2", - "IFF_LOOPBACK", - "IFF_MASTER", - "IFF_MONITOR", - "IFF_MULTICAST", - "IFF_NOARP", - "IFF_NOTRAILERS", - "IFF_NO_PI", - "IFF_OACTIVE", - "IFF_ONE_QUEUE", - "IFF_POINTOPOINT", - "IFF_POINTTOPOINT", - "IFF_PORTSEL", - "IFF_PPROMISC", - "IFF_PROMISC", - "IFF_RENAMING", - "IFF_RUNNING", - "IFF_SIMPLEX", - "IFF_SLAVE", - "IFF_SMART", - "IFF_STATICARP", - "IFF_TAP", - "IFF_TUN", - "IFF_TUN_EXCL", - "IFF_UP", - "IFF_VNET_HDR", - "IFLA_ADDRESS", - "IFLA_BROADCAST", - "IFLA_COST", - "IFLA_IFALIAS", - "IFLA_IFNAME", - "IFLA_LINK", - "IFLA_LINKINFO", - "IFLA_LINKMODE", - "IFLA_MAP", - "IFLA_MASTER", - "IFLA_MAX", - "IFLA_MTU", - "IFLA_NET_NS_PID", - "IFLA_OPERSTATE", - "IFLA_PRIORITY", - "IFLA_PROTINFO", - "IFLA_QDISC", - "IFLA_STATS", - "IFLA_TXQLEN", - "IFLA_UNSPEC", - "IFLA_WEIGHT", - "IFLA_WIRELESS", - "IFNAMSIZ", - "IFT_1822", - "IFT_A12MPPSWITCH", - "IFT_AAL2", - "IFT_AAL5", - "IFT_ADSL", - "IFT_AFLANE8023", - "IFT_AFLANE8025", - "IFT_ARAP", - "IFT_ARCNET", - "IFT_ARCNETPLUS", - "IFT_ASYNC", - "IFT_ATM", - "IFT_ATMDXI", - "IFT_ATMFUNI", - "IFT_ATMIMA", - "IFT_ATMLOGICAL", - "IFT_ATMRADIO", - "IFT_ATMSUBINTERFACE", - "IFT_ATMVCIENDPT", - "IFT_ATMVIRTUAL", - "IFT_BGPPOLICYACCOUNTING", - "IFT_BLUETOOTH", - "IFT_BRIDGE", - "IFT_BSC", - "IFT_CARP", - "IFT_CCTEMUL", - "IFT_CELLULAR", - "IFT_CEPT", - "IFT_CES", - "IFT_CHANNEL", - "IFT_CNR", - "IFT_COFFEE", - "IFT_COMPOSITELINK", - "IFT_DCN", - "IFT_DIGITALPOWERLINE", - "IFT_DIGITALWRAPPEROVERHEADCHANNEL", - "IFT_DLSW", - "IFT_DOCSCABLEDOWNSTREAM", - "IFT_DOCSCABLEMACLAYER", - "IFT_DOCSCABLEUPSTREAM", - "IFT_DOCSCABLEUPSTREAMCHANNEL", - "IFT_DS0", - "IFT_DS0BUNDLE", - "IFT_DS1FDL", - "IFT_DS3", - "IFT_DTM", - "IFT_DUMMY", - "IFT_DVBASILN", - "IFT_DVBASIOUT", - "IFT_DVBRCCDOWNSTREAM", - "IFT_DVBRCCMACLAYER", - "IFT_DVBRCCUPSTREAM", - "IFT_ECONET", - "IFT_ENC", - "IFT_EON", - "IFT_EPLRS", - "IFT_ESCON", - "IFT_ETHER", - "IFT_FAITH", - "IFT_FAST", - "IFT_FASTETHER", - "IFT_FASTETHERFX", - "IFT_FDDI", - "IFT_FIBRECHANNEL", - "IFT_FRAMERELAYINTERCONNECT", - "IFT_FRAMERELAYMPI", - "IFT_FRDLCIENDPT", - "IFT_FRELAY", - "IFT_FRELAYDCE", - "IFT_FRF16MFRBUNDLE", - "IFT_FRFORWARD", - "IFT_G703AT2MB", - "IFT_G703AT64K", - "IFT_GIF", - "IFT_GIGABITETHERNET", - "IFT_GR303IDT", - "IFT_GR303RDT", - "IFT_H323GATEKEEPER", - "IFT_H323PROXY", - "IFT_HDH1822", - "IFT_HDLC", - "IFT_HDSL2", - "IFT_HIPERLAN2", - "IFT_HIPPI", - "IFT_HIPPIINTERFACE", - "IFT_HOSTPAD", - "IFT_HSSI", - "IFT_HY", - "IFT_IBM370PARCHAN", - "IFT_IDSL", - "IFT_IEEE1394", - "IFT_IEEE80211", - "IFT_IEEE80212", - "IFT_IEEE8023ADLAG", - "IFT_IFGSN", - "IFT_IMT", - "IFT_INFINIBAND", - "IFT_INTERLEAVE", - "IFT_IP", - "IFT_IPFORWARD", - "IFT_IPOVERATM", - "IFT_IPOVERCDLC", - "IFT_IPOVERCLAW", - "IFT_IPSWITCH", - "IFT_IPXIP", - "IFT_ISDN", - "IFT_ISDNBASIC", - "IFT_ISDNPRIMARY", - "IFT_ISDNS", - "IFT_ISDNU", - "IFT_ISO88022LLC", - "IFT_ISO88023", - "IFT_ISO88024", - "IFT_ISO88025", - "IFT_ISO88025CRFPINT", - "IFT_ISO88025DTR", - "IFT_ISO88025FIBER", - "IFT_ISO88026", - "IFT_ISUP", - "IFT_L2VLAN", - "IFT_L3IPVLAN", - "IFT_L3IPXVLAN", - "IFT_LAPB", - "IFT_LAPD", - "IFT_LAPF", - "IFT_LINEGROUP", - "IFT_LOCALTALK", - "IFT_LOOP", - "IFT_MEDIAMAILOVERIP", - "IFT_MFSIGLINK", - "IFT_MIOX25", - "IFT_MODEM", - "IFT_MPC", - "IFT_MPLS", - "IFT_MPLSTUNNEL", - "IFT_MSDSL", - "IFT_MVL", - "IFT_MYRINET", - "IFT_NFAS", - "IFT_NSIP", - "IFT_OPTICALCHANNEL", - "IFT_OPTICALTRANSPORT", - "IFT_OTHER", - "IFT_P10", - "IFT_P80", - "IFT_PARA", - "IFT_PDP", - "IFT_PFLOG", - "IFT_PFLOW", - "IFT_PFSYNC", - "IFT_PLC", - "IFT_PON155", - "IFT_PON622", - "IFT_POS", - "IFT_PPP", - "IFT_PPPMULTILINKBUNDLE", - "IFT_PROPATM", - "IFT_PROPBWAP2MP", - "IFT_PROPCNLS", - "IFT_PROPDOCSWIRELESSDOWNSTREAM", - "IFT_PROPDOCSWIRELESSMACLAYER", - "IFT_PROPDOCSWIRELESSUPSTREAM", - "IFT_PROPMUX", - "IFT_PROPVIRTUAL", - "IFT_PROPWIRELESSP2P", - "IFT_PTPSERIAL", - "IFT_PVC", - "IFT_Q2931", - "IFT_QLLC", - "IFT_RADIOMAC", - "IFT_RADSL", - "IFT_REACHDSL", - "IFT_RFC1483", - "IFT_RS232", - "IFT_RSRB", - "IFT_SDLC", - "IFT_SDSL", - "IFT_SHDSL", - "IFT_SIP", - "IFT_SIPSIG", - "IFT_SIPTG", - "IFT_SLIP", - "IFT_SMDSDXI", - "IFT_SMDSICIP", - "IFT_SONET", - "IFT_SONETOVERHEADCHANNEL", - "IFT_SONETPATH", - "IFT_SONETVT", - "IFT_SRP", - "IFT_SS7SIGLINK", - "IFT_STACKTOSTACK", - "IFT_STARLAN", - "IFT_STF", - "IFT_T1", - "IFT_TDLC", - "IFT_TELINK", - "IFT_TERMPAD", - "IFT_TR008", - "IFT_TRANSPHDLC", - "IFT_TUNNEL", - "IFT_ULTRA", - "IFT_USB", - "IFT_V11", - "IFT_V35", - "IFT_V36", - "IFT_V37", - "IFT_VDSL", - "IFT_VIRTUALIPADDRESS", - "IFT_VIRTUALTG", - "IFT_VOICEDID", - "IFT_VOICEEM", - "IFT_VOICEEMFGD", - "IFT_VOICEENCAP", - "IFT_VOICEFGDEANA", - "IFT_VOICEFXO", - "IFT_VOICEFXS", - "IFT_VOICEOVERATM", - "IFT_VOICEOVERCABLE", - "IFT_VOICEOVERFRAMERELAY", - "IFT_VOICEOVERIP", - "IFT_X213", - "IFT_X25", - "IFT_X25DDN", - "IFT_X25HUNTGROUP", - "IFT_X25MLP", - "IFT_X25PLE", - "IFT_XETHER", - "IGNBRK", - "IGNCR", - "IGNORE", - "IGNPAR", - "IMAXBEL", - "INFINITE", - "INLCR", - "INPCK", - "INVALID_FILE_ATTRIBUTES", - "IN_ACCESS", - "IN_ALL_EVENTS", - "IN_ATTRIB", - "IN_CLASSA_HOST", - "IN_CLASSA_MAX", - "IN_CLASSA_NET", - "IN_CLASSA_NSHIFT", - "IN_CLASSB_HOST", - "IN_CLASSB_MAX", - "IN_CLASSB_NET", - "IN_CLASSB_NSHIFT", - "IN_CLASSC_HOST", - "IN_CLASSC_NET", - "IN_CLASSC_NSHIFT", - "IN_CLASSD_HOST", - "IN_CLASSD_NET", - "IN_CLASSD_NSHIFT", - "IN_CLOEXEC", - "IN_CLOSE", - "IN_CLOSE_NOWRITE", - "IN_CLOSE_WRITE", - "IN_CREATE", - "IN_DELETE", - "IN_DELETE_SELF", - "IN_DONT_FOLLOW", - "IN_EXCL_UNLINK", - "IN_IGNORED", - "IN_ISDIR", - "IN_LINKLOCALNETNUM", - "IN_LOOPBACKNET", - "IN_MASK_ADD", - "IN_MODIFY", - "IN_MOVE", - "IN_MOVED_FROM", - "IN_MOVED_TO", - "IN_MOVE_SELF", - "IN_NONBLOCK", - "IN_ONESHOT", - "IN_ONLYDIR", - "IN_OPEN", - "IN_Q_OVERFLOW", - "IN_RFC3021_HOST", - "IN_RFC3021_MASK", - "IN_RFC3021_NET", - "IN_RFC3021_NSHIFT", - "IN_UNMOUNT", - "IOC_IN", - "IOC_INOUT", - "IOC_OUT", - "IOC_VENDOR", - "IOC_WS2", - "IO_REPARSE_TAG_SYMLINK", - "IPMreq", - "IPMreqn", - "IPPROTO_3PC", - "IPPROTO_ADFS", - "IPPROTO_AH", - "IPPROTO_AHIP", - "IPPROTO_APES", - "IPPROTO_ARGUS", - "IPPROTO_AX25", - "IPPROTO_BHA", - "IPPROTO_BLT", - "IPPROTO_BRSATMON", - "IPPROTO_CARP", - "IPPROTO_CFTP", - "IPPROTO_CHAOS", - "IPPROTO_CMTP", - "IPPROTO_COMP", - "IPPROTO_CPHB", - "IPPROTO_CPNX", - "IPPROTO_DCCP", - "IPPROTO_DDP", - "IPPROTO_DGP", - "IPPROTO_DIVERT", - "IPPROTO_DIVERT_INIT", - "IPPROTO_DIVERT_RESP", - "IPPROTO_DONE", - "IPPROTO_DSTOPTS", - "IPPROTO_EGP", - "IPPROTO_EMCON", - "IPPROTO_ENCAP", - "IPPROTO_EON", - "IPPROTO_ESP", - "IPPROTO_ETHERIP", - "IPPROTO_FRAGMENT", - "IPPROTO_GGP", - "IPPROTO_GMTP", - "IPPROTO_GRE", - "IPPROTO_HELLO", - "IPPROTO_HMP", - "IPPROTO_HOPOPTS", - "IPPROTO_ICMP", - "IPPROTO_ICMPV6", - "IPPROTO_IDP", - "IPPROTO_IDPR", - "IPPROTO_IDRP", - "IPPROTO_IGMP", - "IPPROTO_IGP", - "IPPROTO_IGRP", - "IPPROTO_IL", - "IPPROTO_INLSP", - "IPPROTO_INP", - "IPPROTO_IP", - "IPPROTO_IPCOMP", - "IPPROTO_IPCV", - "IPPROTO_IPEIP", - "IPPROTO_IPIP", - "IPPROTO_IPPC", - "IPPROTO_IPV4", - "IPPROTO_IPV6", - "IPPROTO_IPV6_ICMP", - "IPPROTO_IRTP", - "IPPROTO_KRYPTOLAN", - "IPPROTO_LARP", - "IPPROTO_LEAF1", - "IPPROTO_LEAF2", - "IPPROTO_MAX", - "IPPROTO_MAXID", - "IPPROTO_MEAS", - "IPPROTO_MH", - "IPPROTO_MHRP", - "IPPROTO_MICP", - "IPPROTO_MOBILE", - "IPPROTO_MPLS", - "IPPROTO_MTP", - "IPPROTO_MUX", - "IPPROTO_ND", - "IPPROTO_NHRP", - "IPPROTO_NONE", - "IPPROTO_NSP", - "IPPROTO_NVPII", - "IPPROTO_OLD_DIVERT", - "IPPROTO_OSPFIGP", - "IPPROTO_PFSYNC", - "IPPROTO_PGM", - "IPPROTO_PIGP", - "IPPROTO_PIM", - "IPPROTO_PRM", - "IPPROTO_PUP", - "IPPROTO_PVP", - "IPPROTO_RAW", - "IPPROTO_RCCMON", - "IPPROTO_RDP", - "IPPROTO_ROUTING", - "IPPROTO_RSVP", - "IPPROTO_RVD", - "IPPROTO_SATEXPAK", - "IPPROTO_SATMON", - "IPPROTO_SCCSP", - "IPPROTO_SCTP", - "IPPROTO_SDRP", - "IPPROTO_SEND", - "IPPROTO_SEP", - "IPPROTO_SKIP", - "IPPROTO_SPACER", - "IPPROTO_SRPC", - "IPPROTO_ST", - "IPPROTO_SVMTP", - "IPPROTO_SWIPE", - "IPPROTO_TCF", - "IPPROTO_TCP", - "IPPROTO_TLSP", - "IPPROTO_TP", - "IPPROTO_TPXX", - "IPPROTO_TRUNK1", - "IPPROTO_TRUNK2", - "IPPROTO_TTP", - "IPPROTO_UDP", - "IPPROTO_UDPLITE", - "IPPROTO_VINES", - "IPPROTO_VISA", - "IPPROTO_VMTP", - "IPPROTO_VRRP", - "IPPROTO_WBEXPAK", - "IPPROTO_WBMON", - "IPPROTO_WSN", - "IPPROTO_XNET", - "IPPROTO_XTP", - "IPV6_2292DSTOPTS", - "IPV6_2292HOPLIMIT", - "IPV6_2292HOPOPTS", - "IPV6_2292NEXTHOP", - "IPV6_2292PKTINFO", - "IPV6_2292PKTOPTIONS", - "IPV6_2292RTHDR", - "IPV6_ADDRFORM", - "IPV6_ADD_MEMBERSHIP", - "IPV6_AUTHHDR", - "IPV6_AUTH_LEVEL", - "IPV6_AUTOFLOWLABEL", - "IPV6_BINDANY", - "IPV6_BINDV6ONLY", - "IPV6_BOUND_IF", - "IPV6_CHECKSUM", - "IPV6_DEFAULT_MULTICAST_HOPS", - "IPV6_DEFAULT_MULTICAST_LOOP", - "IPV6_DEFHLIM", - "IPV6_DONTFRAG", - "IPV6_DROP_MEMBERSHIP", - "IPV6_DSTOPTS", - "IPV6_ESP_NETWORK_LEVEL", - "IPV6_ESP_TRANS_LEVEL", - "IPV6_FAITH", - "IPV6_FLOWINFO_MASK", - "IPV6_FLOWLABEL_MASK", - "IPV6_FRAGTTL", - "IPV6_FW_ADD", - "IPV6_FW_DEL", - "IPV6_FW_FLUSH", - "IPV6_FW_GET", - "IPV6_FW_ZERO", - "IPV6_HLIMDEC", - "IPV6_HOPLIMIT", - "IPV6_HOPOPTS", - "IPV6_IPCOMP_LEVEL", - "IPV6_IPSEC_POLICY", - "IPV6_JOIN_ANYCAST", - "IPV6_JOIN_GROUP", - "IPV6_LEAVE_ANYCAST", - "IPV6_LEAVE_GROUP", - "IPV6_MAXHLIM", - "IPV6_MAXOPTHDR", - "IPV6_MAXPACKET", - "IPV6_MAX_GROUP_SRC_FILTER", - "IPV6_MAX_MEMBERSHIPS", - "IPV6_MAX_SOCK_SRC_FILTER", - "IPV6_MIN_MEMBERSHIPS", - "IPV6_MMTU", - "IPV6_MSFILTER", - "IPV6_MTU", - "IPV6_MTU_DISCOVER", - "IPV6_MULTICAST_HOPS", - "IPV6_MULTICAST_IF", - "IPV6_MULTICAST_LOOP", - "IPV6_NEXTHOP", - "IPV6_OPTIONS", - "IPV6_PATHMTU", - "IPV6_PIPEX", - "IPV6_PKTINFO", - "IPV6_PMTUDISC_DO", - "IPV6_PMTUDISC_DONT", - "IPV6_PMTUDISC_PROBE", - "IPV6_PMTUDISC_WANT", - "IPV6_PORTRANGE", - "IPV6_PORTRANGE_DEFAULT", - "IPV6_PORTRANGE_HIGH", - "IPV6_PORTRANGE_LOW", - "IPV6_PREFER_TEMPADDR", - "IPV6_RECVDSTOPTS", - "IPV6_RECVDSTPORT", - "IPV6_RECVERR", - "IPV6_RECVHOPLIMIT", - "IPV6_RECVHOPOPTS", - "IPV6_RECVPATHMTU", - "IPV6_RECVPKTINFO", - "IPV6_RECVRTHDR", - "IPV6_RECVTCLASS", - "IPV6_ROUTER_ALERT", - "IPV6_RTABLE", - "IPV6_RTHDR", - "IPV6_RTHDRDSTOPTS", - "IPV6_RTHDR_LOOSE", - "IPV6_RTHDR_STRICT", - "IPV6_RTHDR_TYPE_0", - "IPV6_RXDSTOPTS", - "IPV6_RXHOPOPTS", - "IPV6_SOCKOPT_RESERVED1", - "IPV6_TCLASS", - "IPV6_UNICAST_HOPS", - "IPV6_USE_MIN_MTU", - "IPV6_V6ONLY", - "IPV6_VERSION", - "IPV6_VERSION_MASK", - "IPV6_XFRM_POLICY", - "IP_ADD_MEMBERSHIP", - "IP_ADD_SOURCE_MEMBERSHIP", - "IP_AUTH_LEVEL", - "IP_BINDANY", - "IP_BLOCK_SOURCE", - "IP_BOUND_IF", - "IP_DEFAULT_MULTICAST_LOOP", - "IP_DEFAULT_MULTICAST_TTL", - "IP_DF", - "IP_DIVERTFL", - "IP_DONTFRAG", - "IP_DROP_MEMBERSHIP", - "IP_DROP_SOURCE_MEMBERSHIP", - "IP_DUMMYNET3", - "IP_DUMMYNET_CONFIGURE", - "IP_DUMMYNET_DEL", - "IP_DUMMYNET_FLUSH", - "IP_DUMMYNET_GET", - "IP_EF", - "IP_ERRORMTU", - "IP_ESP_NETWORK_LEVEL", - "IP_ESP_TRANS_LEVEL", - "IP_FAITH", - "IP_FREEBIND", - "IP_FW3", - "IP_FW_ADD", - "IP_FW_DEL", - "IP_FW_FLUSH", - "IP_FW_GET", - "IP_FW_NAT_CFG", - "IP_FW_NAT_DEL", - "IP_FW_NAT_GET_CONFIG", - "IP_FW_NAT_GET_LOG", - "IP_FW_RESETLOG", - "IP_FW_TABLE_ADD", - "IP_FW_TABLE_DEL", - "IP_FW_TABLE_FLUSH", - "IP_FW_TABLE_GETSIZE", - "IP_FW_TABLE_LIST", - "IP_FW_ZERO", - "IP_HDRINCL", - "IP_IPCOMP_LEVEL", - "IP_IPSECFLOWINFO", - "IP_IPSEC_LOCAL_AUTH", - "IP_IPSEC_LOCAL_CRED", - "IP_IPSEC_LOCAL_ID", - "IP_IPSEC_POLICY", - "IP_IPSEC_REMOTE_AUTH", - "IP_IPSEC_REMOTE_CRED", - "IP_IPSEC_REMOTE_ID", - "IP_MAXPACKET", - "IP_MAX_GROUP_SRC_FILTER", - "IP_MAX_MEMBERSHIPS", - "IP_MAX_SOCK_MUTE_FILTER", - "IP_MAX_SOCK_SRC_FILTER", - "IP_MAX_SOURCE_FILTER", - "IP_MF", - "IP_MINFRAGSIZE", - "IP_MINTTL", - "IP_MIN_MEMBERSHIPS", - "IP_MSFILTER", - "IP_MSS", - "IP_MTU", - "IP_MTU_DISCOVER", - "IP_MULTICAST_IF", - "IP_MULTICAST_IFINDEX", - "IP_MULTICAST_LOOP", - "IP_MULTICAST_TTL", - "IP_MULTICAST_VIF", - "IP_NAT__XXX", - "IP_OFFMASK", - "IP_OLD_FW_ADD", - "IP_OLD_FW_DEL", - "IP_OLD_FW_FLUSH", - "IP_OLD_FW_GET", - "IP_OLD_FW_RESETLOG", - "IP_OLD_FW_ZERO", - "IP_ONESBCAST", - "IP_OPTIONS", - "IP_ORIGDSTADDR", - "IP_PASSSEC", - "IP_PIPEX", - "IP_PKTINFO", - "IP_PKTOPTIONS", - "IP_PMTUDISC", - "IP_PMTUDISC_DO", - "IP_PMTUDISC_DONT", - "IP_PMTUDISC_PROBE", - "IP_PMTUDISC_WANT", - "IP_PORTRANGE", - "IP_PORTRANGE_DEFAULT", - "IP_PORTRANGE_HIGH", - "IP_PORTRANGE_LOW", - "IP_RECVDSTADDR", - "IP_RECVDSTPORT", - "IP_RECVERR", - "IP_RECVIF", - "IP_RECVOPTS", - "IP_RECVORIGDSTADDR", - "IP_RECVPKTINFO", - "IP_RECVRETOPTS", - "IP_RECVRTABLE", - "IP_RECVTOS", - "IP_RECVTTL", - "IP_RETOPTS", - "IP_RF", - "IP_ROUTER_ALERT", - "IP_RSVP_OFF", - "IP_RSVP_ON", - "IP_RSVP_VIF_OFF", - "IP_RSVP_VIF_ON", - "IP_RTABLE", - "IP_SENDSRCADDR", - "IP_STRIPHDR", - "IP_TOS", - "IP_TRAFFIC_MGT_BACKGROUND", - "IP_TRANSPARENT", - "IP_TTL", - "IP_UNBLOCK_SOURCE", - "IP_XFRM_POLICY", - "IPv6MTUInfo", - "IPv6Mreq", - "ISIG", - "ISTRIP", - "IUCLC", - "IUTF8", - "IXANY", - "IXOFF", - "IXON", - "IfAddrmsg", - "IfAnnounceMsghdr", - "IfData", - "IfInfomsg", - "IfMsghdr", - "IfaMsghdr", - "IfmaMsghdr", - "IfmaMsghdr2", - "ImplementsGetwd", - "Inet4Pktinfo", - "Inet6Pktinfo", - "InotifyAddWatch", - "InotifyEvent", - "InotifyInit", - "InotifyInit1", - "InotifyRmWatch", - "InterfaceAddrMessage", - "InterfaceAnnounceMessage", - "InterfaceInfo", - "InterfaceMessage", - "InterfaceMulticastAddrMessage", - "InvalidHandle", - "Ioperm", - "Iopl", - "Iovec", - "IpAdapterInfo", - "IpAddrString", - "IpAddressString", - "IpMaskString", - "Issetugid", - "KEY_ALL_ACCESS", - "KEY_CREATE_LINK", - "KEY_CREATE_SUB_KEY", - "KEY_ENUMERATE_SUB_KEYS", - "KEY_EXECUTE", - "KEY_NOTIFY", - "KEY_QUERY_VALUE", - "KEY_READ", - "KEY_SET_VALUE", - "KEY_WOW64_32KEY", - "KEY_WOW64_64KEY", - "KEY_WRITE", - "Kevent", - "Kevent_t", - "Kill", - "Klogctl", - "Kqueue", - "LANG_ENGLISH", - "LAYERED_PROTOCOL", - "LCNT_OVERLOAD_FLUSH", - "LINUX_REBOOT_CMD_CAD_OFF", - "LINUX_REBOOT_CMD_CAD_ON", - "LINUX_REBOOT_CMD_HALT", - "LINUX_REBOOT_CMD_KEXEC", - "LINUX_REBOOT_CMD_POWER_OFF", - "LINUX_REBOOT_CMD_RESTART", - "LINUX_REBOOT_CMD_RESTART2", - "LINUX_REBOOT_CMD_SW_SUSPEND", - "LINUX_REBOOT_MAGIC1", - "LINUX_REBOOT_MAGIC2", - "LOCK_EX", - "LOCK_NB", - "LOCK_SH", - "LOCK_UN", - "LazyDLL", - "LazyProc", - "Lchown", - "Linger", - "Link", - "Listen", - "Listxattr", - "LoadCancelIoEx", - "LoadConnectEx", - "LoadCreateSymbolicLink", - "LoadDLL", - "LoadGetAddrInfo", - "LoadLibrary", - "LoadSetFileCompletionNotificationModes", - "LocalFree", - "Log2phys_t", - "LookupAccountName", - "LookupAccountSid", - "LookupSID", - "LsfJump", - "LsfSocket", - "LsfStmt", - "Lstat", - "MADV_AUTOSYNC", - "MADV_CAN_REUSE", - "MADV_CORE", - "MADV_DOFORK", - "MADV_DONTFORK", - "MADV_DONTNEED", - "MADV_FREE", - "MADV_FREE_REUSABLE", - "MADV_FREE_REUSE", - "MADV_HUGEPAGE", - "MADV_HWPOISON", - "MADV_MERGEABLE", - "MADV_NOCORE", - "MADV_NOHUGEPAGE", - "MADV_NORMAL", - "MADV_NOSYNC", - "MADV_PROTECT", - "MADV_RANDOM", - "MADV_REMOVE", - "MADV_SEQUENTIAL", - "MADV_SPACEAVAIL", - "MADV_UNMERGEABLE", - "MADV_WILLNEED", - "MADV_ZERO_WIRED_PAGES", - "MAP_32BIT", - "MAP_ALIGNED_SUPER", - "MAP_ALIGNMENT_16MB", - "MAP_ALIGNMENT_1TB", - "MAP_ALIGNMENT_256TB", - "MAP_ALIGNMENT_4GB", - "MAP_ALIGNMENT_64KB", - "MAP_ALIGNMENT_64PB", - "MAP_ALIGNMENT_MASK", - "MAP_ALIGNMENT_SHIFT", - "MAP_ANON", - "MAP_ANONYMOUS", - "MAP_COPY", - "MAP_DENYWRITE", - "MAP_EXECUTABLE", - "MAP_FILE", - "MAP_FIXED", - "MAP_FLAGMASK", - "MAP_GROWSDOWN", - "MAP_HASSEMAPHORE", - "MAP_HUGETLB", - "MAP_INHERIT", - "MAP_INHERIT_COPY", - "MAP_INHERIT_DEFAULT", - "MAP_INHERIT_DONATE_COPY", - "MAP_INHERIT_NONE", - "MAP_INHERIT_SHARE", - "MAP_JIT", - "MAP_LOCKED", - "MAP_NOCACHE", - "MAP_NOCORE", - "MAP_NOEXTEND", - "MAP_NONBLOCK", - "MAP_NORESERVE", - "MAP_NOSYNC", - "MAP_POPULATE", - "MAP_PREFAULT_READ", - "MAP_PRIVATE", - "MAP_RENAME", - "MAP_RESERVED0080", - "MAP_RESERVED0100", - "MAP_SHARED", - "MAP_STACK", - "MAP_TRYFIXED", - "MAP_TYPE", - "MAP_WIRED", - "MAXIMUM_REPARSE_DATA_BUFFER_SIZE", - "MAXLEN_IFDESCR", - "MAXLEN_PHYSADDR", - "MAX_ADAPTER_ADDRESS_LENGTH", - "MAX_ADAPTER_DESCRIPTION_LENGTH", - "MAX_ADAPTER_NAME_LENGTH", - "MAX_COMPUTERNAME_LENGTH", - "MAX_INTERFACE_NAME_LEN", - "MAX_LONG_PATH", - "MAX_PATH", - "MAX_PROTOCOL_CHAIN", - "MCL_CURRENT", - "MCL_FUTURE", - "MNT_DETACH", - "MNT_EXPIRE", - "MNT_FORCE", - "MSG_BCAST", - "MSG_CMSG_CLOEXEC", - "MSG_COMPAT", - "MSG_CONFIRM", - "MSG_CONTROLMBUF", - "MSG_CTRUNC", - "MSG_DONTROUTE", - "MSG_DONTWAIT", - "MSG_EOF", - "MSG_EOR", - "MSG_ERRQUEUE", - "MSG_FASTOPEN", - "MSG_FIN", - "MSG_FLUSH", - "MSG_HAVEMORE", - "MSG_HOLD", - "MSG_IOVUSRSPACE", - "MSG_LENUSRSPACE", - "MSG_MCAST", - "MSG_MORE", - "MSG_NAMEMBUF", - "MSG_NBIO", - "MSG_NEEDSA", - "MSG_NOSIGNAL", - "MSG_NOTIFICATION", - "MSG_OOB", - "MSG_PEEK", - "MSG_PROXY", - "MSG_RCVMORE", - "MSG_RST", - "MSG_SEND", - "MSG_SYN", - "MSG_TRUNC", - "MSG_TRYHARD", - "MSG_USERFLAGS", - "MSG_WAITALL", - "MSG_WAITFORONE", - "MSG_WAITSTREAM", - "MS_ACTIVE", - "MS_ASYNC", - "MS_BIND", - "MS_DEACTIVATE", - "MS_DIRSYNC", - "MS_INVALIDATE", - "MS_I_VERSION", - "MS_KERNMOUNT", - "MS_KILLPAGES", - "MS_MANDLOCK", - "MS_MGC_MSK", - "MS_MGC_VAL", - "MS_MOVE", - "MS_NOATIME", - "MS_NODEV", - "MS_NODIRATIME", - "MS_NOEXEC", - "MS_NOSUID", - "MS_NOUSER", - "MS_POSIXACL", - "MS_PRIVATE", - "MS_RDONLY", - "MS_REC", - "MS_RELATIME", - "MS_REMOUNT", - "MS_RMT_MASK", - "MS_SHARED", - "MS_SILENT", - "MS_SLAVE", - "MS_STRICTATIME", - "MS_SYNC", - "MS_SYNCHRONOUS", - "MS_UNBINDABLE", - "Madvise", - "MapViewOfFile", - "MaxTokenInfoClass", - "Mclpool", - "MibIfRow", - "Mkdir", - "Mkdirat", - "Mkfifo", - "Mknod", - "Mknodat", - "Mlock", - "Mlockall", - "Mmap", - "Mount", - "MoveFile", - "Mprotect", - "Msghdr", - "Munlock", - "Munlockall", - "Munmap", - "MustLoadDLL", - "NAME_MAX", - "NETLINK_ADD_MEMBERSHIP", - "NETLINK_AUDIT", - "NETLINK_BROADCAST_ERROR", - "NETLINK_CONNECTOR", - "NETLINK_DNRTMSG", - "NETLINK_DROP_MEMBERSHIP", - "NETLINK_ECRYPTFS", - "NETLINK_FIB_LOOKUP", - "NETLINK_FIREWALL", - "NETLINK_GENERIC", - "NETLINK_INET_DIAG", - "NETLINK_IP6_FW", - "NETLINK_ISCSI", - "NETLINK_KOBJECT_UEVENT", - "NETLINK_NETFILTER", - "NETLINK_NFLOG", - "NETLINK_NO_ENOBUFS", - "NETLINK_PKTINFO", - "NETLINK_RDMA", - "NETLINK_ROUTE", - "NETLINK_SCSITRANSPORT", - "NETLINK_SELINUX", - "NETLINK_UNUSED", - "NETLINK_USERSOCK", - "NETLINK_XFRM", - "NET_RT_DUMP", - "NET_RT_DUMP2", - "NET_RT_FLAGS", - "NET_RT_IFLIST", - "NET_RT_IFLIST2", - "NET_RT_IFLISTL", - "NET_RT_IFMALIST", - "NET_RT_MAXID", - "NET_RT_OIFLIST", - "NET_RT_OOIFLIST", - "NET_RT_STAT", - "NET_RT_STATS", - "NET_RT_TABLE", - "NET_RT_TRASH", - "NLA_ALIGNTO", - "NLA_F_NESTED", - "NLA_F_NET_BYTEORDER", - "NLA_HDRLEN", - "NLMSG_ALIGNTO", - "NLMSG_DONE", - "NLMSG_ERROR", - "NLMSG_HDRLEN", - "NLMSG_MIN_TYPE", - "NLMSG_NOOP", - "NLMSG_OVERRUN", - "NLM_F_ACK", - "NLM_F_APPEND", - "NLM_F_ATOMIC", - "NLM_F_CREATE", - "NLM_F_DUMP", - "NLM_F_ECHO", - "NLM_F_EXCL", - "NLM_F_MATCH", - "NLM_F_MULTI", - "NLM_F_REPLACE", - "NLM_F_REQUEST", - "NLM_F_ROOT", - "NOFLSH", - "NOTE_ABSOLUTE", - "NOTE_ATTRIB", - "NOTE_BACKGROUND", - "NOTE_CHILD", - "NOTE_CRITICAL", - "NOTE_DELETE", - "NOTE_EOF", - "NOTE_EXEC", - "NOTE_EXIT", - "NOTE_EXITSTATUS", - "NOTE_EXIT_CSERROR", - "NOTE_EXIT_DECRYPTFAIL", - "NOTE_EXIT_DETAIL", - "NOTE_EXIT_DETAIL_MASK", - "NOTE_EXIT_MEMORY", - "NOTE_EXIT_REPARENTED", - "NOTE_EXTEND", - "NOTE_FFAND", - "NOTE_FFCOPY", - "NOTE_FFCTRLMASK", - "NOTE_FFLAGSMASK", - "NOTE_FFNOP", - "NOTE_FFOR", - "NOTE_FORK", - "NOTE_LEEWAY", - "NOTE_LINK", - "NOTE_LOWAT", - "NOTE_NONE", - "NOTE_NSECONDS", - "NOTE_PCTRLMASK", - "NOTE_PDATAMASK", - "NOTE_REAP", - "NOTE_RENAME", - "NOTE_RESOURCEEND", - "NOTE_REVOKE", - "NOTE_SECONDS", - "NOTE_SIGNAL", - "NOTE_TRACK", - "NOTE_TRACKERR", - "NOTE_TRIGGER", - "NOTE_TRUNCATE", - "NOTE_USECONDS", - "NOTE_VM_ERROR", - "NOTE_VM_PRESSURE", - "NOTE_VM_PRESSURE_SUDDEN_TERMINATE", - "NOTE_VM_PRESSURE_TERMINATE", - "NOTE_WRITE", - "NameCanonical", - "NameCanonicalEx", - "NameDisplay", - "NameDnsDomain", - "NameFullyQualifiedDN", - "NameSamCompatible", - "NameServicePrincipal", - "NameUniqueId", - "NameUnknown", - "NameUserPrincipal", - "Nanosleep", - "NetApiBufferFree", - "NetGetJoinInformation", - "NetSetupDomainName", - "NetSetupUnjoined", - "NetSetupUnknownStatus", - "NetSetupWorkgroupName", - "NetUserGetInfo", - "NetlinkMessage", - "NetlinkRIB", - "NetlinkRouteAttr", - "NetlinkRouteRequest", - "NewCallback", - "NewCallbackCDecl", - "NewLazyDLL", - "NlAttr", - "NlMsgerr", - "NlMsghdr", - "NsecToFiletime", - "NsecToTimespec", - "NsecToTimeval", - "Ntohs", - "OCRNL", - "OFDEL", - "OFILL", - "OFIOGETBMAP", - "OID_PKIX_KP_SERVER_AUTH", - "OID_SERVER_GATED_CRYPTO", - "OID_SGC_NETSCAPE", - "OLCUC", - "ONLCR", - "ONLRET", - "ONOCR", - "ONOEOT", - "OPEN_ALWAYS", - "OPEN_EXISTING", - "OPOST", - "O_ACCMODE", - "O_ALERT", - "O_ALT_IO", - "O_APPEND", - "O_ASYNC", - "O_CLOEXEC", - "O_CREAT", - "O_DIRECT", - "O_DIRECTORY", - "O_DP_GETRAWENCRYPTED", - "O_DSYNC", - "O_EVTONLY", - "O_EXCL", - "O_EXEC", - "O_EXLOCK", - "O_FSYNC", - "O_LARGEFILE", - "O_NDELAY", - "O_NOATIME", - "O_NOCTTY", - "O_NOFOLLOW", - "O_NONBLOCK", - "O_NOSIGPIPE", - "O_POPUP", - "O_RDONLY", - "O_RDWR", - "O_RSYNC", - "O_SHLOCK", - "O_SYMLINK", - "O_SYNC", - "O_TRUNC", - "O_TTY_INIT", - "O_WRONLY", - "Open", - "OpenCurrentProcessToken", - "OpenProcess", - "OpenProcessToken", - "Openat", - "Overlapped", - "PACKET_ADD_MEMBERSHIP", - "PACKET_BROADCAST", - "PACKET_DROP_MEMBERSHIP", - "PACKET_FASTROUTE", - "PACKET_HOST", - "PACKET_LOOPBACK", - "PACKET_MR_ALLMULTI", - "PACKET_MR_MULTICAST", - "PACKET_MR_PROMISC", - "PACKET_MULTICAST", - "PACKET_OTHERHOST", - "PACKET_OUTGOING", - "PACKET_RECV_OUTPUT", - "PACKET_RX_RING", - "PACKET_STATISTICS", - "PAGE_EXECUTE_READ", - "PAGE_EXECUTE_READWRITE", - "PAGE_EXECUTE_WRITECOPY", - "PAGE_READONLY", - "PAGE_READWRITE", - "PAGE_WRITECOPY", - "PARENB", - "PARMRK", - "PARODD", - "PENDIN", - "PFL_HIDDEN", - "PFL_MATCHES_PROTOCOL_ZERO", - "PFL_MULTIPLE_PROTO_ENTRIES", - "PFL_NETWORKDIRECT_PROVIDER", - "PFL_RECOMMENDED_PROTO_ENTRY", - "PF_FLUSH", - "PKCS_7_ASN_ENCODING", - "PMC5_PIPELINE_FLUSH", - "PRIO_PGRP", - "PRIO_PROCESS", - "PRIO_USER", - "PRI_IOFLUSH", - "PROCESS_QUERY_INFORMATION", - "PROCESS_TERMINATE", - "PROT_EXEC", - "PROT_GROWSDOWN", - "PROT_GROWSUP", - "PROT_NONE", - "PROT_READ", - "PROT_WRITE", - "PROV_DH_SCHANNEL", - "PROV_DSS", - "PROV_DSS_DH", - "PROV_EC_ECDSA_FULL", - "PROV_EC_ECDSA_SIG", - "PROV_EC_ECNRA_FULL", - "PROV_EC_ECNRA_SIG", - "PROV_FORTEZZA", - "PROV_INTEL_SEC", - "PROV_MS_EXCHANGE", - "PROV_REPLACE_OWF", - "PROV_RNG", - "PROV_RSA_AES", - "PROV_RSA_FULL", - "PROV_RSA_SCHANNEL", - "PROV_RSA_SIG", - "PROV_SPYRUS_LYNKS", - "PROV_SSL", - "PR_CAPBSET_DROP", - "PR_CAPBSET_READ", - "PR_CLEAR_SECCOMP_FILTER", - "PR_ENDIAN_BIG", - "PR_ENDIAN_LITTLE", - "PR_ENDIAN_PPC_LITTLE", - "PR_FPEMU_NOPRINT", - "PR_FPEMU_SIGFPE", - "PR_FP_EXC_ASYNC", - "PR_FP_EXC_DISABLED", - "PR_FP_EXC_DIV", - "PR_FP_EXC_INV", - "PR_FP_EXC_NONRECOV", - "PR_FP_EXC_OVF", - "PR_FP_EXC_PRECISE", - "PR_FP_EXC_RES", - "PR_FP_EXC_SW_ENABLE", - "PR_FP_EXC_UND", - "PR_GET_DUMPABLE", - "PR_GET_ENDIAN", - "PR_GET_FPEMU", - "PR_GET_FPEXC", - "PR_GET_KEEPCAPS", - "PR_GET_NAME", - "PR_GET_PDEATHSIG", - "PR_GET_SECCOMP", - "PR_GET_SECCOMP_FILTER", - "PR_GET_SECUREBITS", - "PR_GET_TIMERSLACK", - "PR_GET_TIMING", - "PR_GET_TSC", - "PR_GET_UNALIGN", - "PR_MCE_KILL", - "PR_MCE_KILL_CLEAR", - "PR_MCE_KILL_DEFAULT", - "PR_MCE_KILL_EARLY", - "PR_MCE_KILL_GET", - "PR_MCE_KILL_LATE", - "PR_MCE_KILL_SET", - "PR_SECCOMP_FILTER_EVENT", - "PR_SECCOMP_FILTER_SYSCALL", - "PR_SET_DUMPABLE", - "PR_SET_ENDIAN", - "PR_SET_FPEMU", - "PR_SET_FPEXC", - "PR_SET_KEEPCAPS", - "PR_SET_NAME", - "PR_SET_PDEATHSIG", - "PR_SET_PTRACER", - "PR_SET_SECCOMP", - "PR_SET_SECCOMP_FILTER", - "PR_SET_SECUREBITS", - "PR_SET_TIMERSLACK", - "PR_SET_TIMING", - "PR_SET_TSC", - "PR_SET_UNALIGN", - "PR_TASK_PERF_EVENTS_DISABLE", - "PR_TASK_PERF_EVENTS_ENABLE", - "PR_TIMING_STATISTICAL", - "PR_TIMING_TIMESTAMP", - "PR_TSC_ENABLE", - "PR_TSC_SIGSEGV", - "PR_UNALIGN_NOPRINT", - "PR_UNALIGN_SIGBUS", - "PTRACE_ARCH_PRCTL", - "PTRACE_ATTACH", - "PTRACE_CONT", - "PTRACE_DETACH", - "PTRACE_EVENT_CLONE", - "PTRACE_EVENT_EXEC", - "PTRACE_EVENT_EXIT", - "PTRACE_EVENT_FORK", - "PTRACE_EVENT_VFORK", - "PTRACE_EVENT_VFORK_DONE", - "PTRACE_GETCRUNCHREGS", - "PTRACE_GETEVENTMSG", - "PTRACE_GETFPREGS", - "PTRACE_GETFPXREGS", - "PTRACE_GETHBPREGS", - "PTRACE_GETREGS", - "PTRACE_GETREGSET", - "PTRACE_GETSIGINFO", - "PTRACE_GETVFPREGS", - "PTRACE_GETWMMXREGS", - "PTRACE_GET_THREAD_AREA", - "PTRACE_KILL", - "PTRACE_OLDSETOPTIONS", - "PTRACE_O_MASK", - "PTRACE_O_TRACECLONE", - "PTRACE_O_TRACEEXEC", - "PTRACE_O_TRACEEXIT", - "PTRACE_O_TRACEFORK", - "PTRACE_O_TRACESYSGOOD", - "PTRACE_O_TRACEVFORK", - "PTRACE_O_TRACEVFORKDONE", - "PTRACE_PEEKDATA", - "PTRACE_PEEKTEXT", - "PTRACE_PEEKUSR", - "PTRACE_POKEDATA", - "PTRACE_POKETEXT", - "PTRACE_POKEUSR", - "PTRACE_SETCRUNCHREGS", - "PTRACE_SETFPREGS", - "PTRACE_SETFPXREGS", - "PTRACE_SETHBPREGS", - "PTRACE_SETOPTIONS", - "PTRACE_SETREGS", - "PTRACE_SETREGSET", - "PTRACE_SETSIGINFO", - "PTRACE_SETVFPREGS", - "PTRACE_SETWMMXREGS", - "PTRACE_SET_SYSCALL", - "PTRACE_SET_THREAD_AREA", - "PTRACE_SINGLEBLOCK", - "PTRACE_SINGLESTEP", - "PTRACE_SYSCALL", - "PTRACE_SYSEMU", - "PTRACE_SYSEMU_SINGLESTEP", - "PTRACE_TRACEME", - "PT_ATTACH", - "PT_ATTACHEXC", - "PT_CONTINUE", - "PT_DATA_ADDR", - "PT_DENY_ATTACH", - "PT_DETACH", - "PT_FIRSTMACH", - "PT_FORCEQUOTA", - "PT_KILL", - "PT_MASK", - "PT_READ_D", - "PT_READ_I", - "PT_READ_U", - "PT_SIGEXC", - "PT_STEP", - "PT_TEXT_ADDR", - "PT_TEXT_END_ADDR", - "PT_THUPDATE", - "PT_TRACE_ME", - "PT_WRITE_D", - "PT_WRITE_I", - "PT_WRITE_U", - "ParseDirent", - "ParseNetlinkMessage", - "ParseNetlinkRouteAttr", - "ParseRoutingMessage", - "ParseRoutingSockaddr", - "ParseSocketControlMessage", - "ParseUnixCredentials", - "ParseUnixRights", - "PathMax", - "Pathconf", - "Pause", - "Pipe", - "Pipe2", - "PivotRoot", - "Pointer", - "PostQueuedCompletionStatus", - "Pread", - "Proc", - "ProcAttr", - "Process32First", - "Process32Next", - "ProcessEntry32", - "ProcessInformation", - "Protoent", - "PtraceAttach", - "PtraceCont", - "PtraceDetach", - "PtraceGetEventMsg", - "PtraceGetRegs", - "PtracePeekData", - "PtracePeekText", - "PtracePokeData", - "PtracePokeText", - "PtraceRegs", - "PtraceSetOptions", - "PtraceSetRegs", - "PtraceSingleStep", - "PtraceSyscall", - "Pwrite", - "REG_BINARY", - "REG_DWORD", - "REG_DWORD_BIG_ENDIAN", - "REG_DWORD_LITTLE_ENDIAN", - "REG_EXPAND_SZ", - "REG_FULL_RESOURCE_DESCRIPTOR", - "REG_LINK", - "REG_MULTI_SZ", - "REG_NONE", - "REG_QWORD", - "REG_QWORD_LITTLE_ENDIAN", - "REG_RESOURCE_LIST", - "REG_RESOURCE_REQUIREMENTS_LIST", - "REG_SZ", - "RLIMIT_AS", - "RLIMIT_CORE", - "RLIMIT_CPU", - "RLIMIT_CPU_USAGE_MONITOR", - "RLIMIT_DATA", - "RLIMIT_FSIZE", - "RLIMIT_NOFILE", - "RLIMIT_STACK", - "RLIM_INFINITY", - "RTAX_ADVMSS", - "RTAX_AUTHOR", - "RTAX_BRD", - "RTAX_CWND", - "RTAX_DST", - "RTAX_FEATURES", - "RTAX_FEATURE_ALLFRAG", - "RTAX_FEATURE_ECN", - "RTAX_FEATURE_SACK", - "RTAX_FEATURE_TIMESTAMP", - "RTAX_GATEWAY", - "RTAX_GENMASK", - "RTAX_HOPLIMIT", - "RTAX_IFA", - "RTAX_IFP", - "RTAX_INITCWND", - "RTAX_INITRWND", - "RTAX_LABEL", - "RTAX_LOCK", - "RTAX_MAX", - "RTAX_MTU", - "RTAX_NETMASK", - "RTAX_REORDERING", - "RTAX_RTO_MIN", - "RTAX_RTT", - "RTAX_RTTVAR", - "RTAX_SRC", - "RTAX_SRCMASK", - "RTAX_SSTHRESH", - "RTAX_TAG", - "RTAX_UNSPEC", - "RTAX_WINDOW", - "RTA_ALIGNTO", - "RTA_AUTHOR", - "RTA_BRD", - "RTA_CACHEINFO", - "RTA_DST", - "RTA_FLOW", - "RTA_GATEWAY", - "RTA_GENMASK", - "RTA_IFA", - "RTA_IFP", - "RTA_IIF", - "RTA_LABEL", - "RTA_MAX", - "RTA_METRICS", - "RTA_MULTIPATH", - "RTA_NETMASK", - "RTA_OIF", - "RTA_PREFSRC", - "RTA_PRIORITY", - "RTA_SRC", - "RTA_SRCMASK", - "RTA_TABLE", - "RTA_TAG", - "RTA_UNSPEC", - "RTCF_DIRECTSRC", - "RTCF_DOREDIRECT", - "RTCF_LOG", - "RTCF_MASQ", - "RTCF_NAT", - "RTCF_VALVE", - "RTF_ADDRCLASSMASK", - "RTF_ADDRCONF", - "RTF_ALLONLINK", - "RTF_ANNOUNCE", - "RTF_BLACKHOLE", - "RTF_BROADCAST", - "RTF_CACHE", - "RTF_CLONED", - "RTF_CLONING", - "RTF_CONDEMNED", - "RTF_DEFAULT", - "RTF_DELCLONE", - "RTF_DONE", - "RTF_DYNAMIC", - "RTF_FLOW", - "RTF_FMASK", - "RTF_GATEWAY", - "RTF_GWFLAG_COMPAT", - "RTF_HOST", - "RTF_IFREF", - "RTF_IFSCOPE", - "RTF_INTERFACE", - "RTF_IRTT", - "RTF_LINKRT", - "RTF_LLDATA", - "RTF_LLINFO", - "RTF_LOCAL", - "RTF_MASK", - "RTF_MODIFIED", - "RTF_MPATH", - "RTF_MPLS", - "RTF_MSS", - "RTF_MTU", - "RTF_MULTICAST", - "RTF_NAT", - "RTF_NOFORWARD", - "RTF_NONEXTHOP", - "RTF_NOPMTUDISC", - "RTF_PERMANENT_ARP", - "RTF_PINNED", - "RTF_POLICY", - "RTF_PRCLONING", - "RTF_PROTO1", - "RTF_PROTO2", - "RTF_PROTO3", - "RTF_PROXY", - "RTF_REINSTATE", - "RTF_REJECT", - "RTF_RNH_LOCKED", - "RTF_ROUTER", - "RTF_SOURCE", - "RTF_SRC", - "RTF_STATIC", - "RTF_STICKY", - "RTF_THROW", - "RTF_TUNNEL", - "RTF_UP", - "RTF_USETRAILERS", - "RTF_WASCLONED", - "RTF_WINDOW", - "RTF_XRESOLVE", - "RTM_ADD", - "RTM_BASE", - "RTM_CHANGE", - "RTM_CHGADDR", - "RTM_DELACTION", - "RTM_DELADDR", - "RTM_DELADDRLABEL", - "RTM_DELETE", - "RTM_DELLINK", - "RTM_DELMADDR", - "RTM_DELNEIGH", - "RTM_DELQDISC", - "RTM_DELROUTE", - "RTM_DELRULE", - "RTM_DELTCLASS", - "RTM_DELTFILTER", - "RTM_DESYNC", - "RTM_F_CLONED", - "RTM_F_EQUALIZE", - "RTM_F_NOTIFY", - "RTM_F_PREFIX", - "RTM_GET", - "RTM_GET2", - "RTM_GETACTION", - "RTM_GETADDR", - "RTM_GETADDRLABEL", - "RTM_GETANYCAST", - "RTM_GETDCB", - "RTM_GETLINK", - "RTM_GETMULTICAST", - "RTM_GETNEIGH", - "RTM_GETNEIGHTBL", - "RTM_GETQDISC", - "RTM_GETROUTE", - "RTM_GETRULE", - "RTM_GETTCLASS", - "RTM_GETTFILTER", - "RTM_IEEE80211", - "RTM_IFANNOUNCE", - "RTM_IFINFO", - "RTM_IFINFO2", - "RTM_LLINFO_UPD", - "RTM_LOCK", - "RTM_LOSING", - "RTM_MAX", - "RTM_MAXSIZE", - "RTM_MISS", - "RTM_NEWACTION", - "RTM_NEWADDR", - "RTM_NEWADDRLABEL", - "RTM_NEWLINK", - "RTM_NEWMADDR", - "RTM_NEWMADDR2", - "RTM_NEWNDUSEROPT", - "RTM_NEWNEIGH", - "RTM_NEWNEIGHTBL", - "RTM_NEWPREFIX", - "RTM_NEWQDISC", - "RTM_NEWROUTE", - "RTM_NEWRULE", - "RTM_NEWTCLASS", - "RTM_NEWTFILTER", - "RTM_NR_FAMILIES", - "RTM_NR_MSGTYPES", - "RTM_OIFINFO", - "RTM_OLDADD", - "RTM_OLDDEL", - "RTM_OOIFINFO", - "RTM_REDIRECT", - "RTM_RESOLVE", - "RTM_RTTUNIT", - "RTM_SETDCB", - "RTM_SETGATE", - "RTM_SETLINK", - "RTM_SETNEIGHTBL", - "RTM_VERSION", - "RTNH_ALIGNTO", - "RTNH_F_DEAD", - "RTNH_F_ONLINK", - "RTNH_F_PERVASIVE", - "RTNLGRP_IPV4_IFADDR", - "RTNLGRP_IPV4_MROUTE", - "RTNLGRP_IPV4_ROUTE", - "RTNLGRP_IPV4_RULE", - "RTNLGRP_IPV6_IFADDR", - "RTNLGRP_IPV6_IFINFO", - "RTNLGRP_IPV6_MROUTE", - "RTNLGRP_IPV6_PREFIX", - "RTNLGRP_IPV6_ROUTE", - "RTNLGRP_IPV6_RULE", - "RTNLGRP_LINK", - "RTNLGRP_ND_USEROPT", - "RTNLGRP_NEIGH", - "RTNLGRP_NONE", - "RTNLGRP_NOTIFY", - "RTNLGRP_TC", - "RTN_ANYCAST", - "RTN_BLACKHOLE", - "RTN_BROADCAST", - "RTN_LOCAL", - "RTN_MAX", - "RTN_MULTICAST", - "RTN_NAT", - "RTN_PROHIBIT", - "RTN_THROW", - "RTN_UNICAST", - "RTN_UNREACHABLE", - "RTN_UNSPEC", - "RTN_XRESOLVE", - "RTPROT_BIRD", - "RTPROT_BOOT", - "RTPROT_DHCP", - "RTPROT_DNROUTED", - "RTPROT_GATED", - "RTPROT_KERNEL", - "RTPROT_MRT", - "RTPROT_NTK", - "RTPROT_RA", - "RTPROT_REDIRECT", - "RTPROT_STATIC", - "RTPROT_UNSPEC", - "RTPROT_XORP", - "RTPROT_ZEBRA", - "RTV_EXPIRE", - "RTV_HOPCOUNT", - "RTV_MTU", - "RTV_RPIPE", - "RTV_RTT", - "RTV_RTTVAR", - "RTV_SPIPE", - "RTV_SSTHRESH", - "RTV_WEIGHT", - "RT_CACHING_CONTEXT", - "RT_CLASS_DEFAULT", - "RT_CLASS_LOCAL", - "RT_CLASS_MAIN", - "RT_CLASS_MAX", - "RT_CLASS_UNSPEC", - "RT_DEFAULT_FIB", - "RT_NORTREF", - "RT_SCOPE_HOST", - "RT_SCOPE_LINK", - "RT_SCOPE_NOWHERE", - "RT_SCOPE_SITE", - "RT_SCOPE_UNIVERSE", - "RT_TABLEID_MAX", - "RT_TABLE_COMPAT", - "RT_TABLE_DEFAULT", - "RT_TABLE_LOCAL", - "RT_TABLE_MAIN", - "RT_TABLE_MAX", - "RT_TABLE_UNSPEC", - "RUSAGE_CHILDREN", - "RUSAGE_SELF", - "RUSAGE_THREAD", - "Radvisory_t", - "RawConn", - "RawSockaddr", - "RawSockaddrAny", - "RawSockaddrDatalink", - "RawSockaddrInet4", - "RawSockaddrInet6", - "RawSockaddrLinklayer", - "RawSockaddrNetlink", - "RawSockaddrUnix", - "RawSyscall", - "RawSyscall6", - "Read", - "ReadConsole", - "ReadDirectoryChanges", - "ReadDirent", - "ReadFile", - "Readlink", - "Reboot", - "Recvfrom", - "Recvmsg", - "RegCloseKey", - "RegEnumKeyEx", - "RegOpenKeyEx", - "RegQueryInfoKey", - "RegQueryValueEx", - "RemoveDirectory", - "Removexattr", - "Rename", - "Renameat", - "Revoke", - "Rlimit", - "Rmdir", - "RouteMessage", - "RouteRIB", - "RoutingMessage", - "RtAttr", - "RtGenmsg", - "RtMetrics", - "RtMsg", - "RtMsghdr", - "RtNexthop", - "Rusage", - "SCM_BINTIME", - "SCM_CREDENTIALS", - "SCM_CREDS", - "SCM_RIGHTS", - "SCM_TIMESTAMP", - "SCM_TIMESTAMPING", - "SCM_TIMESTAMPNS", - "SCM_TIMESTAMP_MONOTONIC", - "SHUT_RD", - "SHUT_RDWR", - "SHUT_WR", - "SID", - "SIDAndAttributes", - "SIGABRT", - "SIGALRM", - "SIGBUS", - "SIGCHLD", - "SIGCLD", - "SIGCONT", - "SIGEMT", - "SIGFPE", - "SIGHUP", - "SIGILL", - "SIGINFO", - "SIGINT", - "SIGIO", - "SIGIOT", - "SIGKILL", - "SIGLIBRT", - "SIGLWP", - "SIGPIPE", - "SIGPOLL", - "SIGPROF", - "SIGPWR", - "SIGQUIT", - "SIGSEGV", - "SIGSTKFLT", - "SIGSTOP", - "SIGSYS", - "SIGTERM", - "SIGTHR", - "SIGTRAP", - "SIGTSTP", - "SIGTTIN", - "SIGTTOU", - "SIGUNUSED", - "SIGURG", - "SIGUSR1", - "SIGUSR2", - "SIGVTALRM", - "SIGWINCH", - "SIGXCPU", - "SIGXFSZ", - "SIOCADDDLCI", - "SIOCADDMULTI", - "SIOCADDRT", - "SIOCAIFADDR", - "SIOCAIFGROUP", - "SIOCALIFADDR", - "SIOCARPIPLL", - "SIOCATMARK", - "SIOCAUTOADDR", - "SIOCAUTONETMASK", - "SIOCBRDGADD", - "SIOCBRDGADDS", - "SIOCBRDGARL", - "SIOCBRDGDADDR", - "SIOCBRDGDEL", - "SIOCBRDGDELS", - "SIOCBRDGFLUSH", - "SIOCBRDGFRL", - "SIOCBRDGGCACHE", - "SIOCBRDGGFD", - "SIOCBRDGGHT", - "SIOCBRDGGIFFLGS", - "SIOCBRDGGMA", - "SIOCBRDGGPARAM", - "SIOCBRDGGPRI", - "SIOCBRDGGRL", - "SIOCBRDGGSIFS", - "SIOCBRDGGTO", - "SIOCBRDGIFS", - "SIOCBRDGRTS", - "SIOCBRDGSADDR", - "SIOCBRDGSCACHE", - "SIOCBRDGSFD", - "SIOCBRDGSHT", - "SIOCBRDGSIFCOST", - "SIOCBRDGSIFFLGS", - "SIOCBRDGSIFPRIO", - "SIOCBRDGSMA", - "SIOCBRDGSPRI", - "SIOCBRDGSPROTO", - "SIOCBRDGSTO", - "SIOCBRDGSTXHC", - "SIOCDARP", - "SIOCDELDLCI", - "SIOCDELMULTI", - "SIOCDELRT", - "SIOCDEVPRIVATE", - "SIOCDIFADDR", - "SIOCDIFGROUP", - "SIOCDIFPHYADDR", - "SIOCDLIFADDR", - "SIOCDRARP", - "SIOCGARP", - "SIOCGDRVSPEC", - "SIOCGETKALIVE", - "SIOCGETLABEL", - "SIOCGETPFLOW", - "SIOCGETPFSYNC", - "SIOCGETSGCNT", - "SIOCGETVIFCNT", - "SIOCGETVLAN", - "SIOCGHIWAT", - "SIOCGIFADDR", - "SIOCGIFADDRPREF", - "SIOCGIFALIAS", - "SIOCGIFALTMTU", - "SIOCGIFASYNCMAP", - "SIOCGIFBOND", - "SIOCGIFBR", - "SIOCGIFBRDADDR", - "SIOCGIFCAP", - "SIOCGIFCONF", - "SIOCGIFCOUNT", - "SIOCGIFDATA", - "SIOCGIFDESCR", - "SIOCGIFDEVMTU", - "SIOCGIFDLT", - "SIOCGIFDSTADDR", - "SIOCGIFENCAP", - "SIOCGIFFIB", - "SIOCGIFFLAGS", - "SIOCGIFGATTR", - "SIOCGIFGENERIC", - "SIOCGIFGMEMB", - "SIOCGIFGROUP", - "SIOCGIFHARDMTU", - "SIOCGIFHWADDR", - "SIOCGIFINDEX", - "SIOCGIFKPI", - "SIOCGIFMAC", - "SIOCGIFMAP", - "SIOCGIFMEDIA", - "SIOCGIFMEM", - "SIOCGIFMETRIC", - "SIOCGIFMTU", - "SIOCGIFNAME", - "SIOCGIFNETMASK", - "SIOCGIFPDSTADDR", - "SIOCGIFPFLAGS", - "SIOCGIFPHYS", - "SIOCGIFPRIORITY", - "SIOCGIFPSRCADDR", - "SIOCGIFRDOMAIN", - "SIOCGIFRTLABEL", - "SIOCGIFSLAVE", - "SIOCGIFSTATUS", - "SIOCGIFTIMESLOT", - "SIOCGIFTXQLEN", - "SIOCGIFVLAN", - "SIOCGIFWAKEFLAGS", - "SIOCGIFXFLAGS", - "SIOCGLIFADDR", - "SIOCGLIFPHYADDR", - "SIOCGLIFPHYRTABLE", - "SIOCGLIFPHYTTL", - "SIOCGLINKSTR", - "SIOCGLOWAT", - "SIOCGPGRP", - "SIOCGPRIVATE_0", - "SIOCGPRIVATE_1", - "SIOCGRARP", - "SIOCGSPPPPARAMS", - "SIOCGSTAMP", - "SIOCGSTAMPNS", - "SIOCGVH", - "SIOCGVNETID", - "SIOCIFCREATE", - "SIOCIFCREATE2", - "SIOCIFDESTROY", - "SIOCIFGCLONERS", - "SIOCINITIFADDR", - "SIOCPROTOPRIVATE", - "SIOCRSLVMULTI", - "SIOCRTMSG", - "SIOCSARP", - "SIOCSDRVSPEC", - "SIOCSETKALIVE", - "SIOCSETLABEL", - "SIOCSETPFLOW", - "SIOCSETPFSYNC", - "SIOCSETVLAN", - "SIOCSHIWAT", - "SIOCSIFADDR", - "SIOCSIFADDRPREF", - "SIOCSIFALTMTU", - "SIOCSIFASYNCMAP", - "SIOCSIFBOND", - "SIOCSIFBR", - "SIOCSIFBRDADDR", - "SIOCSIFCAP", - "SIOCSIFDESCR", - "SIOCSIFDSTADDR", - "SIOCSIFENCAP", - "SIOCSIFFIB", - "SIOCSIFFLAGS", - "SIOCSIFGATTR", - "SIOCSIFGENERIC", - "SIOCSIFHWADDR", - "SIOCSIFHWBROADCAST", - "SIOCSIFKPI", - "SIOCSIFLINK", - "SIOCSIFLLADDR", - "SIOCSIFMAC", - "SIOCSIFMAP", - "SIOCSIFMEDIA", - "SIOCSIFMEM", - "SIOCSIFMETRIC", - "SIOCSIFMTU", - "SIOCSIFNAME", - "SIOCSIFNETMASK", - "SIOCSIFPFLAGS", - "SIOCSIFPHYADDR", - "SIOCSIFPHYS", - "SIOCSIFPRIORITY", - "SIOCSIFRDOMAIN", - "SIOCSIFRTLABEL", - "SIOCSIFRVNET", - "SIOCSIFSLAVE", - "SIOCSIFTIMESLOT", - "SIOCSIFTXQLEN", - "SIOCSIFVLAN", - "SIOCSIFVNET", - "SIOCSIFXFLAGS", - "SIOCSLIFPHYADDR", - "SIOCSLIFPHYRTABLE", - "SIOCSLIFPHYTTL", - "SIOCSLINKSTR", - "SIOCSLOWAT", - "SIOCSPGRP", - "SIOCSRARP", - "SIOCSSPPPPARAMS", - "SIOCSVH", - "SIOCSVNETID", - "SIOCZIFDATA", - "SIO_GET_EXTENSION_FUNCTION_POINTER", - "SIO_GET_INTERFACE_LIST", - "SIO_KEEPALIVE_VALS", - "SIO_UDP_CONNRESET", - "SOCK_CLOEXEC", - "SOCK_DCCP", - "SOCK_DGRAM", - "SOCK_FLAGS_MASK", - "SOCK_MAXADDRLEN", - "SOCK_NONBLOCK", - "SOCK_NOSIGPIPE", - "SOCK_PACKET", - "SOCK_RAW", - "SOCK_RDM", - "SOCK_SEQPACKET", - "SOCK_STREAM", - "SOL_AAL", - "SOL_ATM", - "SOL_DECNET", - "SOL_ICMPV6", - "SOL_IP", - "SOL_IPV6", - "SOL_IRDA", - "SOL_PACKET", - "SOL_RAW", - "SOL_SOCKET", - "SOL_TCP", - "SOL_X25", - "SOMAXCONN", - "SO_ACCEPTCONN", - "SO_ACCEPTFILTER", - "SO_ATTACH_FILTER", - "SO_BINDANY", - "SO_BINDTODEVICE", - "SO_BINTIME", - "SO_BROADCAST", - "SO_BSDCOMPAT", - "SO_DEBUG", - "SO_DETACH_FILTER", - "SO_DOMAIN", - "SO_DONTROUTE", - "SO_DONTTRUNC", - "SO_ERROR", - "SO_KEEPALIVE", - "SO_LABEL", - "SO_LINGER", - "SO_LINGER_SEC", - "SO_LISTENINCQLEN", - "SO_LISTENQLEN", - "SO_LISTENQLIMIT", - "SO_MARK", - "SO_NETPROC", - "SO_NKE", - "SO_NOADDRERR", - "SO_NOHEADER", - "SO_NOSIGPIPE", - "SO_NOTIFYCONFLICT", - "SO_NO_CHECK", - "SO_NO_DDP", - "SO_NO_OFFLOAD", - "SO_NP_EXTENSIONS", - "SO_NREAD", - "SO_NUMRCVPKT", - "SO_NWRITE", - "SO_OOBINLINE", - "SO_OVERFLOWED", - "SO_PASSCRED", - "SO_PASSSEC", - "SO_PEERCRED", - "SO_PEERLABEL", - "SO_PEERNAME", - "SO_PEERSEC", - "SO_PRIORITY", - "SO_PROTOCOL", - "SO_PROTOTYPE", - "SO_RANDOMPORT", - "SO_RCVBUF", - "SO_RCVBUFFORCE", - "SO_RCVLOWAT", - "SO_RCVTIMEO", - "SO_RESTRICTIONS", - "SO_RESTRICT_DENYIN", - "SO_RESTRICT_DENYOUT", - "SO_RESTRICT_DENYSET", - "SO_REUSEADDR", - "SO_REUSEPORT", - "SO_REUSESHAREUID", - "SO_RTABLE", - "SO_RXQ_OVFL", - "SO_SECURITY_AUTHENTICATION", - "SO_SECURITY_ENCRYPTION_NETWORK", - "SO_SECURITY_ENCRYPTION_TRANSPORT", - "SO_SETFIB", - "SO_SNDBUF", - "SO_SNDBUFFORCE", - "SO_SNDLOWAT", - "SO_SNDTIMEO", - "SO_SPLICE", - "SO_TIMESTAMP", - "SO_TIMESTAMPING", - "SO_TIMESTAMPNS", - "SO_TIMESTAMP_MONOTONIC", - "SO_TYPE", - "SO_UPCALLCLOSEWAIT", - "SO_UPDATE_ACCEPT_CONTEXT", - "SO_UPDATE_CONNECT_CONTEXT", - "SO_USELOOPBACK", - "SO_USER_COOKIE", - "SO_VENDOR", - "SO_WANTMORE", - "SO_WANTOOBFLAG", - "SSLExtraCertChainPolicyPara", - "STANDARD_RIGHTS_ALL", - "STANDARD_RIGHTS_EXECUTE", - "STANDARD_RIGHTS_READ", - "STANDARD_RIGHTS_REQUIRED", - "STANDARD_RIGHTS_WRITE", - "STARTF_USESHOWWINDOW", - "STARTF_USESTDHANDLES", - "STD_ERROR_HANDLE", - "STD_INPUT_HANDLE", - "STD_OUTPUT_HANDLE", - "SUBLANG_ENGLISH_US", - "SW_FORCEMINIMIZE", - "SW_HIDE", - "SW_MAXIMIZE", - "SW_MINIMIZE", - "SW_NORMAL", - "SW_RESTORE", - "SW_SHOW", - "SW_SHOWDEFAULT", - "SW_SHOWMAXIMIZED", - "SW_SHOWMINIMIZED", - "SW_SHOWMINNOACTIVE", - "SW_SHOWNA", - "SW_SHOWNOACTIVATE", - "SW_SHOWNORMAL", - "SYMBOLIC_LINK_FLAG_DIRECTORY", - "SYNCHRONIZE", - "SYSCTL_VERSION", - "SYSCTL_VERS_0", - "SYSCTL_VERS_1", - "SYSCTL_VERS_MASK", - "SYS_ABORT2", - "SYS_ACCEPT", - "SYS_ACCEPT4", - "SYS_ACCEPT_NOCANCEL", - "SYS_ACCESS", - "SYS_ACCESS_EXTENDED", - "SYS_ACCT", - "SYS_ADD_KEY", - "SYS_ADD_PROFIL", - "SYS_ADJFREQ", - "SYS_ADJTIME", - "SYS_ADJTIMEX", - "SYS_AFS_SYSCALL", - "SYS_AIO_CANCEL", - "SYS_AIO_ERROR", - "SYS_AIO_FSYNC", - "SYS_AIO_MLOCK", - "SYS_AIO_READ", - "SYS_AIO_RETURN", - "SYS_AIO_SUSPEND", - "SYS_AIO_SUSPEND_NOCANCEL", - "SYS_AIO_WAITCOMPLETE", - "SYS_AIO_WRITE", - "SYS_ALARM", - "SYS_ARCH_PRCTL", - "SYS_ARM_FADVISE64_64", - "SYS_ARM_SYNC_FILE_RANGE", - "SYS_ATGETMSG", - "SYS_ATPGETREQ", - "SYS_ATPGETRSP", - "SYS_ATPSNDREQ", - "SYS_ATPSNDRSP", - "SYS_ATPUTMSG", - "SYS_ATSOCKET", - "SYS_AUDIT", - "SYS_AUDITCTL", - "SYS_AUDITON", - "SYS_AUDIT_SESSION_JOIN", - "SYS_AUDIT_SESSION_PORT", - "SYS_AUDIT_SESSION_SELF", - "SYS_BDFLUSH", - "SYS_BIND", - "SYS_BINDAT", - "SYS_BREAK", - "SYS_BRK", - "SYS_BSDTHREAD_CREATE", - "SYS_BSDTHREAD_REGISTER", - "SYS_BSDTHREAD_TERMINATE", - "SYS_CAPGET", - "SYS_CAPSET", - "SYS_CAP_ENTER", - "SYS_CAP_FCNTLS_GET", - "SYS_CAP_FCNTLS_LIMIT", - "SYS_CAP_GETMODE", - "SYS_CAP_GETRIGHTS", - "SYS_CAP_IOCTLS_GET", - "SYS_CAP_IOCTLS_LIMIT", - "SYS_CAP_NEW", - "SYS_CAP_RIGHTS_GET", - "SYS_CAP_RIGHTS_LIMIT", - "SYS_CHDIR", - "SYS_CHFLAGS", - "SYS_CHFLAGSAT", - "SYS_CHMOD", - "SYS_CHMOD_EXTENDED", - "SYS_CHOWN", - "SYS_CHOWN32", - "SYS_CHROOT", - "SYS_CHUD", - "SYS_CLOCK_ADJTIME", - "SYS_CLOCK_GETCPUCLOCKID2", - "SYS_CLOCK_GETRES", - "SYS_CLOCK_GETTIME", - "SYS_CLOCK_NANOSLEEP", - "SYS_CLOCK_SETTIME", - "SYS_CLONE", - "SYS_CLOSE", - "SYS_CLOSEFROM", - "SYS_CLOSE_NOCANCEL", - "SYS_CONNECT", - "SYS_CONNECTAT", - "SYS_CONNECT_NOCANCEL", - "SYS_COPYFILE", - "SYS_CPUSET", - "SYS_CPUSET_GETAFFINITY", - "SYS_CPUSET_GETID", - "SYS_CPUSET_SETAFFINITY", - "SYS_CPUSET_SETID", - "SYS_CREAT", - "SYS_CREATE_MODULE", - "SYS_CSOPS", - "SYS_CSOPS_AUDITTOKEN", - "SYS_DELETE", - "SYS_DELETE_MODULE", - "SYS_DUP", - "SYS_DUP2", - "SYS_DUP3", - "SYS_EACCESS", - "SYS_EPOLL_CREATE", - "SYS_EPOLL_CREATE1", - "SYS_EPOLL_CTL", - "SYS_EPOLL_CTL_OLD", - "SYS_EPOLL_PWAIT", - "SYS_EPOLL_WAIT", - "SYS_EPOLL_WAIT_OLD", - "SYS_EVENTFD", - "SYS_EVENTFD2", - "SYS_EXCHANGEDATA", - "SYS_EXECVE", - "SYS_EXIT", - "SYS_EXIT_GROUP", - "SYS_EXTATTRCTL", - "SYS_EXTATTR_DELETE_FD", - "SYS_EXTATTR_DELETE_FILE", - "SYS_EXTATTR_DELETE_LINK", - "SYS_EXTATTR_GET_FD", - "SYS_EXTATTR_GET_FILE", - "SYS_EXTATTR_GET_LINK", - "SYS_EXTATTR_LIST_FD", - "SYS_EXTATTR_LIST_FILE", - "SYS_EXTATTR_LIST_LINK", - "SYS_EXTATTR_SET_FD", - "SYS_EXTATTR_SET_FILE", - "SYS_EXTATTR_SET_LINK", - "SYS_FACCESSAT", - "SYS_FADVISE64", - "SYS_FADVISE64_64", - "SYS_FALLOCATE", - "SYS_FANOTIFY_INIT", - "SYS_FANOTIFY_MARK", - "SYS_FCHDIR", - "SYS_FCHFLAGS", - "SYS_FCHMOD", - "SYS_FCHMODAT", - "SYS_FCHMOD_EXTENDED", - "SYS_FCHOWN", - "SYS_FCHOWN32", - "SYS_FCHOWNAT", - "SYS_FCHROOT", - "SYS_FCNTL", - "SYS_FCNTL64", - "SYS_FCNTL_NOCANCEL", - "SYS_FDATASYNC", - "SYS_FEXECVE", - "SYS_FFCLOCK_GETCOUNTER", - "SYS_FFCLOCK_GETESTIMATE", - "SYS_FFCLOCK_SETESTIMATE", - "SYS_FFSCTL", - "SYS_FGETATTRLIST", - "SYS_FGETXATTR", - "SYS_FHOPEN", - "SYS_FHSTAT", - "SYS_FHSTATFS", - "SYS_FILEPORT_MAKEFD", - "SYS_FILEPORT_MAKEPORT", - "SYS_FKTRACE", - "SYS_FLISTXATTR", - "SYS_FLOCK", - "SYS_FORK", - "SYS_FPATHCONF", - "SYS_FREEBSD6_FTRUNCATE", - "SYS_FREEBSD6_LSEEK", - "SYS_FREEBSD6_MMAP", - "SYS_FREEBSD6_PREAD", - "SYS_FREEBSD6_PWRITE", - "SYS_FREEBSD6_TRUNCATE", - "SYS_FREMOVEXATTR", - "SYS_FSCTL", - "SYS_FSETATTRLIST", - "SYS_FSETXATTR", - "SYS_FSGETPATH", - "SYS_FSTAT", - "SYS_FSTAT64", - "SYS_FSTAT64_EXTENDED", - "SYS_FSTATAT", - "SYS_FSTATAT64", - "SYS_FSTATFS", - "SYS_FSTATFS64", - "SYS_FSTATV", - "SYS_FSTATVFS1", - "SYS_FSTAT_EXTENDED", - "SYS_FSYNC", - "SYS_FSYNC_NOCANCEL", - "SYS_FSYNC_RANGE", - "SYS_FTIME", - "SYS_FTRUNCATE", - "SYS_FTRUNCATE64", - "SYS_FUTEX", - "SYS_FUTIMENS", - "SYS_FUTIMES", - "SYS_FUTIMESAT", - "SYS_GETATTRLIST", - "SYS_GETAUDIT", - "SYS_GETAUDIT_ADDR", - "SYS_GETAUID", - "SYS_GETCONTEXT", - "SYS_GETCPU", - "SYS_GETCWD", - "SYS_GETDENTS", - "SYS_GETDENTS64", - "SYS_GETDIRENTRIES", - "SYS_GETDIRENTRIES64", - "SYS_GETDIRENTRIESATTR", - "SYS_GETDTABLECOUNT", - "SYS_GETDTABLESIZE", - "SYS_GETEGID", - "SYS_GETEGID32", - "SYS_GETEUID", - "SYS_GETEUID32", - "SYS_GETFH", - "SYS_GETFSSTAT", - "SYS_GETFSSTAT64", - "SYS_GETGID", - "SYS_GETGID32", - "SYS_GETGROUPS", - "SYS_GETGROUPS32", - "SYS_GETHOSTUUID", - "SYS_GETITIMER", - "SYS_GETLCID", - "SYS_GETLOGIN", - "SYS_GETLOGINCLASS", - "SYS_GETPEERNAME", - "SYS_GETPGID", - "SYS_GETPGRP", - "SYS_GETPID", - "SYS_GETPMSG", - "SYS_GETPPID", - "SYS_GETPRIORITY", - "SYS_GETRESGID", - "SYS_GETRESGID32", - "SYS_GETRESUID", - "SYS_GETRESUID32", - "SYS_GETRLIMIT", - "SYS_GETRTABLE", - "SYS_GETRUSAGE", - "SYS_GETSGROUPS", - "SYS_GETSID", - "SYS_GETSOCKNAME", - "SYS_GETSOCKOPT", - "SYS_GETTHRID", - "SYS_GETTID", - "SYS_GETTIMEOFDAY", - "SYS_GETUID", - "SYS_GETUID32", - "SYS_GETVFSSTAT", - "SYS_GETWGROUPS", - "SYS_GETXATTR", - "SYS_GET_KERNEL_SYMS", - "SYS_GET_MEMPOLICY", - "SYS_GET_ROBUST_LIST", - "SYS_GET_THREAD_AREA", - "SYS_GSSD_SYSCALL", - "SYS_GTTY", - "SYS_IDENTITYSVC", - "SYS_IDLE", - "SYS_INITGROUPS", - "SYS_INIT_MODULE", - "SYS_INOTIFY_ADD_WATCH", - "SYS_INOTIFY_INIT", - "SYS_INOTIFY_INIT1", - "SYS_INOTIFY_RM_WATCH", - "SYS_IOCTL", - "SYS_IOPERM", - "SYS_IOPL", - "SYS_IOPOLICYSYS", - "SYS_IOPRIO_GET", - "SYS_IOPRIO_SET", - "SYS_IO_CANCEL", - "SYS_IO_DESTROY", - "SYS_IO_GETEVENTS", - "SYS_IO_SETUP", - "SYS_IO_SUBMIT", - "SYS_IPC", - "SYS_ISSETUGID", - "SYS_JAIL", - "SYS_JAIL_ATTACH", - "SYS_JAIL_GET", - "SYS_JAIL_REMOVE", - "SYS_JAIL_SET", - "SYS_KAS_INFO", - "SYS_KDEBUG_TRACE", - "SYS_KENV", - "SYS_KEVENT", - "SYS_KEVENT64", - "SYS_KEXEC_LOAD", - "SYS_KEYCTL", - "SYS_KILL", - "SYS_KLDFIND", - "SYS_KLDFIRSTMOD", - "SYS_KLDLOAD", - "SYS_KLDNEXT", - "SYS_KLDSTAT", - "SYS_KLDSYM", - "SYS_KLDUNLOAD", - "SYS_KLDUNLOADF", - "SYS_KMQ_NOTIFY", - "SYS_KMQ_OPEN", - "SYS_KMQ_SETATTR", - "SYS_KMQ_TIMEDRECEIVE", - "SYS_KMQ_TIMEDSEND", - "SYS_KMQ_UNLINK", - "SYS_KQUEUE", - "SYS_KQUEUE1", - "SYS_KSEM_CLOSE", - "SYS_KSEM_DESTROY", - "SYS_KSEM_GETVALUE", - "SYS_KSEM_INIT", - "SYS_KSEM_OPEN", - "SYS_KSEM_POST", - "SYS_KSEM_TIMEDWAIT", - "SYS_KSEM_TRYWAIT", - "SYS_KSEM_UNLINK", - "SYS_KSEM_WAIT", - "SYS_KTIMER_CREATE", - "SYS_KTIMER_DELETE", - "SYS_KTIMER_GETOVERRUN", - "SYS_KTIMER_GETTIME", - "SYS_KTIMER_SETTIME", - "SYS_KTRACE", - "SYS_LCHFLAGS", - "SYS_LCHMOD", - "SYS_LCHOWN", - "SYS_LCHOWN32", - "SYS_LEDGER", - "SYS_LGETFH", - "SYS_LGETXATTR", - "SYS_LINK", - "SYS_LINKAT", - "SYS_LIO_LISTIO", - "SYS_LISTEN", - "SYS_LISTXATTR", - "SYS_LLISTXATTR", - "SYS_LOCK", - "SYS_LOOKUP_DCOOKIE", - "SYS_LPATHCONF", - "SYS_LREMOVEXATTR", - "SYS_LSEEK", - "SYS_LSETXATTR", - "SYS_LSTAT", - "SYS_LSTAT64", - "SYS_LSTAT64_EXTENDED", - "SYS_LSTATV", - "SYS_LSTAT_EXTENDED", - "SYS_LUTIMES", - "SYS_MAC_SYSCALL", - "SYS_MADVISE", - "SYS_MADVISE1", - "SYS_MAXSYSCALL", - "SYS_MBIND", - "SYS_MIGRATE_PAGES", - "SYS_MINCORE", - "SYS_MINHERIT", - "SYS_MKCOMPLEX", - "SYS_MKDIR", - "SYS_MKDIRAT", - "SYS_MKDIR_EXTENDED", - "SYS_MKFIFO", - "SYS_MKFIFOAT", - "SYS_MKFIFO_EXTENDED", - "SYS_MKNOD", - "SYS_MKNODAT", - "SYS_MLOCK", - "SYS_MLOCKALL", - "SYS_MMAP", - "SYS_MMAP2", - "SYS_MODCTL", - "SYS_MODFIND", - "SYS_MODFNEXT", - "SYS_MODIFY_LDT", - "SYS_MODNEXT", - "SYS_MODSTAT", - "SYS_MODWATCH", - "SYS_MOUNT", - "SYS_MOVE_PAGES", - "SYS_MPROTECT", - "SYS_MPX", - "SYS_MQUERY", - "SYS_MQ_GETSETATTR", - "SYS_MQ_NOTIFY", - "SYS_MQ_OPEN", - "SYS_MQ_TIMEDRECEIVE", - "SYS_MQ_TIMEDSEND", - "SYS_MQ_UNLINK", - "SYS_MREMAP", - "SYS_MSGCTL", - "SYS_MSGGET", - "SYS_MSGRCV", - "SYS_MSGRCV_NOCANCEL", - "SYS_MSGSND", - "SYS_MSGSND_NOCANCEL", - "SYS_MSGSYS", - "SYS_MSYNC", - "SYS_MSYNC_NOCANCEL", - "SYS_MUNLOCK", - "SYS_MUNLOCKALL", - "SYS_MUNMAP", - "SYS_NAME_TO_HANDLE_AT", - "SYS_NANOSLEEP", - "SYS_NEWFSTATAT", - "SYS_NFSCLNT", - "SYS_NFSSERVCTL", - "SYS_NFSSVC", - "SYS_NFSTAT", - "SYS_NICE", - "SYS_NLM_SYSCALL", - "SYS_NLSTAT", - "SYS_NMOUNT", - "SYS_NSTAT", - "SYS_NTP_ADJTIME", - "SYS_NTP_GETTIME", - "SYS_NUMA_GETAFFINITY", - "SYS_NUMA_SETAFFINITY", - "SYS_OABI_SYSCALL_BASE", - "SYS_OBREAK", - "SYS_OLDFSTAT", - "SYS_OLDLSTAT", - "SYS_OLDOLDUNAME", - "SYS_OLDSTAT", - "SYS_OLDUNAME", - "SYS_OPEN", - "SYS_OPENAT", - "SYS_OPENBSD_POLL", - "SYS_OPEN_BY_HANDLE_AT", - "SYS_OPEN_DPROTECTED_NP", - "SYS_OPEN_EXTENDED", - "SYS_OPEN_NOCANCEL", - "SYS_OVADVISE", - "SYS_PACCEPT", - "SYS_PATHCONF", - "SYS_PAUSE", - "SYS_PCICONFIG_IOBASE", - "SYS_PCICONFIG_READ", - "SYS_PCICONFIG_WRITE", - "SYS_PDFORK", - "SYS_PDGETPID", - "SYS_PDKILL", - "SYS_PERF_EVENT_OPEN", - "SYS_PERSONALITY", - "SYS_PID_HIBERNATE", - "SYS_PID_RESUME", - "SYS_PID_SHUTDOWN_SOCKETS", - "SYS_PID_SUSPEND", - "SYS_PIPE", - "SYS_PIPE2", - "SYS_PIVOT_ROOT", - "SYS_PMC_CONTROL", - "SYS_PMC_GET_INFO", - "SYS_POLL", - "SYS_POLLTS", - "SYS_POLL_NOCANCEL", - "SYS_POSIX_FADVISE", - "SYS_POSIX_FALLOCATE", - "SYS_POSIX_OPENPT", - "SYS_POSIX_SPAWN", - "SYS_PPOLL", - "SYS_PRCTL", - "SYS_PREAD", - "SYS_PREAD64", - "SYS_PREADV", - "SYS_PREAD_NOCANCEL", - "SYS_PRLIMIT64", - "SYS_PROCCTL", - "SYS_PROCESS_POLICY", - "SYS_PROCESS_VM_READV", - "SYS_PROCESS_VM_WRITEV", - "SYS_PROC_INFO", - "SYS_PROF", - "SYS_PROFIL", - "SYS_PSELECT", - "SYS_PSELECT6", - "SYS_PSET_ASSIGN", - "SYS_PSET_CREATE", - "SYS_PSET_DESTROY", - "SYS_PSYNCH_CVBROAD", - "SYS_PSYNCH_CVCLRPREPOST", - "SYS_PSYNCH_CVSIGNAL", - "SYS_PSYNCH_CVWAIT", - "SYS_PSYNCH_MUTEXDROP", - "SYS_PSYNCH_MUTEXWAIT", - "SYS_PSYNCH_RW_DOWNGRADE", - "SYS_PSYNCH_RW_LONGRDLOCK", - "SYS_PSYNCH_RW_RDLOCK", - "SYS_PSYNCH_RW_UNLOCK", - "SYS_PSYNCH_RW_UNLOCK2", - "SYS_PSYNCH_RW_UPGRADE", - "SYS_PSYNCH_RW_WRLOCK", - "SYS_PSYNCH_RW_YIELDWRLOCK", - "SYS_PTRACE", - "SYS_PUTPMSG", - "SYS_PWRITE", - "SYS_PWRITE64", - "SYS_PWRITEV", - "SYS_PWRITE_NOCANCEL", - "SYS_QUERY_MODULE", - "SYS_QUOTACTL", - "SYS_RASCTL", - "SYS_RCTL_ADD_RULE", - "SYS_RCTL_GET_LIMITS", - "SYS_RCTL_GET_RACCT", - "SYS_RCTL_GET_RULES", - "SYS_RCTL_REMOVE_RULE", - "SYS_READ", - "SYS_READAHEAD", - "SYS_READDIR", - "SYS_READLINK", - "SYS_READLINKAT", - "SYS_READV", - "SYS_READV_NOCANCEL", - "SYS_READ_NOCANCEL", - "SYS_REBOOT", - "SYS_RECV", - "SYS_RECVFROM", - "SYS_RECVFROM_NOCANCEL", - "SYS_RECVMMSG", - "SYS_RECVMSG", - "SYS_RECVMSG_NOCANCEL", - "SYS_REMAP_FILE_PAGES", - "SYS_REMOVEXATTR", - "SYS_RENAME", - "SYS_RENAMEAT", - "SYS_REQUEST_KEY", - "SYS_RESTART_SYSCALL", - "SYS_REVOKE", - "SYS_RFORK", - "SYS_RMDIR", - "SYS_RTPRIO", - "SYS_RTPRIO_THREAD", - "SYS_RT_SIGACTION", - "SYS_RT_SIGPENDING", - "SYS_RT_SIGPROCMASK", - "SYS_RT_SIGQUEUEINFO", - "SYS_RT_SIGRETURN", - "SYS_RT_SIGSUSPEND", - "SYS_RT_SIGTIMEDWAIT", - "SYS_RT_TGSIGQUEUEINFO", - "SYS_SBRK", - "SYS_SCHED_GETAFFINITY", - "SYS_SCHED_GETPARAM", - "SYS_SCHED_GETSCHEDULER", - "SYS_SCHED_GET_PRIORITY_MAX", - "SYS_SCHED_GET_PRIORITY_MIN", - "SYS_SCHED_RR_GET_INTERVAL", - "SYS_SCHED_SETAFFINITY", - "SYS_SCHED_SETPARAM", - "SYS_SCHED_SETSCHEDULER", - "SYS_SCHED_YIELD", - "SYS_SCTP_GENERIC_RECVMSG", - "SYS_SCTP_GENERIC_SENDMSG", - "SYS_SCTP_GENERIC_SENDMSG_IOV", - "SYS_SCTP_PEELOFF", - "SYS_SEARCHFS", - "SYS_SECURITY", - "SYS_SELECT", - "SYS_SELECT_NOCANCEL", - "SYS_SEMCONFIG", - "SYS_SEMCTL", - "SYS_SEMGET", - "SYS_SEMOP", - "SYS_SEMSYS", - "SYS_SEMTIMEDOP", - "SYS_SEM_CLOSE", - "SYS_SEM_DESTROY", - "SYS_SEM_GETVALUE", - "SYS_SEM_INIT", - "SYS_SEM_OPEN", - "SYS_SEM_POST", - "SYS_SEM_TRYWAIT", - "SYS_SEM_UNLINK", - "SYS_SEM_WAIT", - "SYS_SEM_WAIT_NOCANCEL", - "SYS_SEND", - "SYS_SENDFILE", - "SYS_SENDFILE64", - "SYS_SENDMMSG", - "SYS_SENDMSG", - "SYS_SENDMSG_NOCANCEL", - "SYS_SENDTO", - "SYS_SENDTO_NOCANCEL", - "SYS_SETATTRLIST", - "SYS_SETAUDIT", - "SYS_SETAUDIT_ADDR", - "SYS_SETAUID", - "SYS_SETCONTEXT", - "SYS_SETDOMAINNAME", - "SYS_SETEGID", - "SYS_SETEUID", - "SYS_SETFIB", - "SYS_SETFSGID", - "SYS_SETFSGID32", - "SYS_SETFSUID", - "SYS_SETFSUID32", - "SYS_SETGID", - "SYS_SETGID32", - "SYS_SETGROUPS", - "SYS_SETGROUPS32", - "SYS_SETHOSTNAME", - "SYS_SETITIMER", - "SYS_SETLCID", - "SYS_SETLOGIN", - "SYS_SETLOGINCLASS", - "SYS_SETNS", - "SYS_SETPGID", - "SYS_SETPRIORITY", - "SYS_SETPRIVEXEC", - "SYS_SETREGID", - "SYS_SETREGID32", - "SYS_SETRESGID", - "SYS_SETRESGID32", - "SYS_SETRESUID", - "SYS_SETRESUID32", - "SYS_SETREUID", - "SYS_SETREUID32", - "SYS_SETRLIMIT", - "SYS_SETRTABLE", - "SYS_SETSGROUPS", - "SYS_SETSID", - "SYS_SETSOCKOPT", - "SYS_SETTID", - "SYS_SETTID_WITH_PID", - "SYS_SETTIMEOFDAY", - "SYS_SETUID", - "SYS_SETUID32", - "SYS_SETWGROUPS", - "SYS_SETXATTR", - "SYS_SET_MEMPOLICY", - "SYS_SET_ROBUST_LIST", - "SYS_SET_THREAD_AREA", - "SYS_SET_TID_ADDRESS", - "SYS_SGETMASK", - "SYS_SHARED_REGION_CHECK_NP", - "SYS_SHARED_REGION_MAP_AND_SLIDE_NP", - "SYS_SHMAT", - "SYS_SHMCTL", - "SYS_SHMDT", - "SYS_SHMGET", - "SYS_SHMSYS", - "SYS_SHM_OPEN", - "SYS_SHM_UNLINK", - "SYS_SHUTDOWN", - "SYS_SIGACTION", - "SYS_SIGALTSTACK", - "SYS_SIGNAL", - "SYS_SIGNALFD", - "SYS_SIGNALFD4", - "SYS_SIGPENDING", - "SYS_SIGPROCMASK", - "SYS_SIGQUEUE", - "SYS_SIGQUEUEINFO", - "SYS_SIGRETURN", - "SYS_SIGSUSPEND", - "SYS_SIGSUSPEND_NOCANCEL", - "SYS_SIGTIMEDWAIT", - "SYS_SIGWAIT", - "SYS_SIGWAITINFO", - "SYS_SOCKET", - "SYS_SOCKETCALL", - "SYS_SOCKETPAIR", - "SYS_SPLICE", - "SYS_SSETMASK", - "SYS_SSTK", - "SYS_STACK_SNAPSHOT", - "SYS_STAT", - "SYS_STAT64", - "SYS_STAT64_EXTENDED", - "SYS_STATFS", - "SYS_STATFS64", - "SYS_STATV", - "SYS_STATVFS1", - "SYS_STAT_EXTENDED", - "SYS_STIME", - "SYS_STTY", - "SYS_SWAPCONTEXT", - "SYS_SWAPCTL", - "SYS_SWAPOFF", - "SYS_SWAPON", - "SYS_SYMLINK", - "SYS_SYMLINKAT", - "SYS_SYNC", - "SYS_SYNCFS", - "SYS_SYNC_FILE_RANGE", - "SYS_SYSARCH", - "SYS_SYSCALL", - "SYS_SYSCALL_BASE", - "SYS_SYSFS", - "SYS_SYSINFO", - "SYS_SYSLOG", - "SYS_TEE", - "SYS_TGKILL", - "SYS_THREAD_SELFID", - "SYS_THR_CREATE", - "SYS_THR_EXIT", - "SYS_THR_KILL", - "SYS_THR_KILL2", - "SYS_THR_NEW", - "SYS_THR_SELF", - "SYS_THR_SET_NAME", - "SYS_THR_SUSPEND", - "SYS_THR_WAKE", - "SYS_TIME", - "SYS_TIMERFD_CREATE", - "SYS_TIMERFD_GETTIME", - "SYS_TIMERFD_SETTIME", - "SYS_TIMER_CREATE", - "SYS_TIMER_DELETE", - "SYS_TIMER_GETOVERRUN", - "SYS_TIMER_GETTIME", - "SYS_TIMER_SETTIME", - "SYS_TIMES", - "SYS_TKILL", - "SYS_TRUNCATE", - "SYS_TRUNCATE64", - "SYS_TUXCALL", - "SYS_UGETRLIMIT", - "SYS_ULIMIT", - "SYS_UMASK", - "SYS_UMASK_EXTENDED", - "SYS_UMOUNT", - "SYS_UMOUNT2", - "SYS_UNAME", - "SYS_UNDELETE", - "SYS_UNLINK", - "SYS_UNLINKAT", - "SYS_UNMOUNT", - "SYS_UNSHARE", - "SYS_USELIB", - "SYS_USTAT", - "SYS_UTIME", - "SYS_UTIMENSAT", - "SYS_UTIMES", - "SYS_UTRACE", - "SYS_UUIDGEN", - "SYS_VADVISE", - "SYS_VFORK", - "SYS_VHANGUP", - "SYS_VM86", - "SYS_VM86OLD", - "SYS_VMSPLICE", - "SYS_VM_PRESSURE_MONITOR", - "SYS_VSERVER", - "SYS_WAIT4", - "SYS_WAIT4_NOCANCEL", - "SYS_WAIT6", - "SYS_WAITEVENT", - "SYS_WAITID", - "SYS_WAITID_NOCANCEL", - "SYS_WAITPID", - "SYS_WATCHEVENT", - "SYS_WORKQ_KERNRETURN", - "SYS_WORKQ_OPEN", - "SYS_WRITE", - "SYS_WRITEV", - "SYS_WRITEV_NOCANCEL", - "SYS_WRITE_NOCANCEL", - "SYS_YIELD", - "SYS__LLSEEK", - "SYS__LWP_CONTINUE", - "SYS__LWP_CREATE", - "SYS__LWP_CTL", - "SYS__LWP_DETACH", - "SYS__LWP_EXIT", - "SYS__LWP_GETNAME", - "SYS__LWP_GETPRIVATE", - "SYS__LWP_KILL", - "SYS__LWP_PARK", - "SYS__LWP_SELF", - "SYS__LWP_SETNAME", - "SYS__LWP_SETPRIVATE", - "SYS__LWP_SUSPEND", - "SYS__LWP_UNPARK", - "SYS__LWP_UNPARK_ALL", - "SYS__LWP_WAIT", - "SYS__LWP_WAKEUP", - "SYS__NEWSELECT", - "SYS__PSET_BIND", - "SYS__SCHED_GETAFFINITY", - "SYS__SCHED_GETPARAM", - "SYS__SCHED_SETAFFINITY", - "SYS__SCHED_SETPARAM", - "SYS__SYSCTL", - "SYS__UMTX_LOCK", - "SYS__UMTX_OP", - "SYS__UMTX_UNLOCK", - "SYS___ACL_ACLCHECK_FD", - "SYS___ACL_ACLCHECK_FILE", - "SYS___ACL_ACLCHECK_LINK", - "SYS___ACL_DELETE_FD", - "SYS___ACL_DELETE_FILE", - "SYS___ACL_DELETE_LINK", - "SYS___ACL_GET_FD", - "SYS___ACL_GET_FILE", - "SYS___ACL_GET_LINK", - "SYS___ACL_SET_FD", - "SYS___ACL_SET_FILE", - "SYS___ACL_SET_LINK", - "SYS___CAP_RIGHTS_GET", - "SYS___CLONE", - "SYS___DISABLE_THREADSIGNAL", - "SYS___GETCWD", - "SYS___GETLOGIN", - "SYS___GET_TCB", - "SYS___MAC_EXECVE", - "SYS___MAC_GETFSSTAT", - "SYS___MAC_GET_FD", - "SYS___MAC_GET_FILE", - "SYS___MAC_GET_LCID", - "SYS___MAC_GET_LCTX", - "SYS___MAC_GET_LINK", - "SYS___MAC_GET_MOUNT", - "SYS___MAC_GET_PID", - "SYS___MAC_GET_PROC", - "SYS___MAC_MOUNT", - "SYS___MAC_SET_FD", - "SYS___MAC_SET_FILE", - "SYS___MAC_SET_LCTX", - "SYS___MAC_SET_LINK", - "SYS___MAC_SET_PROC", - "SYS___MAC_SYSCALL", - "SYS___OLD_SEMWAIT_SIGNAL", - "SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL", - "SYS___POSIX_CHOWN", - "SYS___POSIX_FCHOWN", - "SYS___POSIX_LCHOWN", - "SYS___POSIX_RENAME", - "SYS___PTHREAD_CANCELED", - "SYS___PTHREAD_CHDIR", - "SYS___PTHREAD_FCHDIR", - "SYS___PTHREAD_KILL", - "SYS___PTHREAD_MARKCANCEL", - "SYS___PTHREAD_SIGMASK", - "SYS___QUOTACTL", - "SYS___SEMCTL", - "SYS___SEMWAIT_SIGNAL", - "SYS___SEMWAIT_SIGNAL_NOCANCEL", - "SYS___SETLOGIN", - "SYS___SETUGID", - "SYS___SET_TCB", - "SYS___SIGACTION_SIGTRAMP", - "SYS___SIGTIMEDWAIT", - "SYS___SIGWAIT", - "SYS___SIGWAIT_NOCANCEL", - "SYS___SYSCTL", - "SYS___TFORK", - "SYS___THREXIT", - "SYS___THRSIGDIVERT", - "SYS___THRSLEEP", - "SYS___THRWAKEUP", - "S_ARCH1", - "S_ARCH2", - "S_BLKSIZE", - "S_IEXEC", - "S_IFBLK", - "S_IFCHR", - "S_IFDIR", - "S_IFIFO", - "S_IFLNK", - "S_IFMT", - "S_IFREG", - "S_IFSOCK", - "S_IFWHT", - "S_IREAD", - "S_IRGRP", - "S_IROTH", - "S_IRUSR", - "S_IRWXG", - "S_IRWXO", - "S_IRWXU", - "S_ISGID", - "S_ISTXT", - "S_ISUID", - "S_ISVTX", - "S_IWGRP", - "S_IWOTH", - "S_IWRITE", - "S_IWUSR", - "S_IXGRP", - "S_IXOTH", - "S_IXUSR", - "S_LOGIN_SET", - "SecurityAttributes", - "Seek", - "Select", - "Sendfile", - "Sendmsg", - "SendmsgN", - "Sendto", - "Servent", - "SetBpf", - "SetBpfBuflen", - "SetBpfDatalink", - "SetBpfHeadercmpl", - "SetBpfImmediate", - "SetBpfInterface", - "SetBpfPromisc", - "SetBpfTimeout", - "SetCurrentDirectory", - "SetEndOfFile", - "SetEnvironmentVariable", - "SetFileAttributes", - "SetFileCompletionNotificationModes", - "SetFilePointer", - "SetFileTime", - "SetHandleInformation", - "SetKevent", - "SetLsfPromisc", - "SetNonblock", - "Setdomainname", - "Setegid", - "Setenv", - "Seteuid", - "Setfsgid", - "Setfsuid", - "Setgid", - "Setgroups", - "Sethostname", - "Setlogin", - "Setpgid", - "Setpriority", - "Setprivexec", - "Setregid", - "Setresgid", - "Setresuid", - "Setreuid", - "Setrlimit", - "Setsid", - "Setsockopt", - "SetsockoptByte", - "SetsockoptICMPv6Filter", - "SetsockoptIPMreq", - "SetsockoptIPMreqn", - "SetsockoptIPv6Mreq", - "SetsockoptInet4Addr", - "SetsockoptInt", - "SetsockoptLinger", - "SetsockoptString", - "SetsockoptTimeval", - "Settimeofday", - "Setuid", - "Setxattr", - "Shutdown", - "SidTypeAlias", - "SidTypeComputer", - "SidTypeDeletedAccount", - "SidTypeDomain", - "SidTypeGroup", - "SidTypeInvalid", - "SidTypeLabel", - "SidTypeUnknown", - "SidTypeUser", - "SidTypeWellKnownGroup", - "Signal", - "SizeofBpfHdr", - "SizeofBpfInsn", - "SizeofBpfProgram", - "SizeofBpfStat", - "SizeofBpfVersion", - "SizeofBpfZbuf", - "SizeofBpfZbufHeader", - "SizeofCmsghdr", - "SizeofICMPv6Filter", - "SizeofIPMreq", - "SizeofIPMreqn", - "SizeofIPv6MTUInfo", - "SizeofIPv6Mreq", - "SizeofIfAddrmsg", - "SizeofIfAnnounceMsghdr", - "SizeofIfData", - "SizeofIfInfomsg", - "SizeofIfMsghdr", - "SizeofIfaMsghdr", - "SizeofIfmaMsghdr", - "SizeofIfmaMsghdr2", - "SizeofInet4Pktinfo", - "SizeofInet6Pktinfo", - "SizeofInotifyEvent", - "SizeofLinger", - "SizeofMsghdr", - "SizeofNlAttr", - "SizeofNlMsgerr", - "SizeofNlMsghdr", - "SizeofRtAttr", - "SizeofRtGenmsg", - "SizeofRtMetrics", - "SizeofRtMsg", - "SizeofRtMsghdr", - "SizeofRtNexthop", - "SizeofSockFilter", - "SizeofSockFprog", - "SizeofSockaddrAny", - "SizeofSockaddrDatalink", - "SizeofSockaddrInet4", - "SizeofSockaddrInet6", - "SizeofSockaddrLinklayer", - "SizeofSockaddrNetlink", - "SizeofSockaddrUnix", - "SizeofTCPInfo", - "SizeofUcred", - "SlicePtrFromStrings", - "SockFilter", - "SockFprog", - "Sockaddr", - "SockaddrDatalink", - "SockaddrGen", - "SockaddrInet4", - "SockaddrInet6", - "SockaddrLinklayer", - "SockaddrNetlink", - "SockaddrUnix", - "Socket", - "SocketControlMessage", - "SocketDisableIPv6", - "Socketpair", - "Splice", - "StartProcess", - "StartupInfo", - "Stat", - "Stat_t", - "Statfs", - "Statfs_t", - "Stderr", - "Stdin", - "Stdout", - "StringBytePtr", - "StringByteSlice", - "StringSlicePtr", - "StringToSid", - "StringToUTF16", - "StringToUTF16Ptr", - "Symlink", - "Sync", - "SyncFileRange", - "SysProcAttr", - "SysProcIDMap", - "Syscall", - "Syscall12", - "Syscall15", - "Syscall18", - "Syscall6", - "Syscall9", - "SyscallN", - "Sysctl", - "SysctlUint32", - "Sysctlnode", - "Sysinfo", - "Sysinfo_t", - "Systemtime", - "TCGETS", - "TCIFLUSH", - "TCIOFLUSH", - "TCOFLUSH", - "TCPInfo", - "TCPKeepalive", - "TCP_CA_NAME_MAX", - "TCP_CONGCTL", - "TCP_CONGESTION", - "TCP_CONNECTIONTIMEOUT", - "TCP_CORK", - "TCP_DEFER_ACCEPT", - "TCP_ENABLE_ECN", - "TCP_INFO", - "TCP_KEEPALIVE", - "TCP_KEEPCNT", - "TCP_KEEPIDLE", - "TCP_KEEPINIT", - "TCP_KEEPINTVL", - "TCP_LINGER2", - "TCP_MAXBURST", - "TCP_MAXHLEN", - "TCP_MAXOLEN", - "TCP_MAXSEG", - "TCP_MAXWIN", - "TCP_MAX_SACK", - "TCP_MAX_WINSHIFT", - "TCP_MD5SIG", - "TCP_MD5SIG_MAXKEYLEN", - "TCP_MINMSS", - "TCP_MINMSSOVERLOAD", - "TCP_MSS", - "TCP_NODELAY", - "TCP_NOOPT", - "TCP_NOPUSH", - "TCP_NOTSENT_LOWAT", - "TCP_NSTATES", - "TCP_QUICKACK", - "TCP_RXT_CONNDROPTIME", - "TCP_RXT_FINDROP", - "TCP_SACK_ENABLE", - "TCP_SENDMOREACKS", - "TCP_SYNCNT", - "TCP_VENDOR", - "TCP_WINDOW_CLAMP", - "TCSAFLUSH", - "TCSETS", - "TF_DISCONNECT", - "TF_REUSE_SOCKET", - "TF_USE_DEFAULT_WORKER", - "TF_USE_KERNEL_APC", - "TF_USE_SYSTEM_THREAD", - "TF_WRITE_BEHIND", - "TH32CS_INHERIT", - "TH32CS_SNAPALL", - "TH32CS_SNAPHEAPLIST", - "TH32CS_SNAPMODULE", - "TH32CS_SNAPMODULE32", - "TH32CS_SNAPPROCESS", - "TH32CS_SNAPTHREAD", - "TIME_ZONE_ID_DAYLIGHT", - "TIME_ZONE_ID_STANDARD", - "TIME_ZONE_ID_UNKNOWN", - "TIOCCBRK", - "TIOCCDTR", - "TIOCCONS", - "TIOCDCDTIMESTAMP", - "TIOCDRAIN", - "TIOCDSIMICROCODE", - "TIOCEXCL", - "TIOCEXT", - "TIOCFLAG_CDTRCTS", - "TIOCFLAG_CLOCAL", - "TIOCFLAG_CRTSCTS", - "TIOCFLAG_MDMBUF", - "TIOCFLAG_PPS", - "TIOCFLAG_SOFTCAR", - "TIOCFLUSH", - "TIOCGDEV", - "TIOCGDRAINWAIT", - "TIOCGETA", - "TIOCGETD", - "TIOCGFLAGS", - "TIOCGICOUNT", - "TIOCGLCKTRMIOS", - "TIOCGLINED", - "TIOCGPGRP", - "TIOCGPTN", - "TIOCGQSIZE", - "TIOCGRANTPT", - "TIOCGRS485", - "TIOCGSERIAL", - "TIOCGSID", - "TIOCGSIZE", - "TIOCGSOFTCAR", - "TIOCGTSTAMP", - "TIOCGWINSZ", - "TIOCINQ", - "TIOCIXOFF", - "TIOCIXON", - "TIOCLINUX", - "TIOCMBIC", - "TIOCMBIS", - "TIOCMGDTRWAIT", - "TIOCMGET", - "TIOCMIWAIT", - "TIOCMODG", - "TIOCMODS", - "TIOCMSDTRWAIT", - "TIOCMSET", - "TIOCM_CAR", - "TIOCM_CD", - "TIOCM_CTS", - "TIOCM_DCD", - "TIOCM_DSR", - "TIOCM_DTR", - "TIOCM_LE", - "TIOCM_RI", - "TIOCM_RNG", - "TIOCM_RTS", - "TIOCM_SR", - "TIOCM_ST", - "TIOCNOTTY", - "TIOCNXCL", - "TIOCOUTQ", - "TIOCPKT", - "TIOCPKT_DATA", - "TIOCPKT_DOSTOP", - "TIOCPKT_FLUSHREAD", - "TIOCPKT_FLUSHWRITE", - "TIOCPKT_IOCTL", - "TIOCPKT_NOSTOP", - "TIOCPKT_START", - "TIOCPKT_STOP", - "TIOCPTMASTER", - "TIOCPTMGET", - "TIOCPTSNAME", - "TIOCPTYGNAME", - "TIOCPTYGRANT", - "TIOCPTYUNLK", - "TIOCRCVFRAME", - "TIOCREMOTE", - "TIOCSBRK", - "TIOCSCONS", - "TIOCSCTTY", - "TIOCSDRAINWAIT", - "TIOCSDTR", - "TIOCSERCONFIG", - "TIOCSERGETLSR", - "TIOCSERGETMULTI", - "TIOCSERGSTRUCT", - "TIOCSERGWILD", - "TIOCSERSETMULTI", - "TIOCSERSWILD", - "TIOCSER_TEMT", - "TIOCSETA", - "TIOCSETAF", - "TIOCSETAW", - "TIOCSETD", - "TIOCSFLAGS", - "TIOCSIG", - "TIOCSLCKTRMIOS", - "TIOCSLINED", - "TIOCSPGRP", - "TIOCSPTLCK", - "TIOCSQSIZE", - "TIOCSRS485", - "TIOCSSERIAL", - "TIOCSSIZE", - "TIOCSSOFTCAR", - "TIOCSTART", - "TIOCSTAT", - "TIOCSTI", - "TIOCSTOP", - "TIOCSTSTAMP", - "TIOCSWINSZ", - "TIOCTIMESTAMP", - "TIOCUCNTL", - "TIOCVHANGUP", - "TIOCXMTFRAME", - "TOKEN_ADJUST_DEFAULT", - "TOKEN_ADJUST_GROUPS", - "TOKEN_ADJUST_PRIVILEGES", - "TOKEN_ADJUST_SESSIONID", - "TOKEN_ALL_ACCESS", - "TOKEN_ASSIGN_PRIMARY", - "TOKEN_DUPLICATE", - "TOKEN_EXECUTE", - "TOKEN_IMPERSONATE", - "TOKEN_QUERY", - "TOKEN_QUERY_SOURCE", - "TOKEN_READ", - "TOKEN_WRITE", - "TOSTOP", - "TRUNCATE_EXISTING", - "TUNATTACHFILTER", - "TUNDETACHFILTER", - "TUNGETFEATURES", - "TUNGETIFF", - "TUNGETSNDBUF", - "TUNGETVNETHDRSZ", - "TUNSETDEBUG", - "TUNSETGROUP", - "TUNSETIFF", - "TUNSETLINK", - "TUNSETNOCSUM", - "TUNSETOFFLOAD", - "TUNSETOWNER", - "TUNSETPERSIST", - "TUNSETSNDBUF", - "TUNSETTXFILTER", - "TUNSETVNETHDRSZ", - "Tee", - "TerminateProcess", - "Termios", - "Tgkill", - "Time", - "Time_t", - "Times", - "Timespec", - "TimespecToNsec", - "Timeval", - "Timeval32", - "TimevalToNsec", - "Timex", - "Timezoneinformation", - "Tms", - "Token", - "TokenAccessInformation", - "TokenAuditPolicy", - "TokenDefaultDacl", - "TokenElevation", - "TokenElevationType", - "TokenGroups", - "TokenGroupsAndPrivileges", - "TokenHasRestrictions", - "TokenImpersonationLevel", - "TokenIntegrityLevel", - "TokenLinkedToken", - "TokenLogonSid", - "TokenMandatoryPolicy", - "TokenOrigin", - "TokenOwner", - "TokenPrimaryGroup", - "TokenPrivileges", - "TokenRestrictedSids", - "TokenSandBoxInert", - "TokenSessionId", - "TokenSessionReference", - "TokenSource", - "TokenStatistics", - "TokenType", - "TokenUIAccess", - "TokenUser", - "TokenVirtualizationAllowed", - "TokenVirtualizationEnabled", - "Tokenprimarygroup", - "Tokenuser", - "TranslateAccountName", - "TranslateName", - "TransmitFile", - "TransmitFileBuffers", - "Truncate", - "UNIX_PATH_MAX", - "USAGE_MATCH_TYPE_AND", - "USAGE_MATCH_TYPE_OR", - "UTF16FromString", - "UTF16PtrFromString", - "UTF16ToString", - "Ucred", - "Umask", - "Uname", - "Undelete", - "UnixCredentials", - "UnixRights", - "Unlink", - "Unlinkat", - "UnmapViewOfFile", - "Unmount", - "Unsetenv", - "Unshare", - "UserInfo10", - "Ustat", - "Ustat_t", - "Utimbuf", - "Utime", - "Utimes", - "UtimesNano", - "Utsname", - "VDISCARD", - "VDSUSP", - "VEOF", - "VEOL", - "VEOL2", - "VERASE", - "VERASE2", - "VINTR", - "VKILL", - "VLNEXT", - "VMIN", - "VQUIT", - "VREPRINT", - "VSTART", - "VSTATUS", - "VSTOP", - "VSUSP", - "VSWTC", - "VT0", - "VT1", - "VTDLY", - "VTIME", - "VWERASE", - "VirtualLock", - "VirtualUnlock", - "WAIT_ABANDONED", - "WAIT_FAILED", - "WAIT_OBJECT_0", - "WAIT_TIMEOUT", - "WALL", - "WALLSIG", - "WALTSIG", - "WCLONE", - "WCONTINUED", - "WCOREFLAG", - "WEXITED", - "WLINUXCLONE", - "WNOHANG", - "WNOTHREAD", - "WNOWAIT", - "WNOZOMBIE", - "WOPTSCHECKED", - "WORDSIZE", - "WSABuf", - "WSACleanup", - "WSADESCRIPTION_LEN", - "WSAData", - "WSAEACCES", - "WSAECONNABORTED", - "WSAECONNRESET", - "WSAEnumProtocols", - "WSAID_CONNECTEX", - "WSAIoctl", - "WSAPROTOCOL_LEN", - "WSAProtocolChain", - "WSAProtocolInfo", - "WSARecv", - "WSARecvFrom", - "WSASYS_STATUS_LEN", - "WSASend", - "WSASendTo", - "WSASendto", - "WSAStartup", - "WSTOPPED", - "WTRAPPED", - "WUNTRACED", - "Wait4", - "WaitForSingleObject", - "WaitStatus", - "Win32FileAttributeData", - "Win32finddata", - "Write", - "WriteConsole", - "WriteFile", - "X509_ASN_ENCODING", - "XCASE", - "XP1_CONNECTIONLESS", - "XP1_CONNECT_DATA", - "XP1_DISCONNECT_DATA", - "XP1_EXPEDITED_DATA", - "XP1_GRACEFUL_CLOSE", - "XP1_GUARANTEED_DELIVERY", - "XP1_GUARANTEED_ORDER", - "XP1_IFS_HANDLES", - "XP1_MESSAGE_ORIENTED", - "XP1_MULTIPOINT_CONTROL_PLANE", - "XP1_MULTIPOINT_DATA_PLANE", - "XP1_PARTIAL_MESSAGE", - "XP1_PSEUDO_STREAM", - "XP1_QOS_SUPPORTED", - "XP1_SAN_SUPPORT_SDP", - "XP1_SUPPORT_BROADCAST", - "XP1_SUPPORT_MULTIPOINT", - "XP1_UNI_RECV", - "XP1_UNI_SEND", - }, - "syscall/js": { - "CopyBytesToGo", - "CopyBytesToJS", - "Error", - "Func", - "FuncOf", - "Global", - "Null", - "Type", - "TypeBoolean", - "TypeFunction", - "TypeNull", - "TypeNumber", - "TypeObject", - "TypeString", - "TypeSymbol", - "TypeUndefined", - "Undefined", - "Value", - "ValueError", - "ValueOf", - }, - "testing": { - "AllocsPerRun", - "B", - "Benchmark", - "BenchmarkResult", - "Cover", - "CoverBlock", - "CoverMode", - "Coverage", - "F", - "Init", - "InternalBenchmark", - "InternalExample", - "InternalFuzzTarget", - "InternalTest", - "M", - "Main", - "MainStart", - "PB", - "RegisterCover", - "RunBenchmarks", - "RunExamples", - "RunTests", - "Short", - "T", - "TB", - "Testing", - "Verbose", - }, - "testing/fstest": { - "MapFS", - "MapFile", - "TestFS", - }, - "testing/iotest": { - "DataErrReader", - "ErrReader", - "ErrTimeout", - "HalfReader", - "NewReadLogger", - "NewWriteLogger", - "OneByteReader", - "TestReader", - "TimeoutReader", - "TruncateWriter", - }, - "testing/quick": { - "Check", - "CheckEqual", - "CheckEqualError", - "CheckError", - "Config", - "Generator", - "SetupError", - "Value", - }, - "testing/slogtest": { - "TestHandler", - }, - "text/scanner": { - "Char", - "Comment", - "EOF", - "Float", - "GoTokens", - "GoWhitespace", - "Ident", - "Int", - "Position", - "RawString", - "ScanChars", - "ScanComments", - "ScanFloats", - "ScanIdents", - "ScanInts", - "ScanRawStrings", - "ScanStrings", - "Scanner", - "SkipComments", - "String", - "TokenString", - }, - "text/tabwriter": { - "AlignRight", - "Debug", - "DiscardEmptyColumns", - "Escape", - "FilterHTML", - "NewWriter", - "StripEscape", - "TabIndent", - "Writer", - }, - "text/template": { - "ExecError", - "FuncMap", - "HTMLEscape", - "HTMLEscapeString", - "HTMLEscaper", - "IsTrue", - "JSEscape", - "JSEscapeString", - "JSEscaper", - "Must", - "New", - "ParseFS", - "ParseFiles", - "ParseGlob", - "Template", - "URLQueryEscaper", - }, - "text/template/parse": { - "ActionNode", - "BoolNode", - "BranchNode", - "BreakNode", - "ChainNode", - "CommandNode", - "CommentNode", - "ContinueNode", - "DotNode", - "FieldNode", - "IdentifierNode", - "IfNode", - "IsEmptyTree", - "ListNode", - "Mode", - "New", - "NewIdentifier", - "NilNode", - "Node", - "NodeAction", - "NodeBool", - "NodeBreak", - "NodeChain", - "NodeCommand", - "NodeComment", - "NodeContinue", - "NodeDot", - "NodeField", - "NodeIdentifier", - "NodeIf", - "NodeList", - "NodeNil", - "NodeNumber", - "NodePipe", - "NodeRange", - "NodeString", - "NodeTemplate", - "NodeText", - "NodeType", - "NodeVariable", - "NodeWith", - "NumberNode", - "Parse", - "ParseComments", - "PipeNode", - "Pos", - "RangeNode", - "SkipFuncCheck", - "StringNode", - "TemplateNode", - "TextNode", - "Tree", - "VariableNode", - "WithNode", - }, - "time": { - "ANSIC", - "After", - "AfterFunc", - "April", - "August", - "Date", - "DateOnly", - "DateTime", - "December", - "Duration", - "February", - "FixedZone", - "Friday", - "Hour", - "January", - "July", - "June", - "Kitchen", - "Layout", - "LoadLocation", - "LoadLocationFromTZData", - "Local", - "Location", - "March", - "May", - "Microsecond", - "Millisecond", - "Minute", - "Monday", - "Month", - "Nanosecond", - "NewTicker", - "NewTimer", - "November", - "Now", - "October", - "Parse", - "ParseDuration", - "ParseError", - "ParseInLocation", - "RFC1123", - "RFC1123Z", - "RFC3339", - "RFC3339Nano", - "RFC822", - "RFC822Z", - "RFC850", - "RubyDate", - "Saturday", - "Second", - "September", - "Since", - "Sleep", - "Stamp", - "StampMicro", - "StampMilli", - "StampNano", - "Sunday", - "Thursday", - "Tick", - "Ticker", - "Time", - "TimeOnly", - "Timer", - "Tuesday", - "UTC", - "Unix", - "UnixDate", - "UnixMicro", - "UnixMilli", - "Until", - "Wednesday", - "Weekday", - }, - "unicode": { - "ASCII_Hex_Digit", - "Adlam", - "Ahom", - "Anatolian_Hieroglyphs", - "Arabic", - "Armenian", - "Avestan", - "AzeriCase", - "Balinese", - "Bamum", - "Bassa_Vah", - "Batak", - "Bengali", - "Bhaiksuki", - "Bidi_Control", - "Bopomofo", - "Brahmi", - "Braille", - "Buginese", - "Buhid", - "C", - "Canadian_Aboriginal", - "Carian", - "CaseRange", - "CaseRanges", - "Categories", - "Caucasian_Albanian", - "Cc", - "Cf", - "Chakma", - "Cham", - "Cherokee", - "Chorasmian", - "Co", - "Common", - "Coptic", - "Cs", - "Cuneiform", - "Cypriot", - "Cypro_Minoan", - "Cyrillic", - "Dash", - "Deprecated", - "Deseret", - "Devanagari", - "Diacritic", - "Digit", - "Dives_Akuru", - "Dogra", - "Duployan", - "Egyptian_Hieroglyphs", - "Elbasan", - "Elymaic", - "Ethiopic", - "Extender", - "FoldCategory", - "FoldScript", - "Georgian", - "Glagolitic", - "Gothic", - "Grantha", - "GraphicRanges", - "Greek", - "Gujarati", - "Gunjala_Gondi", - "Gurmukhi", - "Han", - "Hangul", - "Hanifi_Rohingya", - "Hanunoo", - "Hatran", - "Hebrew", - "Hex_Digit", - "Hiragana", - "Hyphen", - "IDS_Binary_Operator", - "IDS_Trinary_Operator", - "Ideographic", - "Imperial_Aramaic", - "In", - "Inherited", - "Inscriptional_Pahlavi", - "Inscriptional_Parthian", - "Is", - "IsControl", - "IsDigit", - "IsGraphic", - "IsLetter", - "IsLower", - "IsMark", - "IsNumber", - "IsOneOf", - "IsPrint", - "IsPunct", - "IsSpace", - "IsSymbol", - "IsTitle", - "IsUpper", - "Javanese", - "Join_Control", - "Kaithi", - "Kannada", - "Katakana", - "Kawi", - "Kayah_Li", - "Kharoshthi", - "Khitan_Small_Script", - "Khmer", - "Khojki", - "Khudawadi", - "L", - "Lao", - "Latin", - "Lepcha", - "Letter", - "Limbu", - "Linear_A", - "Linear_B", - "Lisu", - "Ll", - "Lm", - "Lo", - "Logical_Order_Exception", - "Lower", - "LowerCase", - "Lt", - "Lu", - "Lycian", - "Lydian", - "M", - "Mahajani", - "Makasar", - "Malayalam", - "Mandaic", - "Manichaean", - "Marchen", - "Mark", - "Masaram_Gondi", - "MaxASCII", - "MaxCase", - "MaxLatin1", - "MaxRune", - "Mc", - "Me", - "Medefaidrin", - "Meetei_Mayek", - "Mende_Kikakui", - "Meroitic_Cursive", - "Meroitic_Hieroglyphs", - "Miao", - "Mn", - "Modi", - "Mongolian", - "Mro", - "Multani", - "Myanmar", - "N", - "Nabataean", - "Nag_Mundari", - "Nandinagari", - "Nd", - "New_Tai_Lue", - "Newa", - "Nko", - "Nl", - "No", - "Noncharacter_Code_Point", - "Number", - "Nushu", - "Nyiakeng_Puachue_Hmong", - "Ogham", - "Ol_Chiki", - "Old_Hungarian", - "Old_Italic", - "Old_North_Arabian", - "Old_Permic", - "Old_Persian", - "Old_Sogdian", - "Old_South_Arabian", - "Old_Turkic", - "Old_Uyghur", - "Oriya", - "Osage", - "Osmanya", - "Other", - "Other_Alphabetic", - "Other_Default_Ignorable_Code_Point", - "Other_Grapheme_Extend", - "Other_ID_Continue", - "Other_ID_Start", - "Other_Lowercase", - "Other_Math", - "Other_Uppercase", - "P", - "Pahawh_Hmong", - "Palmyrene", - "Pattern_Syntax", - "Pattern_White_Space", - "Pau_Cin_Hau", - "Pc", - "Pd", - "Pe", - "Pf", - "Phags_Pa", - "Phoenician", - "Pi", - "Po", - "Prepended_Concatenation_Mark", - "PrintRanges", - "Properties", - "Ps", - "Psalter_Pahlavi", - "Punct", - "Quotation_Mark", - "Radical", - "Range16", - "Range32", - "RangeTable", - "Regional_Indicator", - "Rejang", - "ReplacementChar", - "Runic", - "S", - "STerm", - "Samaritan", - "Saurashtra", - "Sc", - "Scripts", - "Sentence_Terminal", - "Sharada", - "Shavian", - "Siddham", - "SignWriting", - "SimpleFold", - "Sinhala", - "Sk", - "Sm", - "So", - "Soft_Dotted", - "Sogdian", - "Sora_Sompeng", - "Soyombo", - "Space", - "SpecialCase", - "Sundanese", - "Syloti_Nagri", - "Symbol", - "Syriac", - "Tagalog", - "Tagbanwa", - "Tai_Le", - "Tai_Tham", - "Tai_Viet", - "Takri", - "Tamil", - "Tangsa", - "Tangut", - "Telugu", - "Terminal_Punctuation", - "Thaana", - "Thai", - "Tibetan", - "Tifinagh", - "Tirhuta", - "Title", - "TitleCase", - "To", - "ToLower", - "ToTitle", - "ToUpper", - "Toto", - "TurkishCase", - "Ugaritic", - "Unified_Ideograph", - "Upper", - "UpperCase", - "UpperLower", - "Vai", - "Variation_Selector", - "Version", - "Vithkuqi", - "Wancho", - "Warang_Citi", - "White_Space", - "Yezidi", - "Yi", - "Z", - "Zanabazar_Square", - "Zl", - "Zp", - "Zs", - }, - "unicode/utf16": { - "AppendRune", - "Decode", - "DecodeRune", - "Encode", - "EncodeRune", - "IsSurrogate", - }, - "unicode/utf8": { - "AppendRune", - "DecodeLastRune", - "DecodeLastRuneInString", - "DecodeRune", - "DecodeRuneInString", - "EncodeRune", - "FullRune", - "FullRuneInString", - "MaxRune", - "RuneCount", - "RuneCountInString", - "RuneError", - "RuneLen", - "RuneSelf", - "RuneStart", - "UTFMax", - "Valid", - "ValidRune", - "ValidString", - }, - "unsafe": { - "Add", - "Alignof", - "Offsetof", - "Pointer", - "Sizeof", - "Slice", - "SliceData", - "String", - "StringData", - }, -} diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go deleted file mode 100644 index 44719de1..00000000 --- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package packagesinternal exposes internal-only fields from go/packages. -package packagesinternal - -var GetForTest = func(p interface{}) string { return "" } -var GetDepsErrors = func(p interface{}) []*PackageError { return nil } - -type PackageError struct { - ImportStack []string // shortest path from package named on command line to this one - Pos string // position of error (if present, file:line:col) - Err string // the error itself -} - -var TypecheckCgo int -var DepsErrors int // must be set as a LoadMode to call GetDepsErrors -var ForTest int // must be set as a LoadMode to call GetForTest - -var SetModFlag = func(config interface{}, value string) {} -var SetModFile = func(config interface{}, value string) {} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/internal/pkgbits/codes.go deleted file mode 100644 index f0cabde9..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/codes.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -// A Code is an enum value that can be encoded into bitstreams. -// -// Code types are preferable for enum types, because they allow -// Decoder to detect desyncs. -type Code interface { - // Marker returns the SyncMarker for the Code's dynamic type. - Marker() SyncMarker - - // Value returns the Code's ordinal value. - Value() int -} - -// A CodeVal distinguishes among go/constant.Value encodings. -type CodeVal int - -func (c CodeVal) Marker() SyncMarker { return SyncVal } -func (c CodeVal) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - ValBool CodeVal = iota - ValString - ValInt64 - ValBigInt - ValBigRat - ValBigFloat -) - -// A CodeType distinguishes among go/types.Type encodings. -type CodeType int - -func (c CodeType) Marker() SyncMarker { return SyncType } -func (c CodeType) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - TypeBasic CodeType = iota - TypeNamed - TypePointer - TypeSlice - TypeArray - TypeChan - TypeMap - TypeSignature - TypeStruct - TypeInterface - TypeUnion - TypeTypeParam -) - -// A CodeObj distinguishes among go/types.Object encodings. -type CodeObj int - -func (c CodeObj) Marker() SyncMarker { return SyncCodeObj } -func (c CodeObj) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - ObjAlias CodeObj = iota - ObjConst - ObjType - ObjFunc - ObjVar - ObjStub -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go deleted file mode 100644 index b92e8e6e..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go +++ /dev/null @@ -1,517 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -import ( - "encoding/binary" - "errors" - "fmt" - "go/constant" - "go/token" - "io" - "math/big" - "os" - "runtime" - "strings" -) - -// A PkgDecoder provides methods for decoding a package's Unified IR -// export data. -type PkgDecoder struct { - // version is the file format version. - version uint32 - - // sync indicates whether the file uses sync markers. - sync bool - - // pkgPath is the package path for the package to be decoded. - // - // TODO(mdempsky): Remove; unneeded since CL 391014. - pkgPath string - - // elemData is the full data payload of the encoded package. - // Elements are densely and contiguously packed together. - // - // The last 8 bytes of elemData are the package fingerprint. - elemData string - - // elemEnds stores the byte-offset end positions of element - // bitstreams within elemData. - // - // For example, element I's bitstream data starts at elemEnds[I-1] - // (or 0, if I==0) and ends at elemEnds[I]. - // - // Note: elemEnds is indexed by absolute indices, not - // section-relative indices. - elemEnds []uint32 - - // elemEndsEnds stores the index-offset end positions of relocation - // sections within elemEnds. - // - // For example, section K's end positions start at elemEndsEnds[K-1] - // (or 0, if K==0) and end at elemEndsEnds[K]. - elemEndsEnds [numRelocs]uint32 - - scratchRelocEnt []RelocEnt -} - -// PkgPath returns the package path for the package -// -// TODO(mdempsky): Remove; unneeded since CL 391014. -func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath } - -// SyncMarkers reports whether pr uses sync markers. -func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync } - -// NewPkgDecoder returns a PkgDecoder initialized to read the Unified -// IR export data from input. pkgPath is the package path for the -// compilation unit that produced the export data. -// -// TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014. -func NewPkgDecoder(pkgPath, input string) PkgDecoder { - pr := PkgDecoder{ - pkgPath: pkgPath, - } - - // TODO(mdempsky): Implement direct indexing of input string to - // avoid copying the position information. - - r := strings.NewReader(input) - - assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil) - - switch pr.version { - default: - panic(fmt.Errorf("unsupported version: %v", pr.version)) - case 0: - // no flags - case 1: - var flags uint32 - assert(binary.Read(r, binary.LittleEndian, &flags) == nil) - pr.sync = flags&flagSyncMarkers != 0 - } - - assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil) - - pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1]) - assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil) - - pos, err := r.Seek(0, io.SeekCurrent) - assert(err == nil) - - pr.elemData = input[pos:] - assert(len(pr.elemData)-8 == int(pr.elemEnds[len(pr.elemEnds)-1])) - - return pr -} - -// NumElems returns the number of elements in section k. -func (pr *PkgDecoder) NumElems(k RelocKind) int { - count := int(pr.elemEndsEnds[k]) - if k > 0 { - count -= int(pr.elemEndsEnds[k-1]) - } - return count -} - -// TotalElems returns the total number of elements across all sections. -func (pr *PkgDecoder) TotalElems() int { - return len(pr.elemEnds) -} - -// Fingerprint returns the package fingerprint. -func (pr *PkgDecoder) Fingerprint() [8]byte { - var fp [8]byte - copy(fp[:], pr.elemData[len(pr.elemData)-8:]) - return fp -} - -// AbsIdx returns the absolute index for the given (section, index) -// pair. -func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int { - absIdx := int(idx) - if k > 0 { - absIdx += int(pr.elemEndsEnds[k-1]) - } - if absIdx >= int(pr.elemEndsEnds[k]) { - errorf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) - } - return absIdx -} - -// DataIdx returns the raw element bitstream for the given (section, -// index) pair. -func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string { - absIdx := pr.AbsIdx(k, idx) - - var start uint32 - if absIdx > 0 { - start = pr.elemEnds[absIdx-1] - } - end := pr.elemEnds[absIdx] - - return pr.elemData[start:end] -} - -// StringIdx returns the string value for the given string index. -func (pr *PkgDecoder) StringIdx(idx Index) string { - return pr.DataIdx(RelocString, idx) -} - -// NewDecoder returns a Decoder for the given (section, index) pair, -// and decodes the given SyncMarker from the element bitstream. -func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { - r := pr.NewDecoderRaw(k, idx) - r.Sync(marker) - return r -} - -// TempDecoder returns a Decoder for the given (section, index) pair, -// and decodes the given SyncMarker from the element bitstream. -// If possible the Decoder should be RetireDecoder'd when it is no longer -// needed, this will avoid heap allocations. -func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { - r := pr.TempDecoderRaw(k, idx) - r.Sync(marker) - return r -} - -func (pr *PkgDecoder) RetireDecoder(d *Decoder) { - pr.scratchRelocEnt = d.Relocs - d.Relocs = nil -} - -// NewDecoderRaw returns a Decoder for the given (section, index) pair. -// -// Most callers should use NewDecoder instead. -func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder { - r := Decoder{ - common: pr, - k: k, - Idx: idx, - } - - // TODO(mdempsky) r.data.Reset(...) after #44505 is resolved. - r.Data = *strings.NewReader(pr.DataIdx(k, idx)) - - r.Sync(SyncRelocs) - r.Relocs = make([]RelocEnt, r.Len()) - for i := range r.Relocs { - r.Sync(SyncReloc) - r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} - } - - return r -} - -func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder { - r := Decoder{ - common: pr, - k: k, - Idx: idx, - } - - r.Data.Reset(pr.DataIdx(k, idx)) - r.Sync(SyncRelocs) - l := r.Len() - if cap(pr.scratchRelocEnt) >= l { - r.Relocs = pr.scratchRelocEnt[:l] - pr.scratchRelocEnt = nil - } else { - r.Relocs = make([]RelocEnt, l) - } - for i := range r.Relocs { - r.Sync(SyncReloc) - r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} - } - - return r -} - -// A Decoder provides methods for decoding an individual element's -// bitstream data. -type Decoder struct { - common *PkgDecoder - - Relocs []RelocEnt - Data strings.Reader - - k RelocKind - Idx Index -} - -func (r *Decoder) checkErr(err error) { - if err != nil { - errorf("unexpected decoding error: %w", err) - } -} - -func (r *Decoder) rawUvarint() uint64 { - x, err := readUvarint(&r.Data) - r.checkErr(err) - return x -} - -// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint. -// This avoids the interface conversion and thus has better escape properties, -// which flows up the stack. -func readUvarint(r *strings.Reader) (uint64, error) { - var x uint64 - var s uint - for i := 0; i < binary.MaxVarintLen64; i++ { - b, err := r.ReadByte() - if err != nil { - if i > 0 && err == io.EOF { - err = io.ErrUnexpectedEOF - } - return x, err - } - if b < 0x80 { - if i == binary.MaxVarintLen64-1 && b > 1 { - return x, overflow - } - return x | uint64(b)<> 1) - if ux&1 != 0 { - x = ^x - } - return x -} - -func (r *Decoder) rawReloc(k RelocKind, idx int) Index { - e := r.Relocs[idx] - assert(e.Kind == k) - return e.Idx -} - -// Sync decodes a sync marker from the element bitstream and asserts -// that it matches the expected marker. -// -// If r.common.sync is false, then Sync is a no-op. -func (r *Decoder) Sync(mWant SyncMarker) { - if !r.common.sync { - return - } - - pos, _ := r.Data.Seek(0, io.SeekCurrent) - mHave := SyncMarker(r.rawUvarint()) - writerPCs := make([]int, r.rawUvarint()) - for i := range writerPCs { - writerPCs[i] = int(r.rawUvarint()) - } - - if mHave == mWant { - return - } - - // There's some tension here between printing: - // - // (1) full file paths that tools can recognize (e.g., so emacs - // hyperlinks the "file:line" text for easy navigation), or - // - // (2) short file paths that are easier for humans to read (e.g., by - // omitting redundant or irrelevant details, so it's easier to - // focus on the useful bits that remain). - // - // The current formatting favors the former, as it seems more - // helpful in practice. But perhaps the formatting could be improved - // to better address both concerns. For example, use relative file - // paths if they would be shorter, or rewrite file paths to contain - // "$GOROOT" (like objabi.AbsFile does) if tools can be taught how - // to reliably expand that again. - - fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos) - - fmt.Printf("\nfound %v, written at:\n", mHave) - if len(writerPCs) == 0 { - fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath) - } - for _, pc := range writerPCs { - fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc))) - } - - fmt.Printf("\nexpected %v, reading at:\n", mWant) - var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size? - n := runtime.Callers(2, readerPCs[:]) - for _, pc := range fmtFrames(readerPCs[:n]...) { - fmt.Printf("\t%s\n", pc) - } - - // We already printed a stack trace for the reader, so now we can - // simply exit. Printing a second one with panic or base.Fatalf - // would just be noise. - os.Exit(1) -} - -// Bool decodes and returns a bool value from the element bitstream. -func (r *Decoder) Bool() bool { - r.Sync(SyncBool) - x, err := r.Data.ReadByte() - r.checkErr(err) - assert(x < 2) - return x != 0 -} - -// Int64 decodes and returns an int64 value from the element bitstream. -func (r *Decoder) Int64() int64 { - r.Sync(SyncInt64) - return r.rawVarint() -} - -// Uint64 decodes and returns a uint64 value from the element bitstream. -func (r *Decoder) Uint64() uint64 { - r.Sync(SyncUint64) - return r.rawUvarint() -} - -// Len decodes and returns a non-negative int value from the element bitstream. -func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v } - -// Int decodes and returns an int value from the element bitstream. -func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v } - -// Uint decodes and returns a uint value from the element bitstream. -func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v } - -// Code decodes a Code value from the element bitstream and returns -// its ordinal value. It's the caller's responsibility to convert the -// result to an appropriate Code type. -// -// TODO(mdempsky): Ideally this method would have signature "Code[T -// Code] T" instead, but we don't allow generic methods and the -// compiler can't depend on generics yet anyway. -func (r *Decoder) Code(mark SyncMarker) int { - r.Sync(mark) - return r.Len() -} - -// Reloc decodes a relocation of expected section k from the element -// bitstream and returns an index to the referenced element. -func (r *Decoder) Reloc(k RelocKind) Index { - r.Sync(SyncUseReloc) - return r.rawReloc(k, r.Len()) -} - -// String decodes and returns a string value from the element -// bitstream. -func (r *Decoder) String() string { - r.Sync(SyncString) - return r.common.StringIdx(r.Reloc(RelocString)) -} - -// Strings decodes and returns a variable-length slice of strings from -// the element bitstream. -func (r *Decoder) Strings() []string { - res := make([]string, r.Len()) - for i := range res { - res[i] = r.String() - } - return res -} - -// Value decodes and returns a constant.Value from the element -// bitstream. -func (r *Decoder) Value() constant.Value { - r.Sync(SyncValue) - isComplex := r.Bool() - val := r.scalar() - if isComplex { - val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar())) - } - return val -} - -func (r *Decoder) scalar() constant.Value { - switch tag := CodeVal(r.Code(SyncVal)); tag { - default: - panic(fmt.Errorf("unexpected scalar tag: %v", tag)) - - case ValBool: - return constant.MakeBool(r.Bool()) - case ValString: - return constant.MakeString(r.String()) - case ValInt64: - return constant.MakeInt64(r.Int64()) - case ValBigInt: - return constant.Make(r.bigInt()) - case ValBigRat: - num := r.bigInt() - denom := r.bigInt() - return constant.Make(new(big.Rat).SetFrac(num, denom)) - case ValBigFloat: - return constant.Make(r.bigFloat()) - } -} - -func (r *Decoder) bigInt() *big.Int { - v := new(big.Int).SetBytes([]byte(r.String())) - if r.Bool() { - v.Neg(v) - } - return v -} - -func (r *Decoder) bigFloat() *big.Float { - v := new(big.Float).SetPrec(512) - assert(v.UnmarshalText([]byte(r.String())) == nil) - return v -} - -// @@@ Helpers - -// TODO(mdempsky): These should probably be removed. I think they're a -// smell that the export data format is not yet quite right. - -// PeekPkgPath returns the package path for the specified package -// index. -func (pr *PkgDecoder) PeekPkgPath(idx Index) string { - var path string - { - r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef) - path = r.String() - pr.RetireDecoder(&r) - } - if path == "" { - path = pr.pkgPath - } - return path -} - -// PeekObj returns the package path, object name, and CodeObj for the -// specified object index. -func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) { - var ridx Index - var name string - var rcode int - { - r := pr.TempDecoder(RelocName, idx, SyncObject1) - r.Sync(SyncSym) - r.Sync(SyncPkg) - ridx = r.Reloc(RelocPkg) - name = r.String() - rcode = r.Code(SyncCodeObj) - pr.RetireDecoder(&r) - } - - path := pr.PeekPkgPath(ridx) - assert(name != "") - - tag := CodeObj(rcode) - - return path, name, tag -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/internal/pkgbits/doc.go deleted file mode 100644 index c8a2796b..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package pkgbits implements low-level coding abstractions for -// Unified IR's export data format. -// -// At a low-level, a package is a collection of bitstream elements. -// Each element has a "kind" and a dense, non-negative index. -// Elements can be randomly accessed given their kind and index. -// -// Individual elements are sequences of variable-length values (e.g., -// integers, booleans, strings, go/constant values, cross-references -// to other elements). Package pkgbits provides APIs for encoding and -// decoding these low-level values, but the details of mapping -// higher-level Go constructs into elements is left to higher-level -// abstractions. -// -// Elements may cross-reference each other with "relocations." For -// example, an element representing a pointer type has a relocation -// referring to the element type. -// -// Go constructs may be composed as a constellation of multiple -// elements. For example, a declared function may have one element to -// describe the object (e.g., its name, type, position), and a -// separate element to describe its function body. This allows readers -// some flexibility in efficiently seeking or re-reading data (e.g., -// inlining requires re-reading the function body for each inlined -// call, without needing to re-read the object-level details). -// -// This is a copy of internal/pkgbits in the Go implementation. -package pkgbits diff --git a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go deleted file mode 100644 index 6482617a..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -import ( - "bytes" - "crypto/md5" - "encoding/binary" - "go/constant" - "io" - "math/big" - "runtime" -) - -// currentVersion is the current version number. -// -// - v0: initial prototype -// -// - v1: adds the flags uint32 word -const currentVersion uint32 = 1 - -// A PkgEncoder provides methods for encoding a package's Unified IR -// export data. -type PkgEncoder struct { - // elems holds the bitstream for previously encoded elements. - elems [numRelocs][]string - - // stringsIdx maps previously encoded strings to their index within - // the RelocString section, to allow deduplication. That is, - // elems[RelocString][stringsIdx[s]] == s (if present). - stringsIdx map[string]Index - - // syncFrames is the number of frames to write at each sync - // marker. A negative value means sync markers are omitted. - syncFrames int -} - -// SyncMarkers reports whether pw uses sync markers. -func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 } - -// NewPkgEncoder returns an initialized PkgEncoder. -// -// syncFrames is the number of caller frames that should be serialized -// at Sync points. Serializing additional frames results in larger -// export data files, but can help diagnosing desync errors in -// higher-level Unified IR reader/writer code. If syncFrames is -// negative, then sync markers are omitted entirely. -func NewPkgEncoder(syncFrames int) PkgEncoder { - return PkgEncoder{ - stringsIdx: make(map[string]Index), - syncFrames: syncFrames, - } -} - -// DumpTo writes the package's encoded data to out0 and returns the -// package fingerprint. -func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { - h := md5.New() - out := io.MultiWriter(out0, h) - - writeUint32 := func(x uint32) { - assert(binary.Write(out, binary.LittleEndian, x) == nil) - } - - writeUint32(currentVersion) - - var flags uint32 - if pw.SyncMarkers() { - flags |= flagSyncMarkers - } - writeUint32(flags) - - // Write elemEndsEnds. - var sum uint32 - for _, elems := range &pw.elems { - sum += uint32(len(elems)) - writeUint32(sum) - } - - // Write elemEnds. - sum = 0 - for _, elems := range &pw.elems { - for _, elem := range elems { - sum += uint32(len(elem)) - writeUint32(sum) - } - } - - // Write elemData. - for _, elems := range &pw.elems { - for _, elem := range elems { - _, err := io.WriteString(out, elem) - assert(err == nil) - } - } - - // Write fingerprint. - copy(fingerprint[:], h.Sum(nil)) - _, err := out0.Write(fingerprint[:]) - assert(err == nil) - - return -} - -// StringIdx adds a string value to the strings section, if not -// already present, and returns its index. -func (pw *PkgEncoder) StringIdx(s string) Index { - if idx, ok := pw.stringsIdx[s]; ok { - assert(pw.elems[RelocString][idx] == s) - return idx - } - - idx := Index(len(pw.elems[RelocString])) - pw.elems[RelocString] = append(pw.elems[RelocString], s) - pw.stringsIdx[s] = idx - return idx -} - -// NewEncoder returns an Encoder for a new element within the given -// section, and encodes the given SyncMarker as the start of the -// element bitstream. -func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder { - e := pw.NewEncoderRaw(k) - e.Sync(marker) - return e -} - -// NewEncoderRaw returns an Encoder for a new element within the given -// section. -// -// Most callers should use NewEncoder instead. -func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder { - idx := Index(len(pw.elems[k])) - pw.elems[k] = append(pw.elems[k], "") // placeholder - - return Encoder{ - p: pw, - k: k, - Idx: idx, - } -} - -// An Encoder provides methods for encoding an individual element's -// bitstream data. -type Encoder struct { - p *PkgEncoder - - Relocs []RelocEnt - RelocMap map[RelocEnt]uint32 - Data bytes.Buffer // accumulated element bitstream data - - encodingRelocHeader bool - - k RelocKind - Idx Index // index within relocation section -} - -// Flush finalizes the element's bitstream and returns its Index. -func (w *Encoder) Flush() Index { - var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved - - // Backup the data so we write the relocations at the front. - var tmp bytes.Buffer - io.Copy(&tmp, &w.Data) - - // TODO(mdempsky): Consider writing these out separately so they're - // easier to strip, along with function bodies, so that we can prune - // down to just the data that's relevant to go/types. - if w.encodingRelocHeader { - panic("encodingRelocHeader already true; recursive flush?") - } - w.encodingRelocHeader = true - w.Sync(SyncRelocs) - w.Len(len(w.Relocs)) - for _, rEnt := range w.Relocs { - w.Sync(SyncReloc) - w.Len(int(rEnt.Kind)) - w.Len(int(rEnt.Idx)) - } - - io.Copy(&sb, &w.Data) - io.Copy(&sb, &tmp) - w.p.elems[w.k][w.Idx] = sb.String() - - return w.Idx -} - -func (w *Encoder) checkErr(err error) { - if err != nil { - errorf("unexpected encoding error: %v", err) - } -} - -func (w *Encoder) rawUvarint(x uint64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutUvarint(buf[:], x) - _, err := w.Data.Write(buf[:n]) - w.checkErr(err) -} - -func (w *Encoder) rawVarint(x int64) { - // Zig-zag encode. - ux := uint64(x) << 1 - if x < 0 { - ux = ^ux - } - - w.rawUvarint(ux) -} - -func (w *Encoder) rawReloc(r RelocKind, idx Index) int { - e := RelocEnt{r, idx} - if w.RelocMap != nil { - if i, ok := w.RelocMap[e]; ok { - return int(i) - } - } else { - w.RelocMap = make(map[RelocEnt]uint32) - } - - i := len(w.Relocs) - w.RelocMap[e] = uint32(i) - w.Relocs = append(w.Relocs, e) - return i -} - -func (w *Encoder) Sync(m SyncMarker) { - if !w.p.SyncMarkers() { - return - } - - // Writing out stack frame string references requires working - // relocations, but writing out the relocations themselves involves - // sync markers. To prevent infinite recursion, we simply trim the - // stack frame for sync markers within the relocation header. - var frames []string - if !w.encodingRelocHeader && w.p.syncFrames > 0 { - pcs := make([]uintptr, w.p.syncFrames) - n := runtime.Callers(2, pcs) - frames = fmtFrames(pcs[:n]...) - } - - // TODO(mdempsky): Save space by writing out stack frames as a - // linked list so we can share common stack frames. - w.rawUvarint(uint64(m)) - w.rawUvarint(uint64(len(frames))) - for _, frame := range frames { - w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame)))) - } -} - -// Bool encodes and writes a bool value into the element bitstream, -// and then returns the bool value. -// -// For simple, 2-alternative encodings, the idiomatic way to call Bool -// is something like: -// -// if w.Bool(x != 0) { -// // alternative #1 -// } else { -// // alternative #2 -// } -// -// For multi-alternative encodings, use Code instead. -func (w *Encoder) Bool(b bool) bool { - w.Sync(SyncBool) - var x byte - if b { - x = 1 - } - err := w.Data.WriteByte(x) - w.checkErr(err) - return b -} - -// Int64 encodes and writes an int64 value into the element bitstream. -func (w *Encoder) Int64(x int64) { - w.Sync(SyncInt64) - w.rawVarint(x) -} - -// Uint64 encodes and writes a uint64 value into the element bitstream. -func (w *Encoder) Uint64(x uint64) { - w.Sync(SyncUint64) - w.rawUvarint(x) -} - -// Len encodes and writes a non-negative int value into the element bitstream. -func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) } - -// Int encodes and writes an int value into the element bitstream. -func (w *Encoder) Int(x int) { w.Int64(int64(x)) } - -// Uint encodes and writes a uint value into the element bitstream. -func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) } - -// Reloc encodes and writes a relocation for the given (section, -// index) pair into the element bitstream. -// -// Note: Only the index is formally written into the element -// bitstream, so bitstream decoders must know from context which -// section an encoded relocation refers to. -func (w *Encoder) Reloc(r RelocKind, idx Index) { - w.Sync(SyncUseReloc) - w.Len(w.rawReloc(r, idx)) -} - -// Code encodes and writes a Code value into the element bitstream. -func (w *Encoder) Code(c Code) { - w.Sync(c.Marker()) - w.Len(c.Value()) -} - -// String encodes and writes a string value into the element -// bitstream. -// -// Internally, strings are deduplicated by adding them to the strings -// section (if not already present), and then writing a relocation -// into the element bitstream. -func (w *Encoder) String(s string) { - w.Sync(SyncString) - w.Reloc(RelocString, w.p.StringIdx(s)) -} - -// Strings encodes and writes a variable-length slice of strings into -// the element bitstream. -func (w *Encoder) Strings(ss []string) { - w.Len(len(ss)) - for _, s := range ss { - w.String(s) - } -} - -// Value encodes and writes a constant.Value into the element -// bitstream. -func (w *Encoder) Value(val constant.Value) { - w.Sync(SyncValue) - if w.Bool(val.Kind() == constant.Complex) { - w.scalar(constant.Real(val)) - w.scalar(constant.Imag(val)) - } else { - w.scalar(val) - } -} - -func (w *Encoder) scalar(val constant.Value) { - switch v := constant.Val(val).(type) { - default: - errorf("unhandled %v (%v)", val, val.Kind()) - case bool: - w.Code(ValBool) - w.Bool(v) - case string: - w.Code(ValString) - w.String(v) - case int64: - w.Code(ValInt64) - w.Int64(v) - case *big.Int: - w.Code(ValBigInt) - w.bigInt(v) - case *big.Rat: - w.Code(ValBigRat) - w.bigInt(v.Num()) - w.bigInt(v.Denom()) - case *big.Float: - w.Code(ValBigFloat) - w.bigFloat(v) - } -} - -func (w *Encoder) bigInt(v *big.Int) { - b := v.Bytes() - w.String(string(b)) // TODO: More efficient encoding. - w.Bool(v.Sign() < 0) -} - -func (w *Encoder) bigFloat(v *big.Float) { - b := v.Append(nil, 'p', -1) - w.String(string(b)) // TODO: More efficient encoding. -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/internal/pkgbits/flags.go deleted file mode 100644 index 65422274..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/flags.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -const ( - flagSyncMarkers = 1 << iota // file format contains sync markers -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go deleted file mode 100644 index 5294f6a6..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.7 -// +build !go1.7 - -// TODO(mdempsky): Remove after #44505 is resolved - -package pkgbits - -import "runtime" - -func walkFrames(pcs []uintptr, visit frameVisitor) { - for _, pc := range pcs { - fn := runtime.FuncForPC(pc) - file, line := fn.FileLine(pc) - - visit(file, line, fn.Name(), pc-fn.Entry()) - } -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go deleted file mode 100644 index 2324ae7a..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.7 -// +build go1.7 - -package pkgbits - -import "runtime" - -// walkFrames calls visit for each call frame represented by pcs. -// -// pcs should be a slice of PCs, as returned by runtime.Callers. -func walkFrames(pcs []uintptr, visit frameVisitor) { - if len(pcs) == 0 { - return - } - - frames := runtime.CallersFrames(pcs) - for { - frame, more := frames.Next() - visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) - if !more { - return - } - } -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go deleted file mode 100644 index fcdfb97c..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -// A RelocKind indicates a particular section within a unified IR export. -type RelocKind int32 - -// An Index represents a bitstream element index within a particular -// section. -type Index int32 - -// A relocEnt (relocation entry) is an entry in an element's local -// reference table. -// -// TODO(mdempsky): Rename this too. -type RelocEnt struct { - Kind RelocKind - Idx Index -} - -// Reserved indices within the meta relocation section. -const ( - PublicRootIdx Index = 0 - PrivateRootIdx Index = 1 -) - -const ( - RelocString RelocKind = iota - RelocMeta - RelocPosBase - RelocPkg - RelocName - RelocType - RelocObj - RelocObjExt - RelocObjDict - RelocBody - - numRelocs = iota -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/support.go b/vendor/golang.org/x/tools/internal/pkgbits/support.go deleted file mode 100644 index ad26d3b2..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/support.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -import "fmt" - -func assert(b bool) { - if !b { - panic("assertion failed") - } -} - -func errorf(format string, args ...interface{}) { - panic(fmt.Errorf(format, args...)) -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/internal/pkgbits/sync.go deleted file mode 100644 index 5bd51ef7..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/sync.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -import ( - "fmt" - "strings" -) - -// fmtFrames formats a backtrace for reporting reader/writer desyncs. -func fmtFrames(pcs ...uintptr) []string { - res := make([]string, 0, len(pcs)) - walkFrames(pcs, func(file string, line int, name string, offset uintptr) { - // Trim package from function name. It's just redundant noise. - name = strings.TrimPrefix(name, "cmd/compile/internal/noder.") - - res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset)) - }) - return res -} - -type frameVisitor func(file string, line int, name string, offset uintptr) - -// SyncMarker is an enum type that represents markers that may be -// written to export data to ensure the reader and writer stay -// synchronized. -type SyncMarker int - -//go:generate stringer -type=SyncMarker -trimprefix=Sync - -const ( - _ SyncMarker = iota - - // Public markers (known to go/types importers). - - // Low-level coding markers. - SyncEOF - SyncBool - SyncInt64 - SyncUint64 - SyncString - SyncValue - SyncVal - SyncRelocs - SyncReloc - SyncUseReloc - - // Higher-level object and type markers. - SyncPublic - SyncPos - SyncPosBase - SyncObject - SyncObject1 - SyncPkg - SyncPkgDef - SyncMethod - SyncType - SyncTypeIdx - SyncTypeParamNames - SyncSignature - SyncParams - SyncParam - SyncCodeObj - SyncSym - SyncLocalIdent - SyncSelector - - // Private markers (only known to cmd/compile). - SyncPrivate - - SyncFuncExt - SyncVarExt - SyncTypeExt - SyncPragma - - SyncExprList - SyncExprs - SyncExpr - SyncExprType - SyncAssign - SyncOp - SyncFuncLit - SyncCompLit - - SyncDecl - SyncFuncBody - SyncOpenScope - SyncCloseScope - SyncCloseAnotherScope - SyncDeclNames - SyncDeclName - - SyncStmts - SyncBlockStmt - SyncIfStmt - SyncForStmt - SyncSwitchStmt - SyncRangeStmt - SyncCaseClause - SyncCommClause - SyncSelectStmt - SyncDecls - SyncLabeledStmt - SyncUseObjLocal - SyncAddLocal - SyncLinkname - SyncStmt1 - SyncStmtsEnd - SyncLabel - SyncOptLabel -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go deleted file mode 100644 index 4a5b0ca5..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go +++ /dev/null @@ -1,89 +0,0 @@ -// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT. - -package pkgbits - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[SyncEOF-1] - _ = x[SyncBool-2] - _ = x[SyncInt64-3] - _ = x[SyncUint64-4] - _ = x[SyncString-5] - _ = x[SyncValue-6] - _ = x[SyncVal-7] - _ = x[SyncRelocs-8] - _ = x[SyncReloc-9] - _ = x[SyncUseReloc-10] - _ = x[SyncPublic-11] - _ = x[SyncPos-12] - _ = x[SyncPosBase-13] - _ = x[SyncObject-14] - _ = x[SyncObject1-15] - _ = x[SyncPkg-16] - _ = x[SyncPkgDef-17] - _ = x[SyncMethod-18] - _ = x[SyncType-19] - _ = x[SyncTypeIdx-20] - _ = x[SyncTypeParamNames-21] - _ = x[SyncSignature-22] - _ = x[SyncParams-23] - _ = x[SyncParam-24] - _ = x[SyncCodeObj-25] - _ = x[SyncSym-26] - _ = x[SyncLocalIdent-27] - _ = x[SyncSelector-28] - _ = x[SyncPrivate-29] - _ = x[SyncFuncExt-30] - _ = x[SyncVarExt-31] - _ = x[SyncTypeExt-32] - _ = x[SyncPragma-33] - _ = x[SyncExprList-34] - _ = x[SyncExprs-35] - _ = x[SyncExpr-36] - _ = x[SyncExprType-37] - _ = x[SyncAssign-38] - _ = x[SyncOp-39] - _ = x[SyncFuncLit-40] - _ = x[SyncCompLit-41] - _ = x[SyncDecl-42] - _ = x[SyncFuncBody-43] - _ = x[SyncOpenScope-44] - _ = x[SyncCloseScope-45] - _ = x[SyncCloseAnotherScope-46] - _ = x[SyncDeclNames-47] - _ = x[SyncDeclName-48] - _ = x[SyncStmts-49] - _ = x[SyncBlockStmt-50] - _ = x[SyncIfStmt-51] - _ = x[SyncForStmt-52] - _ = x[SyncSwitchStmt-53] - _ = x[SyncRangeStmt-54] - _ = x[SyncCaseClause-55] - _ = x[SyncCommClause-56] - _ = x[SyncSelectStmt-57] - _ = x[SyncDecls-58] - _ = x[SyncLabeledStmt-59] - _ = x[SyncUseObjLocal-60] - _ = x[SyncAddLocal-61] - _ = x[SyncLinkname-62] - _ = x[SyncStmt1-63] - _ = x[SyncStmtsEnd-64] - _ = x[SyncLabel-65] - _ = x[SyncOptLabel-66] -} - -const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel" - -var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458} - -func (i SyncMarker) String() string { - i -= 1 - if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) { - return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")" - } - return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]] -} diff --git a/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go deleted file mode 100644 index 7e638ec2..00000000 --- a/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// package tokeninternal provides access to some internal features of the token -// package. -package tokeninternal - -import ( - "fmt" - "go/token" - "sort" - "sync" - "unsafe" -) - -// GetLines returns the table of line-start offsets from a token.File. -func GetLines(file *token.File) []int { - // token.File has a Lines method on Go 1.21 and later. - if file, ok := (interface{})(file).(interface{ Lines() []int }); ok { - return file.Lines() - } - - // This declaration must match that of token.File. - // This creates a risk of dependency skew. - // For now we check that the size of the two - // declarations is the same, on the (fragile) assumption - // that future changes would add fields. - type tokenFile119 struct { - _ string - _ int - _ int - mu sync.Mutex // we're not complete monsters - lines []int - _ []struct{} - } - type tokenFile118 struct { - _ *token.FileSet // deleted in go1.19 - tokenFile119 - } - - type uP = unsafe.Pointer - switch unsafe.Sizeof(*file) { - case unsafe.Sizeof(tokenFile118{}): - var ptr *tokenFile118 - *(*uP)(uP(&ptr)) = uP(file) - ptr.mu.Lock() - defer ptr.mu.Unlock() - return ptr.lines - - case unsafe.Sizeof(tokenFile119{}): - var ptr *tokenFile119 - *(*uP)(uP(&ptr)) = uP(file) - ptr.mu.Lock() - defer ptr.mu.Unlock() - return ptr.lines - - default: - panic("unexpected token.File size") - } -} - -// AddExistingFiles adds the specified files to the FileSet if they -// are not already present. It panics if any pair of files in the -// resulting FileSet would overlap. -func AddExistingFiles(fset *token.FileSet, files []*token.File) { - // Punch through the FileSet encapsulation. - type tokenFileSet struct { - // This type remained essentially consistent from go1.16 to go1.21. - mutex sync.RWMutex - base int - files []*token.File - _ *token.File // changed to atomic.Pointer[token.File] in go1.19 - } - - // If the size of token.FileSet changes, this will fail to compile. - const delta = int64(unsafe.Sizeof(tokenFileSet{})) - int64(unsafe.Sizeof(token.FileSet{})) - var _ [-delta * delta]int - - type uP = unsafe.Pointer - var ptr *tokenFileSet - *(*uP)(uP(&ptr)) = uP(fset) - ptr.mutex.Lock() - defer ptr.mutex.Unlock() - - // Merge and sort. - newFiles := append(ptr.files, files...) - sort.Slice(newFiles, func(i, j int) bool { - return newFiles[i].Base() < newFiles[j].Base() - }) - - // Reject overlapping files. - // Discard adjacent identical files. - out := newFiles[:0] - for i, file := range newFiles { - if i > 0 { - prev := newFiles[i-1] - if file == prev { - continue - } - if prev.Base()+prev.Size()+1 > file.Base() { - panic(fmt.Sprintf("file %s (%d-%d) overlaps with file %s (%d-%d)", - prev.Name(), prev.Base(), prev.Base()+prev.Size(), - file.Name(), file.Base(), file.Base()+file.Size())) - } - } - out = append(out, file) - } - newFiles = out - - ptr.files = newFiles - - // Advance FileSet.Base(). - if len(newFiles) > 0 { - last := newFiles[len(newFiles)-1] - newBase := last.Base() + last.Size() + 1 - if ptr.base < newBase { - ptr.base = newBase - } - } -} - -// FileSetFor returns a new FileSet containing a sequence of new Files with -// the same base, size, and line as the input files, for use in APIs that -// require a FileSet. -// -// Precondition: the input files must be non-overlapping, and sorted in order -// of their Base. -func FileSetFor(files ...*token.File) *token.FileSet { - fset := token.NewFileSet() - for _, f := range files { - f2 := fset.AddFile(f.Name(), f.Base(), f.Size()) - lines := GetLines(f) - f2.SetLines(lines) - } - return fset -} - -// CloneFileSet creates a new FileSet holding all files in fset. It does not -// create copies of the token.Files in fset: they are added to the resulting -// FileSet unmodified. -func CloneFileSet(fset *token.FileSet) *token.FileSet { - var files []*token.File - fset.Iterate(func(f *token.File) bool { - files = append(files, f) - return true - }) - newFileSet := token.NewFileSet() - AddExistingFiles(newFileSet, files) - return newFileSet -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go deleted file mode 100644 index cdab9885..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/common.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package typeparams contains common utilities for writing tools that interact -// with generic Go code, as introduced with Go 1.18. -// -// Many of the types and functions in this package are proxies for the new APIs -// introduced in the standard library with Go 1.18. For example, the -// typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec -// function returns the value of the go/ast.TypeSpec.TypeParams field. At Go -// versions older than 1.18 these helpers are implemented as stubs, allowing -// users of this package to write code that handles generic constructs inline, -// even if the Go version being used to compile does not support generics. -// -// Additionally, this package contains common utilities for working with the -// new generic constructs, to supplement the standard library APIs. Notably, -// the StructuralTerms API computes a minimal representation of the structural -// restrictions on a type parameter. -// -// An external version of these APIs is available in the -// golang.org/x/exp/typeparams module. -package typeparams - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" -) - -// UnpackIndexExpr extracts data from AST nodes that represent index -// expressions. -// -// For an ast.IndexExpr, the resulting indices slice will contain exactly one -// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable -// number of index expressions. -// -// For nodes that don't represent index expressions, the first return value of -// UnpackIndexExpr will be nil. -func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) { - switch e := n.(type) { - case *ast.IndexExpr: - return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack - case *ast.IndexListExpr: - return e.X, e.Lbrack, e.Indices, e.Rbrack - } - return nil, token.NoPos, nil, token.NoPos -} - -// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on -// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 -// will panic. -func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { - switch len(indices) { - case 0: - panic("empty indices") - case 1: - return &ast.IndexExpr{ - X: x, - Lbrack: lbrack, - Index: indices[0], - Rbrack: rbrack, - } - default: - return &ast.IndexListExpr{ - X: x, - Lbrack: lbrack, - Indices: indices, - Rbrack: rbrack, - } - } -} - -// IsTypeParam reports whether t is a type parameter. -func IsTypeParam(t types.Type) bool { - _, ok := t.(*types.TypeParam) - return ok -} - -// OriginMethod returns the origin method associated with the method fn. -// For methods on a non-generic receiver base type, this is just -// fn. However, for methods with a generic receiver, OriginMethod returns the -// corresponding method in the method set of the origin type. -// -// As a special case, if fn is not a method (has no receiver), OriginMethod -// returns fn. -func OriginMethod(fn *types.Func) *types.Func { - recv := fn.Type().(*types.Signature).Recv() - if recv == nil { - return fn - } - base := recv.Type() - p, isPtr := base.(*types.Pointer) - if isPtr { - base = p.Elem() - } - named, isNamed := base.(*types.Named) - if !isNamed { - // Receiver is a *types.Interface. - return fn - } - if named.TypeParams().Len() == 0 { - // Receiver base has no type parameters, so we can avoid the lookup below. - return fn - } - orig := named.Origin() - gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name()) - - // This is a fix for a gopls crash (#60628) due to a go/types bug (#60634). In: - // package p - // type T *int - // func (*T) f() {} - // LookupFieldOrMethod(T, true, p, f)=nil, but NewMethodSet(*T)={(*T).f}. - // Here we make them consistent by force. - // (The go/types bug is general, but this workaround is reached only - // for generic T thanks to the early return above.) - if gfn == nil { - mset := types.NewMethodSet(types.NewPointer(orig)) - for i := 0; i < mset.Len(); i++ { - m := mset.At(i) - if m.Obj().Id() == fn.Id() { - gfn = m.Obj() - break - } - } - } - - // In golang/go#61196, we observe another crash, this time inexplicable. - if gfn == nil { - panic(fmt.Sprintf("missing origin method for %s.%s; named == origin: %t, named.NumMethods(): %d, origin.NumMethods(): %d", named, fn, named == orig, named.NumMethods(), orig.NumMethods())) - } - - return gfn.(*types.Func) -} - -// GenericAssignableTo is a generalization of types.AssignableTo that -// implements the following rule for uninstantiated generic types: -// -// If V and T are generic named types, then V is considered assignable to T if, -// for every possible instantation of V[A_1, ..., A_N], the instantiation -// T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N]. -// -// If T has structural constraints, they must be satisfied by V. -// -// For example, consider the following type declarations: -// -// type Interface[T any] interface { -// Accept(T) -// } -// -// type Container[T any] struct { -// Element T -// } -// -// func (c Container[T]) Accept(t T) { c.Element = t } -// -// In this case, GenericAssignableTo reports that instantiations of Container -// are assignable to the corresponding instantiation of Interface. -func GenericAssignableTo(ctxt *types.Context, V, T types.Type) bool { - // If V and T are not both named, or do not have matching non-empty type - // parameter lists, fall back on types.AssignableTo. - - VN, Vnamed := V.(*types.Named) - TN, Tnamed := T.(*types.Named) - if !Vnamed || !Tnamed { - return types.AssignableTo(V, T) - } - - vtparams := VN.TypeParams() - ttparams := TN.TypeParams() - if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || VN.TypeArgs().Len() != 0 || TN.TypeArgs().Len() != 0 { - return types.AssignableTo(V, T) - } - - // V and T have the same (non-zero) number of type params. Instantiate both - // with the type parameters of V. This must always succeed for V, and will - // succeed for T if and only if the type set of each type parameter of V is a - // subset of the type set of the corresponding type parameter of T, meaning - // that every instantiation of V corresponds to a valid instantiation of T. - - // Minor optimization: ensure we share a context across the two - // instantiations below. - if ctxt == nil { - ctxt = types.NewContext() - } - - var targs []types.Type - for i := 0; i < vtparams.Len(); i++ { - targs = append(targs, vtparams.At(i)) - } - - vinst, err := types.Instantiate(ctxt, V, targs, true) - if err != nil { - panic("type parameters should satisfy their own constraints") - } - - tinst, err := types.Instantiate(ctxt, T, targs, true) - if err != nil { - return false - } - - return types.AssignableTo(vinst, tinst) -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go deleted file mode 100644 index 7ea8840e..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/coretype.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeparams - -import ( - "go/types" -) - -// CoreType returns the core type of T or nil if T does not have a core type. -// -// See https://go.dev/ref/spec#Core_types for the definition of a core type. -func CoreType(T types.Type) types.Type { - U := T.Underlying() - if _, ok := U.(*types.Interface); !ok { - return U // for non-interface types, - } - - terms, err := _NormalTerms(U) - if len(terms) == 0 || err != nil { - // len(terms) -> empty type set of interface. - // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set. - return nil // no core type. - } - - U = terms[0].Type().Underlying() - var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying()) - for identical = 1; identical < len(terms); identical++ { - if !types.Identical(U, terms[identical].Type().Underlying()) { - break - } - } - - if identical == len(terms) { - // https://go.dev/ref/spec#Core_types - // "There is a single type U which is the underlying type of all types in the type set of T" - return U - } - ch, ok := U.(*types.Chan) - if !ok { - return nil // no core type as identical < len(terms) and U is not a channel. - } - // https://go.dev/ref/spec#Core_types - // "the type chan E if T contains only bidirectional channels, or the type chan<- E or - // <-chan E depending on the direction of the directional channels present." - for chans := identical; chans < len(terms); chans++ { - curr, ok := terms[chans].Type().Underlying().(*types.Chan) - if !ok { - return nil - } - if !types.Identical(ch.Elem(), curr.Elem()) { - return nil // channel elements are not identical. - } - if ch.Dir() == types.SendRecv { - // ch is bidirectional. We can safely always use curr's direction. - ch = curr - } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() { - // ch and curr are not bidirectional and not the same direction. - return nil - } - } - return ch -} - -// _NormalTerms returns a slice of terms representing the normalized structural -// type restrictions of a type, if any. -// -// For all types other than *types.TypeParam, *types.Interface, and -// *types.Union, this is just a single term with Tilde() == false and -// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see -// below. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration type -// T[P interface{~int; m()}] int the structural restriction of the type -// parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// _NormalTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, _NormalTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the type is -// invalid, exceeds complexity bounds, or has an empty type set. In the latter -// case, _NormalTerms returns ErrEmptyTypeSet. -// -// _NormalTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func _NormalTerms(typ types.Type) ([]*types.Term, error) { - switch typ := typ.(type) { - case *types.TypeParam: - return StructuralTerms(typ) - case *types.Union: - return UnionTermSet(typ) - case *types.Interface: - return InterfaceTermSet(typ) - default: - return []*types.Term{types.NewTerm(false, typ)}, nil - } -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go deleted file mode 100644 index 93c80fdc..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/normalize.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeparams - -import ( - "errors" - "fmt" - "go/types" - "os" - "strings" -) - -//go:generate go run copytermlist.go - -const debug = false - -var ErrEmptyTypeSet = errors.New("empty type set") - -// StructuralTerms returns a slice of terms representing the normalized -// structural type restrictions of a type parameter, if any. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration -// -// type T[P interface{~int; m()}] int -// -// the structural restriction of the type parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// StructuralTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, StructuralTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the -// constraint interface is invalid, exceeds complexity bounds, or has an empty -// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. -// -// StructuralTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) { - constraint := tparam.Constraint() - if constraint == nil { - return nil, fmt.Errorf("%s has nil constraint", tparam) - } - iface, _ := constraint.Underlying().(*types.Interface) - if iface == nil { - return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) - } - return InterfaceTermSet(iface) -} - -// InterfaceTermSet computes the normalized terms for a constraint interface, -// returning an error if the term set cannot be computed or is empty. In the -// latter case, the error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) { - return computeTermSet(iface) -} - -// UnionTermSet computes the normalized terms for a union, returning an error -// if the term set cannot be computed or is empty. In the latter case, the -// error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func UnionTermSet(union *types.Union) ([]*types.Term, error) { - return computeTermSet(union) -} - -func computeTermSet(typ types.Type) ([]*types.Term, error) { - tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) - if err != nil { - return nil, err - } - if tset.terms.isEmpty() { - return nil, ErrEmptyTypeSet - } - if tset.terms.isAll() { - return nil, nil - } - var terms []*types.Term - for _, term := range tset.terms { - terms = append(terms, types.NewTerm(term.tilde, term.typ)) - } - return terms, nil -} - -// A termSet holds the normalized set of terms for a given type. -// -// The name termSet is intentionally distinct from 'type set': a type set is -// all types that implement a type (and includes method restrictions), whereas -// a term set just represents the structural restrictions on a type. -type termSet struct { - complete bool - terms termlist -} - -func indentf(depth int, format string, args ...interface{}) { - fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) -} - -func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { - if t == nil { - panic("nil type") - } - - if debug { - indentf(depth, "%s", t.String()) - defer func() { - if err != nil { - indentf(depth, "=> %s", err) - } else { - indentf(depth, "=> %s", res.terms.String()) - } - }() - } - - const maxTermCount = 100 - if tset, ok := seen[t]; ok { - if !tset.complete { - return nil, fmt.Errorf("cycle detected in the declaration of %s", t) - } - return tset, nil - } - - // Mark the current type as seen to avoid infinite recursion. - tset := new(termSet) - defer func() { - tset.complete = true - }() - seen[t] = tset - - switch u := t.Underlying().(type) { - case *types.Interface: - // The term set of an interface is the intersection of the term sets of its - // embedded types. - tset.terms = allTermlist - for i := 0; i < u.NumEmbeddeds(); i++ { - embedded := u.EmbeddedType(i) - if _, ok := embedded.Underlying().(*types.TypeParam); ok { - return nil, fmt.Errorf("invalid embedded type %T", embedded) - } - tset2, err := computeTermSetInternal(embedded, seen, depth+1) - if err != nil { - return nil, err - } - tset.terms = tset.terms.intersect(tset2.terms) - } - case *types.Union: - // The term set of a union is the union of term sets of its terms. - tset.terms = nil - for i := 0; i < u.Len(); i++ { - t := u.Term(i) - var terms termlist - switch t.Type().Underlying().(type) { - case *types.Interface: - tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) - if err != nil { - return nil, err - } - terms = tset2.terms - case *types.TypeParam, *types.Union: - // A stand-alone type parameter or union is not permitted as union - // term. - return nil, fmt.Errorf("invalid union term %T", t) - default: - if t.Type() == types.Typ[types.Invalid] { - continue - } - terms = termlist{{t.Tilde(), t.Type()}} - } - tset.terms = tset.terms.union(terms) - if len(tset.terms) > maxTermCount { - return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) - } - } - case *types.TypeParam: - panic("unreachable") - default: - // For all other types, the term set is just a single non-tilde term - // holding the type itself. - if u != types.Typ[types.Invalid] { - tset.terms = termlist{{false, t}} - } - } - return tset, nil -} - -// under is a facade for the go/types internal function of the same name. It is -// used by typeterm.go. -func under(t types.Type) types.Type { - return t.Underlying() -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/vendor/golang.org/x/tools/internal/typeparams/termlist.go deleted file mode 100644 index cbd12f80..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/termlist.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import ( - "bytes" - "go/types" -) - -// A termlist represents the type set represented by the union -// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. -// A termlist is in normal form if all terms are disjoint. -// termlist operations don't require the operands to be in -// normal form. -type termlist []*term - -// allTermlist represents the set of all types. -// It is in normal form. -var allTermlist = termlist{new(term)} - -// String prints the termlist exactly (without normalization). -func (xl termlist) String() string { - if len(xl) == 0 { - return "∅" - } - var buf bytes.Buffer - for i, x := range xl { - if i > 0 { - buf.WriteString(" | ") - } - buf.WriteString(x.String()) - } - return buf.String() -} - -// isEmpty reports whether the termlist xl represents the empty set of types. -func (xl termlist) isEmpty() bool { - // If there's a non-nil term, the entire list is not empty. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil { - return false - } - } - return true -} - -// isAll reports whether the termlist xl represents the set of all types. -func (xl termlist) isAll() bool { - // If there's a 𝓤 term, the entire list is 𝓤. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil && x.typ == nil { - return true - } - } - return false -} - -// norm returns the normal form of xl. -func (xl termlist) norm() termlist { - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - used := make([]bool, len(xl)) - var rl termlist - for i, xi := range xl { - if xi == nil || used[i] { - continue - } - for j := i + 1; j < len(xl); j++ { - xj := xl[j] - if xj == nil || used[j] { - continue - } - if u1, u2 := xi.union(xj); u2 == nil { - // If we encounter a 𝓤 term, the entire list is 𝓤. - // Exit early. - // (Note that this is not just an optimization; - // if we continue, we may end up with a 𝓤 term - // and other terms and the result would not be - // in normal form.) - if u1.typ == nil { - return allTermlist - } - xi = u1 - used[j] = true // xj is now unioned into xi - ignore it in future iterations - } - } - rl = append(rl, xi) - } - return rl -} - -// union returns the union xl ∪ yl. -func (xl termlist) union(yl termlist) termlist { - return append(xl, yl...).norm() -} - -// intersect returns the intersection xl ∩ yl. -func (xl termlist) intersect(yl termlist) termlist { - if xl.isEmpty() || yl.isEmpty() { - return nil - } - - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - var rl termlist - for _, x := range xl { - for _, y := range yl { - if r := x.intersect(y); r != nil { - rl = append(rl, r) - } - } - } - return rl.norm() -} - -// equal reports whether xl and yl represent the same type set. -func (xl termlist) equal(yl termlist) bool { - // TODO(gri) this should be more efficient - return xl.subsetOf(yl) && yl.subsetOf(xl) -} - -// includes reports whether t ∈ xl. -func (xl termlist) includes(t types.Type) bool { - for _, x := range xl { - if x.includes(t) { - return true - } - } - return false -} - -// supersetOf reports whether y ⊆ xl. -func (xl termlist) supersetOf(y *term) bool { - for _, x := range xl { - if y.subsetOf(x) { - return true - } - } - return false -} - -// subsetOf reports whether xl ⊆ yl. -func (xl termlist) subsetOf(yl termlist) bool { - if yl.isEmpty() { - return xl.isEmpty() - } - - // each term x of xl must be a subset of yl - for _, x := range xl { - if !yl.supersetOf(x) { - return false // x is not a subset yl - } - } - return true -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go deleted file mode 100644 index 7350bb70..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import "go/types" - -// A term describes elementary type sets: -// -// ∅: (*term)(nil) == ∅ // set of no types (empty set) -// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) -// T: &term{false, T} == {T} // set of type T -// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t -type term struct { - tilde bool // valid if typ != nil - typ types.Type -} - -func (x *term) String() string { - switch { - case x == nil: - return "∅" - case x.typ == nil: - return "𝓤" - case x.tilde: - return "~" + x.typ.String() - default: - return x.typ.String() - } -} - -// equal reports whether x and y represent the same type set. -func (x *term) equal(y *term) bool { - // easy cases - switch { - case x == nil || y == nil: - return x == y - case x.typ == nil || y.typ == nil: - return x.typ == y.typ - } - // ∅ ⊂ x, y ⊂ 𝓤 - - return x.tilde == y.tilde && types.Identical(x.typ, y.typ) -} - -// union returns the union x ∪ y: zero, one, or two non-nil terms. -func (x *term) union(y *term) (_, _ *term) { - // easy cases - switch { - case x == nil && y == nil: - return nil, nil // ∅ ∪ ∅ == ∅ - case x == nil: - return y, nil // ∅ ∪ y == y - case y == nil: - return x, nil // x ∪ ∅ == x - case x.typ == nil: - return x, nil // 𝓤 ∪ y == 𝓤 - case y.typ == nil: - return y, nil // x ∪ 𝓤 == 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return x, y // x ∪ y == (x, y) if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∪ ~t == ~t - // ~t ∪ T == ~t - // T ∪ ~t == ~t - // T ∪ T == T - if x.tilde || !y.tilde { - return x, nil - } - return y, nil -} - -// intersect returns the intersection x ∩ y. -func (x *term) intersect(y *term) *term { - // easy cases - switch { - case x == nil || y == nil: - return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ - case x.typ == nil: - return y // 𝓤 ∩ y == y - case y.typ == nil: - return x // x ∩ 𝓤 == x - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return nil // x ∩ y == ∅ if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∩ ~t == ~t - // ~t ∩ T == T - // T ∩ ~t == T - // T ∩ T == T - if !x.tilde || y.tilde { - return x - } - return y -} - -// includes reports whether t ∈ x. -func (x *term) includes(t types.Type) bool { - // easy cases - switch { - case x == nil: - return false // t ∈ ∅ == false - case x.typ == nil: - return true // t ∈ 𝓤 == true - } - // ∅ ⊂ x ⊂ 𝓤 - - u := t - if x.tilde { - u = under(u) - } - return types.Identical(x.typ, u) -} - -// subsetOf reports whether x ⊆ y. -func (x *term) subsetOf(y *term) bool { - // easy cases - switch { - case x == nil: - return true // ∅ ⊆ y == true - case y == nil: - return false // x ⊆ ∅ == false since x != ∅ - case y.typ == nil: - return true // x ⊆ 𝓤 == true - case x.typ == nil: - return false // 𝓤 ⊆ y == false since y != 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return false // x ⊆ y == false if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ⊆ ~t == true - // ~t ⊆ T == false - // T ⊆ ~t == true - // T ⊆ T == true - return !x.tilde || y.tilde -} - -// disjoint reports whether x ∩ y == ∅. -// x.typ and y.typ must not be nil. -func (x *term) disjoint(y *term) bool { - if debug && (x.typ == nil || y.typ == nil) { - panic("invalid argument(s)") - } - ux := x.typ - if y.tilde { - ux = under(ux) - } - uy := y.typ - if x.tilde { - uy = under(uy) - } - return !types.Identical(ux, uy) -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go deleted file mode 100644 index 07484073..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go +++ /dev/null @@ -1,1560 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -//go:generate stringer -type=ErrorCode - -type ErrorCode int - -// This file defines the error codes that can be produced during type-checking. -// Collectively, these codes provide an identifier that may be used to -// implement special handling for certain types of errors. -// -// Error codes should be fine-grained enough that the exact nature of the error -// can be easily determined, but coarse enough that they are not an -// implementation detail of the type checking algorithm. As a rule-of-thumb, -// errors should be considered equivalent if there is a theoretical refactoring -// of the type checker in which they are emitted in exactly one place. For -// example, the type checker emits different error messages for "too many -// arguments" and "too few arguments", but one can imagine an alternative type -// checker where this check instead just emits a single "wrong number of -// arguments", so these errors should have the same code. -// -// Error code names should be as brief as possible while retaining accuracy and -// distinctiveness. In most cases names should start with an adjective -// describing the nature of the error (e.g. "invalid", "unused", "misplaced"), -// and end with a noun identifying the relevant language object. For example, -// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the -// convention that "bad" implies a problem with syntax, and "invalid" implies a -// problem with types. - -const ( - // InvalidSyntaxTree occurs if an invalid syntax tree is provided - // to the type checker. It should never happen. - InvalidSyntaxTree ErrorCode = -1 -) - -const ( - _ ErrorCode = iota - - // Test is reserved for errors that only apply while in self-test mode. - Test - - /* package names */ - - // BlankPkgName occurs when a package name is the blank identifier "_". - // - // Per the spec: - // "The PackageName must not be the blank identifier." - BlankPkgName - - // MismatchedPkgName occurs when a file's package name doesn't match the - // package name already established by other files. - MismatchedPkgName - - // InvalidPkgUse occurs when a package identifier is used outside of a - // selector expression. - // - // Example: - // import "fmt" - // - // var _ = fmt - InvalidPkgUse - - /* imports */ - - // BadImportPath occurs when an import path is not valid. - BadImportPath - - // BrokenImport occurs when importing a package fails. - // - // Example: - // import "amissingpackage" - BrokenImport - - // ImportCRenamed occurs when the special import "C" is renamed. "C" is a - // pseudo-package, and must not be renamed. - // - // Example: - // import _ "C" - ImportCRenamed - - // UnusedImport occurs when an import is unused. - // - // Example: - // import "fmt" - // - // func main() {} - UnusedImport - - /* initialization */ - - // InvalidInitCycle occurs when an invalid cycle is detected within the - // initialization graph. - // - // Example: - // var x int = f() - // - // func f() int { return x } - InvalidInitCycle - - /* decls */ - - // DuplicateDecl occurs when an identifier is declared multiple times. - // - // Example: - // var x = 1 - // var x = 2 - DuplicateDecl - - // InvalidDeclCycle occurs when a declaration cycle is not valid. - // - // Example: - // import "unsafe" - // - // type T struct { - // a [n]int - // } - // - // var n = unsafe.Sizeof(T{}) - InvalidDeclCycle - - // InvalidTypeCycle occurs when a cycle in type definitions results in a - // type that is not well-defined. - // - // Example: - // import "unsafe" - // - // type T [unsafe.Sizeof(T{})]int - InvalidTypeCycle - - /* decls > const */ - - // InvalidConstInit occurs when a const declaration has a non-constant - // initializer. - // - // Example: - // var x int - // const _ = x - InvalidConstInit - - // InvalidConstVal occurs when a const value cannot be converted to its - // target type. - // - // TODO(findleyr): this error code and example are not very clear. Consider - // removing it. - // - // Example: - // const _ = 1 << "hello" - InvalidConstVal - - // InvalidConstType occurs when the underlying type in a const declaration - // is not a valid constant type. - // - // Example: - // const c *int = 4 - InvalidConstType - - /* decls > var (+ other variable assignment codes) */ - - // UntypedNilUse occurs when the predeclared (untyped) value nil is used to - // initialize a variable declared without an explicit type. - // - // Example: - // var x = nil - UntypedNilUse - - // WrongAssignCount occurs when the number of values on the right-hand side - // of an assignment or or initialization expression does not match the number - // of variables on the left-hand side. - // - // Example: - // var x = 1, 2 - WrongAssignCount - - // UnassignableOperand occurs when the left-hand side of an assignment is - // not assignable. - // - // Example: - // func f() { - // const c = 1 - // c = 2 - // } - UnassignableOperand - - // NoNewVar occurs when a short variable declaration (':=') does not declare - // new variables. - // - // Example: - // func f() { - // x := 1 - // x := 2 - // } - NoNewVar - - // MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does - // not have single-valued left-hand or right-hand side. - // - // Per the spec: - // "In assignment operations, both the left- and right-hand expression lists - // must contain exactly one single-valued expression" - // - // Example: - // func f() int { - // x, y := 1, 2 - // x, y += 1 - // return x + y - // } - MultiValAssignOp - - // InvalidIfaceAssign occurs when a value of type T is used as an - // interface, but T does not implement a method of the expected interface. - // - // Example: - // type I interface { - // f() - // } - // - // type T int - // - // var x I = T(1) - InvalidIfaceAssign - - // InvalidChanAssign occurs when a chan assignment is invalid. - // - // Per the spec, a value x is assignable to a channel type T if: - // "x is a bidirectional channel value, T is a channel type, x's type V and - // T have identical element types, and at least one of V or T is not a - // defined type." - // - // Example: - // type T1 chan int - // type T2 chan int - // - // var x T1 - // // Invalid assignment because both types are named - // var _ T2 = x - InvalidChanAssign - - // IncompatibleAssign occurs when the type of the right-hand side expression - // in an assignment cannot be assigned to the type of the variable being - // assigned. - // - // Example: - // var x []int - // var _ int = x - IncompatibleAssign - - // UnaddressableFieldAssign occurs when trying to assign to a struct field - // in a map value. - // - // Example: - // func f() { - // m := make(map[string]struct{i int}) - // m["foo"].i = 42 - // } - UnaddressableFieldAssign - - /* decls > type (+ other type expression codes) */ - - // NotAType occurs when the identifier used as the underlying type in a type - // declaration or the right-hand side of a type alias does not denote a type. - // - // Example: - // var S = 2 - // - // type T S - NotAType - - // InvalidArrayLen occurs when an array length is not a constant value. - // - // Example: - // var n = 3 - // var _ = [n]int{} - InvalidArrayLen - - // BlankIfaceMethod occurs when a method name is '_'. - // - // Per the spec: - // "The name of each explicitly specified method must be unique and not - // blank." - // - // Example: - // type T interface { - // _(int) - // } - BlankIfaceMethod - - // IncomparableMapKey occurs when a map key type does not support the == and - // != operators. - // - // Per the spec: - // "The comparison operators == and != must be fully defined for operands of - // the key type; thus the key type must not be a function, map, or slice." - // - // Example: - // var x map[T]int - // - // type T []int - IncomparableMapKey - - // InvalidIfaceEmbed occurs when a non-interface type is embedded in an - // interface. - // - // Example: - // type T struct {} - // - // func (T) m() - // - // type I interface { - // T - // } - InvalidIfaceEmbed - - // InvalidPtrEmbed occurs when an embedded field is of the pointer form *T, - // and T itself is itself a pointer, an unsafe.Pointer, or an interface. - // - // Per the spec: - // "An embedded field must be specified as a type name T or as a pointer to - // a non-interface type name *T, and T itself may not be a pointer type." - // - // Example: - // type T *int - // - // type S struct { - // *T - // } - InvalidPtrEmbed - - /* decls > func and method */ - - // BadRecv occurs when a method declaration does not have exactly one - // receiver parameter. - // - // Example: - // func () _() {} - BadRecv - - // InvalidRecv occurs when a receiver type expression is not of the form T - // or *T, or T is a pointer type. - // - // Example: - // type T struct {} - // - // func (**T) m() {} - InvalidRecv - - // DuplicateFieldAndMethod occurs when an identifier appears as both a field - // and method name. - // - // Example: - // type T struct { - // m int - // } - // - // func (T) m() {} - DuplicateFieldAndMethod - - // DuplicateMethod occurs when two methods on the same receiver type have - // the same name. - // - // Example: - // type T struct {} - // func (T) m() {} - // func (T) m(i int) int { return i } - DuplicateMethod - - /* decls > special */ - - // InvalidBlank occurs when a blank identifier is used as a value or type. - // - // Per the spec: - // "The blank identifier may appear as an operand only on the left-hand side - // of an assignment." - // - // Example: - // var x = _ - InvalidBlank - - // InvalidIota occurs when the predeclared identifier iota is used outside - // of a constant declaration. - // - // Example: - // var x = iota - InvalidIota - - // MissingInitBody occurs when an init function is missing its body. - // - // Example: - // func init() - MissingInitBody - - // InvalidInitSig occurs when an init function declares parameters or - // results. - // - // Example: - // func init() int { return 1 } - InvalidInitSig - - // InvalidInitDecl occurs when init is declared as anything other than a - // function. - // - // Example: - // var init = 1 - InvalidInitDecl - - // InvalidMainDecl occurs when main is declared as anything other than a - // function, in a main package. - InvalidMainDecl - - /* exprs */ - - // TooManyValues occurs when a function returns too many values for the - // expression context in which it is used. - // - // Example: - // func ReturnTwo() (int, int) { - // return 1, 2 - // } - // - // var x = ReturnTwo() - TooManyValues - - // NotAnExpr occurs when a type expression is used where a value expression - // is expected. - // - // Example: - // type T struct {} - // - // func f() { - // T - // } - NotAnExpr - - /* exprs > const */ - - // TruncatedFloat occurs when a float constant is truncated to an integer - // value. - // - // Example: - // var _ int = 98.6 - TruncatedFloat - - // NumericOverflow occurs when a numeric constant overflows its target type. - // - // Example: - // var x int8 = 1000 - NumericOverflow - - /* exprs > operation */ - - // UndefinedOp occurs when an operator is not defined for the type(s) used - // in an operation. - // - // Example: - // var c = "a" - "b" - UndefinedOp - - // MismatchedTypes occurs when operand types are incompatible in a binary - // operation. - // - // Example: - // var a = "hello" - // var b = 1 - // var c = a - b - MismatchedTypes - - // DivByZero occurs when a division operation is provable at compile - // time to be a division by zero. - // - // Example: - // const divisor = 0 - // var x int = 1/divisor - DivByZero - - // NonNumericIncDec occurs when an increment or decrement operator is - // applied to a non-numeric value. - // - // Example: - // func f() { - // var c = "c" - // c++ - // } - NonNumericIncDec - - /* exprs > ptr */ - - // UnaddressableOperand occurs when the & operator is applied to an - // unaddressable expression. - // - // Example: - // var x = &1 - UnaddressableOperand - - // InvalidIndirection occurs when a non-pointer value is indirected via the - // '*' operator. - // - // Example: - // var x int - // var y = *x - InvalidIndirection - - /* exprs > [] */ - - // NonIndexableOperand occurs when an index operation is applied to a value - // that cannot be indexed. - // - // Example: - // var x = 1 - // var y = x[1] - NonIndexableOperand - - // InvalidIndex occurs when an index argument is not of integer type, - // negative, or out-of-bounds. - // - // Example: - // var s = [...]int{1,2,3} - // var x = s[5] - // - // Example: - // var s = []int{1,2,3} - // var _ = s[-1] - // - // Example: - // var s = []int{1,2,3} - // var i string - // var _ = s[i] - InvalidIndex - - // SwappedSliceIndices occurs when constant indices in a slice expression - // are decreasing in value. - // - // Example: - // var _ = []int{1,2,3}[2:1] - SwappedSliceIndices - - /* operators > slice */ - - // NonSliceableOperand occurs when a slice operation is applied to a value - // whose type is not sliceable, or is unaddressable. - // - // Example: - // var x = [...]int{1, 2, 3}[:1] - // - // Example: - // var x = 1 - // var y = 1[:1] - NonSliceableOperand - - // InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is - // applied to a string. - // - // Example: - // var s = "hello" - // var x = s[1:2:3] - InvalidSliceExpr - - /* exprs > shift */ - - // InvalidShiftCount occurs when the right-hand side of a shift operation is - // either non-integer, negative, or too large. - // - // Example: - // var ( - // x string - // y int = 1 << x - // ) - InvalidShiftCount - - // InvalidShiftOperand occurs when the shifted operand is not an integer. - // - // Example: - // var s = "hello" - // var x = s << 2 - InvalidShiftOperand - - /* exprs > chan */ - - // InvalidReceive occurs when there is a channel receive from a value that - // is either not a channel, or is a send-only channel. - // - // Example: - // func f() { - // var x = 1 - // <-x - // } - InvalidReceive - - // InvalidSend occurs when there is a channel send to a value that is not a - // channel, or is a receive-only channel. - // - // Example: - // func f() { - // var x = 1 - // x <- "hello!" - // } - InvalidSend - - /* exprs > literal */ - - // DuplicateLitKey occurs when an index is duplicated in a slice, array, or - // map literal. - // - // Example: - // var _ = []int{0:1, 0:2} - // - // Example: - // var _ = map[string]int{"a": 1, "a": 2} - DuplicateLitKey - - // MissingLitKey occurs when a map literal is missing a key expression. - // - // Example: - // var _ = map[string]int{1} - MissingLitKey - - // InvalidLitIndex occurs when the key in a key-value element of a slice or - // array literal is not an integer constant. - // - // Example: - // var i = 0 - // var x = []string{i: "world"} - InvalidLitIndex - - // OversizeArrayLit occurs when an array literal exceeds its length. - // - // Example: - // var _ = [2]int{1,2,3} - OversizeArrayLit - - // MixedStructLit occurs when a struct literal contains a mix of positional - // and named elements. - // - // Example: - // var _ = struct{i, j int}{i: 1, 2} - MixedStructLit - - // InvalidStructLit occurs when a positional struct literal has an incorrect - // number of values. - // - // Example: - // var _ = struct{i, j int}{1,2,3} - InvalidStructLit - - // MissingLitField occurs when a struct literal refers to a field that does - // not exist on the struct type. - // - // Example: - // var _ = struct{i int}{j: 2} - MissingLitField - - // DuplicateLitField occurs when a struct literal contains duplicated - // fields. - // - // Example: - // var _ = struct{i int}{i: 1, i: 2} - DuplicateLitField - - // UnexportedLitField occurs when a positional struct literal implicitly - // assigns an unexported field of an imported type. - UnexportedLitField - - // InvalidLitField occurs when a field name is not a valid identifier. - // - // Example: - // var _ = struct{i int}{1: 1} - InvalidLitField - - // UntypedLit occurs when a composite literal omits a required type - // identifier. - // - // Example: - // type outer struct{ - // inner struct { i int } - // } - // - // var _ = outer{inner: {1}} - UntypedLit - - // InvalidLit occurs when a composite literal expression does not match its - // type. - // - // Example: - // type P *struct{ - // x int - // } - // var _ = P {} - InvalidLit - - /* exprs > selector */ - - // AmbiguousSelector occurs when a selector is ambiguous. - // - // Example: - // type E1 struct { i int } - // type E2 struct { i int } - // type T struct { E1; E2 } - // - // var x T - // var _ = x.i - AmbiguousSelector - - // UndeclaredImportedName occurs when a package-qualified identifier is - // undeclared by the imported package. - // - // Example: - // import "go/types" - // - // var _ = types.NotAnActualIdentifier - UndeclaredImportedName - - // UnexportedName occurs when a selector refers to an unexported identifier - // of an imported package. - // - // Example: - // import "reflect" - // - // type _ reflect.flag - UnexportedName - - // UndeclaredName occurs when an identifier is not declared in the current - // scope. - // - // Example: - // var x T - UndeclaredName - - // MissingFieldOrMethod occurs when a selector references a field or method - // that does not exist. - // - // Example: - // type T struct {} - // - // var x = T{}.f - MissingFieldOrMethod - - /* exprs > ... */ - - // BadDotDotDotSyntax occurs when a "..." occurs in a context where it is - // not valid. - // - // Example: - // var _ = map[int][...]int{0: {}} - BadDotDotDotSyntax - - // NonVariadicDotDotDot occurs when a "..." is used on the final argument to - // a non-variadic function. - // - // Example: - // func printArgs(s []string) { - // for _, a := range s { - // println(a) - // } - // } - // - // func f() { - // s := []string{"a", "b", "c"} - // printArgs(s...) - // } - NonVariadicDotDotDot - - // MisplacedDotDotDot occurs when a "..." is used somewhere other than the - // final argument to a function call. - // - // Example: - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func f() { - // a := []int{1,2,3} - // printArgs(0, a...) - // } - MisplacedDotDotDot - - // InvalidDotDotDotOperand occurs when a "..." operator is applied to a - // single-valued operand. - // - // Example: - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func f() { - // a := 1 - // printArgs(a...) - // } - // - // Example: - // func args() (int, int) { - // return 1, 2 - // } - // - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func g() { - // printArgs(args()...) - // } - InvalidDotDotDotOperand - - // InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in - // function. - // - // Example: - // var s = []int{1, 2, 3} - // var l = len(s...) - InvalidDotDotDot - - /* exprs > built-in */ - - // UncalledBuiltin occurs when a built-in function is used as a - // function-valued expression, instead of being called. - // - // Per the spec: - // "The built-in functions do not have standard Go types, so they can only - // appear in call expressions; they cannot be used as function values." - // - // Example: - // var _ = copy - UncalledBuiltin - - // InvalidAppend occurs when append is called with a first argument that is - // not a slice. - // - // Example: - // var _ = append(1, 2) - InvalidAppend - - // InvalidCap occurs when an argument to the cap built-in function is not of - // supported type. - // - // See https://golang.org/ref/spec#Lengthand_capacity for information on - // which underlying types are supported as arguments to cap and len. - // - // Example: - // var s = 2 - // var x = cap(s) - InvalidCap - - // InvalidClose occurs when close(...) is called with an argument that is - // not of channel type, or that is a receive-only channel. - // - // Example: - // func f() { - // var x int - // close(x) - // } - InvalidClose - - // InvalidCopy occurs when the arguments are not of slice type or do not - // have compatible type. - // - // See https://golang.org/ref/spec#Appendingand_copying_slices for more - // information on the type requirements for the copy built-in. - // - // Example: - // func f() { - // var x []int - // y := []int64{1,2,3} - // copy(x, y) - // } - InvalidCopy - - // InvalidComplex occurs when the complex built-in function is called with - // arguments with incompatible types. - // - // Example: - // var _ = complex(float32(1), float64(2)) - InvalidComplex - - // InvalidDelete occurs when the delete built-in function is called with a - // first argument that is not a map. - // - // Example: - // func f() { - // m := "hello" - // delete(m, "e") - // } - InvalidDelete - - // InvalidImag occurs when the imag built-in function is called with an - // argument that does not have complex type. - // - // Example: - // var _ = imag(int(1)) - InvalidImag - - // InvalidLen occurs when an argument to the len built-in function is not of - // supported type. - // - // See https://golang.org/ref/spec#Lengthand_capacity for information on - // which underlying types are supported as arguments to cap and len. - // - // Example: - // var s = 2 - // var x = len(s) - InvalidLen - - // SwappedMakeArgs occurs when make is called with three arguments, and its - // length argument is larger than its capacity argument. - // - // Example: - // var x = make([]int, 3, 2) - SwappedMakeArgs - - // InvalidMake occurs when make is called with an unsupported type argument. - // - // See https://golang.org/ref/spec#Makingslices_maps_and_channels for - // information on the types that may be created using make. - // - // Example: - // var x = make(int) - InvalidMake - - // InvalidReal occurs when the real built-in function is called with an - // argument that does not have complex type. - // - // Example: - // var _ = real(int(1)) - InvalidReal - - /* exprs > assertion */ - - // InvalidAssert occurs when a type assertion is applied to a - // value that is not of interface type. - // - // Example: - // var x = 1 - // var _ = x.(float64) - InvalidAssert - - // ImpossibleAssert occurs for a type assertion x.(T) when the value x of - // interface cannot have dynamic type T, due to a missing or mismatching - // method on T. - // - // Example: - // type T int - // - // func (t *T) m() int { return int(*t) } - // - // type I interface { m() int } - // - // var x I - // var _ = x.(T) - ImpossibleAssert - - /* exprs > conversion */ - - // InvalidConversion occurs when the argument type cannot be converted to the - // target. - // - // See https://golang.org/ref/spec#Conversions for the rules of - // convertibility. - // - // Example: - // var x float64 - // var _ = string(x) - InvalidConversion - - // InvalidUntypedConversion occurs when an there is no valid implicit - // conversion from an untyped value satisfying the type constraints of the - // context in which it is used. - // - // Example: - // var _ = 1 + "" - InvalidUntypedConversion - - /* offsetof */ - - // BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument - // that is not a selector expression. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Offsetof(x) - BadOffsetofSyntax - - // InvalidOffsetof occurs when unsafe.Offsetof is called with a method - // selector, rather than a field selector, or when the field is embedded via - // a pointer. - // - // Per the spec: - // - // "If f is an embedded field, it must be reachable without pointer - // indirections through fields of the struct. " - // - // Example: - // import "unsafe" - // - // type T struct { f int } - // type S struct { *T } - // var s S - // var _ = unsafe.Offsetof(s.f) - // - // Example: - // import "unsafe" - // - // type S struct{} - // - // func (S) m() {} - // - // var s S - // var _ = unsafe.Offsetof(s.m) - InvalidOffsetof - - /* control flow > scope */ - - // UnusedExpr occurs when a side-effect free expression is used as a - // statement. Such a statement has no effect. - // - // Example: - // func f(i int) { - // i*i - // } - UnusedExpr - - // UnusedVar occurs when a variable is declared but unused. - // - // Example: - // func f() { - // x := 1 - // } - UnusedVar - - // MissingReturn occurs when a function with results is missing a return - // statement. - // - // Example: - // func f() int {} - MissingReturn - - // WrongResultCount occurs when a return statement returns an incorrect - // number of values. - // - // Example: - // func ReturnOne() int { - // return 1, 2 - // } - WrongResultCount - - // OutOfScopeResult occurs when the name of a value implicitly returned by - // an empty return statement is shadowed in a nested scope. - // - // Example: - // func factor(n int) (i int) { - // for i := 2; i < n; i++ { - // if n%i == 0 { - // return - // } - // } - // return 0 - // } - OutOfScopeResult - - /* control flow > if */ - - // InvalidCond occurs when an if condition is not a boolean expression. - // - // Example: - // func checkReturn(i int) { - // if i { - // panic("non-zero return") - // } - // } - InvalidCond - - /* control flow > for */ - - // InvalidPostDecl occurs when there is a declaration in a for-loop post - // statement. - // - // Example: - // func f() { - // for i := 0; i < 10; j := 0 {} - // } - InvalidPostDecl - - // InvalidChanRange occurs when a send-only channel used in a range - // expression. - // - // Example: - // func sum(c chan<- int) { - // s := 0 - // for i := range c { - // s += i - // } - // } - InvalidChanRange - - // InvalidIterVar occurs when two iteration variables are used while ranging - // over a channel. - // - // Example: - // func f(c chan int) { - // for k, v := range c { - // println(k, v) - // } - // } - InvalidIterVar - - // InvalidRangeExpr occurs when the type of a range expression is not array, - // slice, string, map, or channel. - // - // Example: - // func f(i int) { - // for j := range i { - // println(j) - // } - // } - InvalidRangeExpr - - /* control flow > switch */ - - // MisplacedBreak occurs when a break statement is not within a for, switch, - // or select statement of the innermost function definition. - // - // Example: - // func f() { - // break - // } - MisplacedBreak - - // MisplacedContinue occurs when a continue statement is not within a for - // loop of the innermost function definition. - // - // Example: - // func sumeven(n int) int { - // proceed := func() { - // continue - // } - // sum := 0 - // for i := 1; i <= n; i++ { - // if i % 2 != 0 { - // proceed() - // } - // sum += i - // } - // return sum - // } - MisplacedContinue - - // MisplacedFallthrough occurs when a fallthrough statement is not within an - // expression switch. - // - // Example: - // func typename(i interface{}) string { - // switch i.(type) { - // case int64: - // fallthrough - // case int: - // return "int" - // } - // return "unsupported" - // } - MisplacedFallthrough - - // DuplicateCase occurs when a type or expression switch has duplicate - // cases. - // - // Example: - // func printInt(i int) { - // switch i { - // case 1: - // println("one") - // case 1: - // println("One") - // } - // } - DuplicateCase - - // DuplicateDefault occurs when a type or expression switch has multiple - // default clauses. - // - // Example: - // func printInt(i int) { - // switch i { - // case 1: - // println("one") - // default: - // println("One") - // default: - // println("1") - // } - // } - DuplicateDefault - - // BadTypeKeyword occurs when a .(type) expression is used anywhere other - // than a type switch. - // - // Example: - // type I interface { - // m() - // } - // var t I - // var _ = t.(type) - BadTypeKeyword - - // InvalidTypeSwitch occurs when .(type) is used on an expression that is - // not of interface type. - // - // Example: - // func f(i int) { - // switch x := i.(type) {} - // } - InvalidTypeSwitch - - // InvalidExprSwitch occurs when a switch expression is not comparable. - // - // Example: - // func _() { - // var a struct{ _ func() } - // switch a /* ERROR cannot switch on a */ { - // } - // } - InvalidExprSwitch - - /* control flow > select */ - - // InvalidSelectCase occurs when a select case is not a channel send or - // receive. - // - // Example: - // func checkChan(c <-chan int) bool { - // select { - // case c: - // return true - // default: - // return false - // } - // } - InvalidSelectCase - - /* control flow > labels and jumps */ - - // UndeclaredLabel occurs when an undeclared label is jumped to. - // - // Example: - // func f() { - // goto L - // } - UndeclaredLabel - - // DuplicateLabel occurs when a label is declared more than once. - // - // Example: - // func f() int { - // L: - // L: - // return 1 - // } - DuplicateLabel - - // MisplacedLabel occurs when a break or continue label is not on a for, - // switch, or select statement. - // - // Example: - // func f() { - // L: - // a := []int{1,2,3} - // for _, e := range a { - // if e > 10 { - // break L - // } - // println(a) - // } - // } - MisplacedLabel - - // UnusedLabel occurs when a label is declared but not used. - // - // Example: - // func f() { - // L: - // } - UnusedLabel - - // JumpOverDecl occurs when a label jumps over a variable declaration. - // - // Example: - // func f() int { - // goto L - // x := 2 - // L: - // x++ - // return x - // } - JumpOverDecl - - // JumpIntoBlock occurs when a forward jump goes to a label inside a nested - // block. - // - // Example: - // func f(x int) { - // goto L - // if x > 0 { - // L: - // print("inside block") - // } - // } - JumpIntoBlock - - /* control flow > calls */ - - // InvalidMethodExpr occurs when a pointer method is called but the argument - // is not addressable. - // - // Example: - // type T struct {} - // - // func (*T) m() int { return 1 } - // - // var _ = T.m(T{}) - InvalidMethodExpr - - // WrongArgCount occurs when too few or too many arguments are passed by a - // function call. - // - // Example: - // func f(i int) {} - // var x = f() - WrongArgCount - - // InvalidCall occurs when an expression is called that is not of function - // type. - // - // Example: - // var x = "x" - // var y = x() - InvalidCall - - /* control flow > suspended */ - - // UnusedResults occurs when a restricted expression-only built-in function - // is suspended via go or defer. Such a suspension discards the results of - // these side-effect free built-in functions, and therefore is ineffectual. - // - // Example: - // func f(a []int) int { - // defer len(a) - // return i - // } - UnusedResults - - // InvalidDefer occurs when a deferred expression is not a function call, - // for example if the expression is a type conversion. - // - // Example: - // func f(i int) int { - // defer int32(i) - // return i - // } - InvalidDefer - - // InvalidGo occurs when a go expression is not a function call, for example - // if the expression is a type conversion. - // - // Example: - // func f(i int) int { - // go int32(i) - // return i - // } - InvalidGo - - // All codes below were added in Go 1.17. - - /* decl */ - - // BadDecl occurs when a declaration has invalid syntax. - BadDecl - - // RepeatedDecl occurs when an identifier occurs more than once on the left - // hand side of a short variable declaration. - // - // Example: - // func _() { - // x, y, y := 1, 2, 3 - // } - RepeatedDecl - - /* unsafe */ - - // InvalidUnsafeAdd occurs when unsafe.Add is called with a - // length argument that is not of integer type. - // - // Example: - // import "unsafe" - // - // var p unsafe.Pointer - // var _ = unsafe.Add(p, float64(1)) - InvalidUnsafeAdd - - // InvalidUnsafeSlice occurs when unsafe.Slice is called with a - // pointer argument that is not of pointer type or a length argument - // that is not of integer type, negative, or out of bounds. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(x, 1) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, float64(1)) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, -1) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, uint64(1) << 63) - InvalidUnsafeSlice - - // All codes below were added in Go 1.18. - - /* features */ - - // UnsupportedFeature occurs when a language feature is used that is not - // supported at this Go version. - UnsupportedFeature - - /* type params */ - - // NotAGenericType occurs when a non-generic type is used where a generic - // type is expected: in type or function instantiation. - // - // Example: - // type T int - // - // var _ T[int] - NotAGenericType - - // WrongTypeArgCount occurs when a type or function is instantiated with an - // incorrent number of type arguments, including when a generic type or - // function is used without instantiation. - // - // Errors inolving failed type inference are assigned other error codes. - // - // Example: - // type T[p any] int - // - // var _ T[int, string] - // - // Example: - // func f[T any]() {} - // - // var x = f - WrongTypeArgCount - - // CannotInferTypeArgs occurs when type or function type argument inference - // fails to infer all type arguments. - // - // Example: - // func f[T any]() {} - // - // func _() { - // f() - // } - // - // Example: - // type N[P, Q any] struct{} - // - // var _ N[int] - CannotInferTypeArgs - - // InvalidTypeArg occurs when a type argument does not satisfy its - // corresponding type parameter constraints. - // - // Example: - // type T[P ~int] struct{} - // - // var _ T[string] - InvalidTypeArg // arguments? InferenceFailed - - // InvalidInstanceCycle occurs when an invalid cycle is detected - // within the instantiation graph. - // - // Example: - // func f[T any]() { f[*T]() } - InvalidInstanceCycle - - // InvalidUnion occurs when an embedded union or approximation element is - // not valid. - // - // Example: - // type _ interface { - // ~int | interface{ m() } - // } - InvalidUnion - - // MisplacedConstraintIface occurs when a constraint-type interface is used - // outside of constraint position. - // - // Example: - // type I interface { ~int } - // - // var _ I - MisplacedConstraintIface - - // InvalidMethodTypeParams occurs when methods have type parameters. - // - // It cannot be encountered with an AST parsed using go/parser. - InvalidMethodTypeParams - - // MisplacedTypeParam occurs when a type parameter is used in a place where - // it is not permitted. - // - // Example: - // type T[P any] P - // - // Example: - // type T[P any] struct{ *P } - MisplacedTypeParam - - // InvalidUnsafeSliceData occurs when unsafe.SliceData is called with - // an argument that is not of slice type. It also occurs if it is used - // in a package compiled for a language version before go1.20. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.SliceData(x) - InvalidUnsafeSliceData - - // InvalidUnsafeString occurs when unsafe.String is called with - // a length argument that is not of integer type, negative, or - // out of bounds. It also occurs if it is used in a package - // compiled for a language version before go1.20. - // - // Example: - // import "unsafe" - // - // var b [10]byte - // var _ = unsafe.String(&b[0], -1) - InvalidUnsafeString - - // InvalidUnsafeStringData occurs if it is used in a package - // compiled for a language version before go1.20. - _ // not used anymore - -) diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go deleted file mode 100644 index 15ecf7c5..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go +++ /dev/null @@ -1,179 +0,0 @@ -// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT. - -package typesinternal - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[InvalidSyntaxTree - -1] - _ = x[Test-1] - _ = x[BlankPkgName-2] - _ = x[MismatchedPkgName-3] - _ = x[InvalidPkgUse-4] - _ = x[BadImportPath-5] - _ = x[BrokenImport-6] - _ = x[ImportCRenamed-7] - _ = x[UnusedImport-8] - _ = x[InvalidInitCycle-9] - _ = x[DuplicateDecl-10] - _ = x[InvalidDeclCycle-11] - _ = x[InvalidTypeCycle-12] - _ = x[InvalidConstInit-13] - _ = x[InvalidConstVal-14] - _ = x[InvalidConstType-15] - _ = x[UntypedNilUse-16] - _ = x[WrongAssignCount-17] - _ = x[UnassignableOperand-18] - _ = x[NoNewVar-19] - _ = x[MultiValAssignOp-20] - _ = x[InvalidIfaceAssign-21] - _ = x[InvalidChanAssign-22] - _ = x[IncompatibleAssign-23] - _ = x[UnaddressableFieldAssign-24] - _ = x[NotAType-25] - _ = x[InvalidArrayLen-26] - _ = x[BlankIfaceMethod-27] - _ = x[IncomparableMapKey-28] - _ = x[InvalidIfaceEmbed-29] - _ = x[InvalidPtrEmbed-30] - _ = x[BadRecv-31] - _ = x[InvalidRecv-32] - _ = x[DuplicateFieldAndMethod-33] - _ = x[DuplicateMethod-34] - _ = x[InvalidBlank-35] - _ = x[InvalidIota-36] - _ = x[MissingInitBody-37] - _ = x[InvalidInitSig-38] - _ = x[InvalidInitDecl-39] - _ = x[InvalidMainDecl-40] - _ = x[TooManyValues-41] - _ = x[NotAnExpr-42] - _ = x[TruncatedFloat-43] - _ = x[NumericOverflow-44] - _ = x[UndefinedOp-45] - _ = x[MismatchedTypes-46] - _ = x[DivByZero-47] - _ = x[NonNumericIncDec-48] - _ = x[UnaddressableOperand-49] - _ = x[InvalidIndirection-50] - _ = x[NonIndexableOperand-51] - _ = x[InvalidIndex-52] - _ = x[SwappedSliceIndices-53] - _ = x[NonSliceableOperand-54] - _ = x[InvalidSliceExpr-55] - _ = x[InvalidShiftCount-56] - _ = x[InvalidShiftOperand-57] - _ = x[InvalidReceive-58] - _ = x[InvalidSend-59] - _ = x[DuplicateLitKey-60] - _ = x[MissingLitKey-61] - _ = x[InvalidLitIndex-62] - _ = x[OversizeArrayLit-63] - _ = x[MixedStructLit-64] - _ = x[InvalidStructLit-65] - _ = x[MissingLitField-66] - _ = x[DuplicateLitField-67] - _ = x[UnexportedLitField-68] - _ = x[InvalidLitField-69] - _ = x[UntypedLit-70] - _ = x[InvalidLit-71] - _ = x[AmbiguousSelector-72] - _ = x[UndeclaredImportedName-73] - _ = x[UnexportedName-74] - _ = x[UndeclaredName-75] - _ = x[MissingFieldOrMethod-76] - _ = x[BadDotDotDotSyntax-77] - _ = x[NonVariadicDotDotDot-78] - _ = x[MisplacedDotDotDot-79] - _ = x[InvalidDotDotDotOperand-80] - _ = x[InvalidDotDotDot-81] - _ = x[UncalledBuiltin-82] - _ = x[InvalidAppend-83] - _ = x[InvalidCap-84] - _ = x[InvalidClose-85] - _ = x[InvalidCopy-86] - _ = x[InvalidComplex-87] - _ = x[InvalidDelete-88] - _ = x[InvalidImag-89] - _ = x[InvalidLen-90] - _ = x[SwappedMakeArgs-91] - _ = x[InvalidMake-92] - _ = x[InvalidReal-93] - _ = x[InvalidAssert-94] - _ = x[ImpossibleAssert-95] - _ = x[InvalidConversion-96] - _ = x[InvalidUntypedConversion-97] - _ = x[BadOffsetofSyntax-98] - _ = x[InvalidOffsetof-99] - _ = x[UnusedExpr-100] - _ = x[UnusedVar-101] - _ = x[MissingReturn-102] - _ = x[WrongResultCount-103] - _ = x[OutOfScopeResult-104] - _ = x[InvalidCond-105] - _ = x[InvalidPostDecl-106] - _ = x[InvalidChanRange-107] - _ = x[InvalidIterVar-108] - _ = x[InvalidRangeExpr-109] - _ = x[MisplacedBreak-110] - _ = x[MisplacedContinue-111] - _ = x[MisplacedFallthrough-112] - _ = x[DuplicateCase-113] - _ = x[DuplicateDefault-114] - _ = x[BadTypeKeyword-115] - _ = x[InvalidTypeSwitch-116] - _ = x[InvalidExprSwitch-117] - _ = x[InvalidSelectCase-118] - _ = x[UndeclaredLabel-119] - _ = x[DuplicateLabel-120] - _ = x[MisplacedLabel-121] - _ = x[UnusedLabel-122] - _ = x[JumpOverDecl-123] - _ = x[JumpIntoBlock-124] - _ = x[InvalidMethodExpr-125] - _ = x[WrongArgCount-126] - _ = x[InvalidCall-127] - _ = x[UnusedResults-128] - _ = x[InvalidDefer-129] - _ = x[InvalidGo-130] - _ = x[BadDecl-131] - _ = x[RepeatedDecl-132] - _ = x[InvalidUnsafeAdd-133] - _ = x[InvalidUnsafeSlice-134] - _ = x[UnsupportedFeature-135] - _ = x[NotAGenericType-136] - _ = x[WrongTypeArgCount-137] - _ = x[CannotInferTypeArgs-138] - _ = x[InvalidTypeArg-139] - _ = x[InvalidInstanceCycle-140] - _ = x[InvalidUnion-141] - _ = x[MisplacedConstraintIface-142] - _ = x[InvalidMethodTypeParams-143] - _ = x[MisplacedTypeParam-144] - _ = x[InvalidUnsafeSliceData-145] - _ = x[InvalidUnsafeString-146] -} - -const ( - _ErrorCode_name_0 = "InvalidSyntaxTree" - _ErrorCode_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString" -) - -var ( - _ErrorCode_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411, 428, 443, 450, 461, 484, 499, 511, 522, 537, 551, 566, 581, 594, 603, 617, 632, 643, 658, 667, 683, 703, 721, 740, 752, 771, 790, 806, 823, 842, 856, 867, 882, 895, 910, 926, 940, 956, 971, 988, 1006, 1021, 1031, 1041, 1058, 1080, 1094, 1108, 1128, 1146, 1166, 1184, 1207, 1223, 1238, 1251, 1261, 1273, 1284, 1298, 1311, 1322, 1332, 1347, 1358, 1369, 1382, 1398, 1415, 1439, 1456, 1471, 1481, 1490, 1503, 1519, 1535, 1546, 1561, 1577, 1591, 1607, 1621, 1638, 1658, 1671, 1687, 1701, 1718, 1735, 1752, 1767, 1781, 1795, 1806, 1818, 1831, 1848, 1861, 1872, 1885, 1897, 1906, 1913, 1925, 1941, 1959, 1977, 1992, 2009, 2028, 2042, 2062, 2074, 2098, 2121, 2139, 2161, 2180} -) - -func (i ErrorCode) String() string { - switch { - case i == -1: - return _ErrorCode_name_0 - case 1 <= i && i <= 146: - i -= 1 - return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]] - default: - return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go deleted file mode 100644 index ce7d4351..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package typesinternal provides access to internal go/types APIs that are not -// yet exported. -package typesinternal - -import ( - "go/token" - "go/types" - "reflect" - "unsafe" -) - -func SetUsesCgo(conf *types.Config) bool { - v := reflect.ValueOf(conf).Elem() - - f := v.FieldByName("go115UsesCgo") - if !f.IsValid() { - f = v.FieldByName("UsesCgo") - if !f.IsValid() { - return false - } - } - - addr := unsafe.Pointer(f.UnsafeAddr()) - *(*bool)(addr) = true - - return true -} - -// ReadGo116ErrorData extracts additional information from types.Error values -// generated by Go version 1.16 and later: the error code, start position, and -// end position. If all positions are valid, start <= err.Pos <= end. -// -// If the data could not be read, the final result parameter will be false. -func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) { - var data [3]int - // By coincidence all of these fields are ints, which simplifies things. - v := reflect.ValueOf(err) - for i, name := range []string{"go116code", "go116start", "go116end"} { - f := v.FieldByName(name) - if !f.IsValid() { - return 0, 0, 0, false - } - data[i] = int(f.Int()) - } - return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true -} - -var SetGoVersion = func(conf *types.Config, version string) bool { return false } diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types_118.go b/vendor/golang.org/x/tools/internal/typesinternal/types_118.go deleted file mode 100644 index a42b072a..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/types_118.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.18 -// +build go1.18 - -package typesinternal - -import ( - "go/types" -) - -func init() { - SetGoVersion = func(conf *types.Config, version string) bool { - conf.GoVersion = version - return true - } -} diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go deleted file mode 100644 index bbabcd22..00000000 --- a/vendor/golang.org/x/tools/internal/versions/gover.go +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This is a fork of internal/gover for use by x/tools until -// go1.21 and earlier are no longer supported by x/tools. - -package versions - -import "strings" - -// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]] -// The numbers are the original decimal strings to avoid integer overflows -// and since there is very little actual math. (Probably overflow doesn't matter in practice, -// but at the time this code was written, there was an existing test that used -// go1.99999999999, which does not fit in an int on 32-bit platforms. -// The "big decimal" representation avoids the problem entirely.) -type gover struct { - major string // decimal - minor string // decimal or "" - patch string // decimal or "" - kind string // "", "alpha", "beta", "rc" - pre string // decimal or "" -} - -// compare returns -1, 0, or +1 depending on whether -// x < y, x == y, or x > y, interpreted as toolchain versions. -// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21". -// Malformed versions compare less than well-formed versions and equal to each other. -// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0". -func compare(x, y string) int { - vx := parse(x) - vy := parse(y) - - if c := cmpInt(vx.major, vy.major); c != 0 { - return c - } - if c := cmpInt(vx.minor, vy.minor); c != 0 { - return c - } - if c := cmpInt(vx.patch, vy.patch); c != 0 { - return c - } - if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc - return c - } - if c := cmpInt(vx.pre, vy.pre); c != 0 { - return c - } - return 0 -} - -// lang returns the Go language version. For example, lang("1.2.3") == "1.2". -func lang(x string) string { - v := parse(x) - if v.minor == "" || v.major == "1" && v.minor == "0" { - return v.major - } - return v.major + "." + v.minor -} - -// isValid reports whether the version x is valid. -func isValid(x string) bool { - return parse(x) != gover{} -} - -// parse parses the Go version string x into a version. -// It returns the zero version if x is malformed. -func parse(x string) gover { - var v gover - - // Parse major version. - var ok bool - v.major, x, ok = cutInt(x) - if !ok { - return gover{} - } - if x == "" { - // Interpret "1" as "1.0.0". - v.minor = "0" - v.patch = "0" - return v - } - - // Parse . before minor version. - if x[0] != '.' { - return gover{} - } - - // Parse minor version. - v.minor, x, ok = cutInt(x[1:]) - if !ok { - return gover{} - } - if x == "" { - // Patch missing is same as "0" for older versions. - // Starting in Go 1.21, patch missing is different from explicit .0. - if cmpInt(v.minor, "21") < 0 { - v.patch = "0" - } - return v - } - - // Parse patch if present. - if x[0] == '.' { - v.patch, x, ok = cutInt(x[1:]) - if !ok || x != "" { - // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != ""). - // Allowing them would be a bit confusing because we already have: - // 1.21 < 1.21rc1 - // But a prerelease of a patch would have the opposite effect: - // 1.21.3rc1 < 1.21.3 - // We've never needed them before, so let's not start now. - return gover{} - } - return v - } - - // Parse prerelease. - i := 0 - for i < len(x) && (x[i] < '0' || '9' < x[i]) { - if x[i] < 'a' || 'z' < x[i] { - return gover{} - } - i++ - } - if i == 0 { - return gover{} - } - v.kind, x = x[:i], x[i:] - if x == "" { - return v - } - v.pre, x, ok = cutInt(x) - if !ok || x != "" { - return gover{} - } - - return v -} - -// cutInt scans the leading decimal number at the start of x to an integer -// and returns that value and the rest of the string. -func cutInt(x string) (n, rest string, ok bool) { - i := 0 - for i < len(x) && '0' <= x[i] && x[i] <= '9' { - i++ - } - if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero - return "", "", false - } - return x[:i], x[i:], true -} - -// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers. -// (Copied from golang.org/x/mod/semver's compareInt.) -func cmpInt(x, y string) int { - if x == y { - return 0 - } - if len(x) < len(y) { - return -1 - } - if len(x) > len(y) { - return +1 - } - if x < y { - return -1 - } else { - return +1 - } -} diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go deleted file mode 100644 index 562eef21..00000000 --- a/vendor/golang.org/x/tools/internal/versions/types.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package versions - -import ( - "go/types" -) - -// GoVersion returns the Go version of the type package. -// It returns zero if no version can be determined. -func GoVersion(pkg *types.Package) string { - // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25. - if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok { - return pkg.GoVersion() - } - return "" -} diff --git a/vendor/golang.org/x/tools/internal/versions/types_go121.go b/vendor/golang.org/x/tools/internal/versions/types_go121.go deleted file mode 100644 index a7b79207..00000000 --- a/vendor/golang.org/x/tools/internal/versions/types_go121.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.22 -// +build !go1.22 - -package versions - -import ( - "go/ast" - "go/types" -) - -// FileVersions always reports the a file's Go version as the -// zero version at this Go version. -func FileVersions(info *types.Info, file *ast.File) string { return "" } - -// InitFileVersions is a noop at this Go version. -func InitFileVersions(*types.Info) {} diff --git a/vendor/golang.org/x/tools/internal/versions/types_go122.go b/vendor/golang.org/x/tools/internal/versions/types_go122.go deleted file mode 100644 index 7b9ba89a..00000000 --- a/vendor/golang.org/x/tools/internal/versions/types_go122.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.22 -// +build go1.22 - -package versions - -import ( - "go/ast" - "go/types" -) - -// FileVersions maps a file to the file's semantic Go version. -// The reported version is the zero version if a version cannot be determined. -func FileVersions(info *types.Info, file *ast.File) string { - return info.FileVersions[file] -} - -// InitFileVersions initializes info to record Go versions for Go files. -func InitFileVersions(info *types.Info) { - info.FileVersions = make(map[*ast.File]string) -} diff --git a/vendor/golang.org/x/tools/internal/versions/versions_go121.go b/vendor/golang.org/x/tools/internal/versions/versions_go121.go deleted file mode 100644 index cf4a7d03..00000000 --- a/vendor/golang.org/x/tools/internal/versions/versions_go121.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.22 -// +build !go1.22 - -package versions - -// Lang returns the Go language version for version x. -// If x is not a valid version, Lang returns the empty string. -// For example: -// -// Lang("go1.21rc2") = "go1.21" -// Lang("go1.21.2") = "go1.21" -// Lang("go1.21") = "go1.21" -// Lang("go1") = "go1" -// Lang("bad") = "" -// Lang("1.21") = "" -func Lang(x string) string { - v := lang(stripGo(x)) - if v == "" { - return "" - } - return x[:2+len(v)] // "go"+v without allocation -} - -// Compare returns -1, 0, or +1 depending on whether -// x < y, x == y, or x > y, interpreted as Go versions. -// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". -// Invalid versions, including the empty string, compare less than -// valid versions and equal to each other. -// The language version "go1.21" compares less than the -// release candidate and eventual releases "go1.21rc1" and "go1.21.0". -// Custom toolchain suffixes are ignored during comparison: -// "go1.21.0" and "go1.21.0-bigcorp" are equal. -func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) } - -// IsValid reports whether the version x is valid. -func IsValid(x string) bool { return isValid(stripGo(x)) } - -// stripGo converts from a "go1.21" version to a "1.21" version. -// If v does not start with "go", stripGo returns the empty string (a known invalid version). -func stripGo(v string) string { - if len(v) < 2 || v[:2] != "go" { - return "" - } - return v[2:] -} diff --git a/vendor/golang.org/x/tools/internal/versions/versions_go122.go b/vendor/golang.org/x/tools/internal/versions/versions_go122.go deleted file mode 100644 index c1c1814b..00000000 --- a/vendor/golang.org/x/tools/internal/versions/versions_go122.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.22 -// +build go1.22 - -package versions - -import ( - "go/version" -) - -// Lang returns the Go language version for version x. -// If x is not a valid version, Lang returns the empty string. -// For example: -// -// Lang("go1.21rc2") = "go1.21" -// Lang("go1.21.2") = "go1.21" -// Lang("go1.21") = "go1.21" -// Lang("go1") = "go1" -// Lang("bad") = "" -// Lang("1.21") = "" -func Lang(x string) string { return version.Lang(x) } - -// Compare returns -1, 0, or +1 depending on whether -// x < y, x == y, or x > y, interpreted as Go versions. -// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". -// Invalid versions, including the empty string, compare less than -// valid versions and equal to each other. -// The language version "go1.21" compares less than the -// release candidate and eventual releases "go1.21rc1" and "go1.21.0". -// Custom toolchain suffixes are ignored during comparison: -// "go1.21.0" and "go1.21.0-bigcorp" are equal. -func Compare(x, y string) int { return version.Compare(x, y) } - -// IsValid reports whether the version x is valid. -func IsValid(x string) bool { return version.IsValid(x) } diff --git a/vendor/k8s.io/code-generator/CONTRIBUTING.md b/vendor/k8s.io/code-generator/CONTRIBUTING.md deleted file mode 100644 index 76625b7b..00000000 --- a/vendor/k8s.io/code-generator/CONTRIBUTING.md +++ /dev/null @@ -1,7 +0,0 @@ -# Contributing guidelines - -Do not open pull requests directly against this repository, they will be ignored. Instead, please open pull requests against [kubernetes/kubernetes](https://git.k8s.io/kubernetes/). Please follow the same [contributing guide](https://git.k8s.io/kubernetes/CONTRIBUTING.md) you would follow for any other pull request made to kubernetes/kubernetes. - -This repository is published from [kubernetes/kubernetes/staging/src/k8s.io/code-generator](https://git.k8s.io/kubernetes/staging/src/k8s.io/code-generator) by the [kubernetes publishing-bot](https://git.k8s.io/publishing-bot). - -Please see [Staging Directory and Publishing](https://git.k8s.io/community/contributors/devel/sig-architecture/staging.md) for more information diff --git a/vendor/k8s.io/code-generator/LICENSE b/vendor/k8s.io/code-generator/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/k8s.io/code-generator/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/vendor/k8s.io/code-generator/OWNERS b/vendor/k8s.io/code-generator/OWNERS deleted file mode 100644 index 3b87391c..00000000 --- a/vendor/k8s.io/code-generator/OWNERS +++ /dev/null @@ -1,15 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - deads2k - - wojtek-t - - sttts -reviewers: - - deads2k - - wojtek-t - - sttts -labels: - - sig/api-machinery - - area/code-generation -emeritus_approvers: - - lavalamp diff --git a/vendor/k8s.io/code-generator/README.md b/vendor/k8s.io/code-generator/README.md deleted file mode 100644 index 122868a5..00000000 --- a/vendor/k8s.io/code-generator/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# code-generator - -Golang code-generators used to implement [Kubernetes-style API types](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md). - -## Purpose - -These code-generators can be used -- in the context of [CustomResourceDefinition](https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/) to build native, versioned clients, - informers and other helpers -- in the context of [User-provider API Servers](https://github.com/kubernetes/apiserver) to build conversions between internal and versioned types, defaulters, protobuf codecs, - internal and versioned clients and informers. - -## Resources -- The example [sample controller](https://github.com/kubernetes/sample-controller) shows a code example of a controller that uses the clients, listers and informers generated by this library. -- The article [Kubernetes Deep Dive: Code Generation for CustomResources](https://cloud.redhat.com/blog/kubernetes-deep-dive-code-generation-customresources/) gives a step by step instruction on how to use this library. - -## Compatibility - -HEAD of this repo will match HEAD of k8s.io/apiserver, k8s.io/apimachinery, and k8s.io/client-go. - -## Where does it come from? - -`code-generator` is synced from https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/code-generator. -Code changes are made in that location, merged into `k8s.io/kubernetes` and later synced here. - diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/args/args.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/args/args.go deleted file mode 100644 index 78f36484..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/args/args.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "fmt" - "path" - - "github.com/spf13/pflag" - "k8s.io/gengo/args" - "k8s.io/gengo/types" - - codegenutil "k8s.io/code-generator/pkg/util" -) - -// CustomArgs is a wrapper for arguments to applyconfiguration-gen. -type CustomArgs struct { - // ExternalApplyConfigurations provides the locations of externally generated - // apply configuration types for types referenced by the go structs provided as input. - // Locations are provided as a comma separated list of .: - // entries. - // - // E.g. if a type references appsv1.Deployment, the location of its apply configuration should - // be provided: - // k8s.io/api/apps/v1.Deployment:k8s.io/client-go/applyconfigurations/apps/v1 - // - // meta/v1 types (TypeMeta and ObjectMeta) are always included and do not need to be passed in. - ExternalApplyConfigurations map[types.Name]string - - OpenAPISchemaFilePath string -} - -// NewDefaults returns default arguments for the generator. -func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { - genericArgs := args.Default().WithoutDefaultFlagParsing() - customArgs := &CustomArgs{ - ExternalApplyConfigurations: map[types.Name]string{ - // Always include TypeMeta and ObjectMeta. They are sufficient for the vast majority of use cases. - {Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "TypeMeta"}: "k8s.io/client-go/applyconfigurations/meta/v1", - {Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ObjectMeta"}: "k8s.io/client-go/applyconfigurations/meta/v1", - {Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "OwnerReference"}: "k8s.io/client-go/applyconfigurations/meta/v1", - }, - } - genericArgs.CustomArgs = customArgs - - if pkg := codegenutil.CurrentPackage(); len(pkg) != 0 { - genericArgs.OutputPackagePath = path.Join(pkg, "pkg/client/applyconfigurations") - } - - return genericArgs, customArgs -} - -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet, inputBase string) { - pflag.Var(NewExternalApplyConfigurationValue(&ca.ExternalApplyConfigurations, nil), "external-applyconfigurations", - "list of comma separated external apply configurations locations in .: form."+ - "For example: k8s.io/api/apps/v1.Deployment:k8s.io/client-go/applyconfigurations/apps/v1") - pflag.StringVar(&ca.OpenAPISchemaFilePath, "openapi-schema", "", - "path to the openapi schema containing all the types that apply configurations will be generated for") -} - -// Validate checks the given arguments. -func Validate(genericArgs *args.GeneratorArgs) error { - if len(genericArgs.OutputPackagePath) == 0 { - return fmt.Errorf("output package cannot be empty") - } - return nil -} diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/args/externaltypes.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/args/externaltypes.go deleted file mode 100644 index 0785fbea..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/args/externaltypes.go +++ /dev/null @@ -1,122 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "bytes" - "encoding/csv" - "flag" - "fmt" - "strings" - - "k8s.io/gengo/types" -) - -type externalApplyConfigurationValue struct { - externals *map[types.Name]string -} - -func NewExternalApplyConfigurationValue(externals *map[types.Name]string, def []string) *externalApplyConfigurationValue { - val := new(externalApplyConfigurationValue) - val.externals = externals - if def != nil { - if err := val.set(def); err != nil { - panic(err) - } - } - return val -} - -var _ flag.Value = &externalApplyConfigurationValue{} - -func (s *externalApplyConfigurationValue) set(vs []string) error { - for _, input := range vs { - typ, pkg, err := parseExternalMapping(input) - if err != nil { - return err - } - if _, ok := (*s.externals)[typ]; ok { - return fmt.Errorf("duplicate type found in --external-applyconfigurations: %v", typ) - } - (*s.externals)[typ] = pkg - } - - return nil -} - -func (s *externalApplyConfigurationValue) Set(val string) error { - vs, err := readAsCSV(val) - if err != nil { - return err - } - if err := s.set(vs); err != nil { - return err - } - - return nil -} - -func (s *externalApplyConfigurationValue) Type() string { - return "string" -} - -func (s *externalApplyConfigurationValue) String() string { - var strs []string - for k, v := range *s.externals { - strs = append(strs, fmt.Sprintf("%s.%s:%s", k.Package, k.Name, v)) - } - str, _ := writeAsCSV(strs) - return "[" + str + "]" -} - -func readAsCSV(val string) ([]string, error) { - if val == "" { - return []string{}, nil - } - stringReader := strings.NewReader(val) - csvReader := csv.NewReader(stringReader) - return csvReader.Read() -} - -func writeAsCSV(vals []string) (string, error) { - b := &bytes.Buffer{} - w := csv.NewWriter(b) - err := w.Write(vals) - if err != nil { - return "", err - } - w.Flush() - return strings.TrimSuffix(b.String(), "\n"), nil -} - -func parseExternalMapping(mapping string) (typ types.Name, pkg string, err error) { - parts := strings.Split(mapping, ":") - if len(parts) != 2 { - return types.Name{}, "", fmt.Errorf("expected string of the form .: but got %s", mapping) - } - packageTypeStr := parts[0] - pkg = parts[1] - // need to split on the *last* dot, since k8s.io (and other valid packages) have a dot in it - lastDot := strings.LastIndex(packageTypeStr, ".") - if lastDot == -1 || lastDot == len(packageTypeStr)-1 { - return types.Name{}, "", fmt.Errorf("expected package and type of the form . but got %s", packageTypeStr) - } - structPkg := packageTypeStr[:lastDot] - structType := packageTypeStr[lastDot+1:] - - return types.Name{Package: structPkg, Name: structType}, pkg, nil -} diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/applyconfiguration.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/applyconfiguration.go deleted file mode 100644 index 8e02bb23..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/applyconfiguration.go +++ /dev/null @@ -1,423 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - "k8s.io/klog/v2" - - "k8s.io/code-generator/cmd/client-gen/generators/util" - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" -) - -// applyConfigurationGenerator produces apply configurations for a given GroupVersion and type. -type applyConfigurationGenerator struct { - generator.DefaultGen - outputPackage string - localPackage types.Name - groupVersion clientgentypes.GroupVersion - applyConfig applyConfig - imports namer.ImportTracker - refGraph refGraph - openAPIType *string // if absent, extraction function cannot be generated -} - -var _ generator.Generator = &applyConfigurationGenerator{} - -func (g *applyConfigurationGenerator) Filter(_ *generator.Context, t *types.Type) bool { - return t == g.applyConfig.Type -} - -func (g *applyConfigurationGenerator) Namers(*generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.localPackage.Package, g.imports), - "singularKind": namer.NewPublicNamer(0), - } -} - -func (g *applyConfigurationGenerator) Imports(*generator.Context) (imports []string) { - return g.imports.ImportLines() -} - -// TypeParams provides a struct that an apply configuration -// is generated for as well as the apply configuration details -// and types referenced by the struct. -type TypeParams struct { - Struct *types.Type - ApplyConfig applyConfig - Tags util.Tags - APIVersion string - ExtractInto *types.Type - ParserFunc *types.Type - OpenAPIType *string -} - -type memberParams struct { - TypeParams - Member types.Member - MemberType *types.Type - JSONTags JSONTags - ArgType *types.Type // only set for maps and slices - EmbeddedIn *memberParams // parent embedded member, if any -} - -func (g *applyConfigurationGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - klog.V(5).Infof("processing type %v", t) - typeParams := TypeParams{ - Struct: t, - ApplyConfig: g.applyConfig, - Tags: genclientTags(t), - APIVersion: g.groupVersion.ToAPIVersion(), - ExtractInto: extractInto, - ParserFunc: types.Ref(g.outputPackage+"/internal", "Parser"), - OpenAPIType: g.openAPIType, - } - - g.generateStruct(sw, typeParams) - - if typeParams.Tags.GenerateClient { - if typeParams.Tags.NonNamespaced { - sw.Do(clientgenTypeConstructorNonNamespaced, typeParams) - } else { - sw.Do(clientgenTypeConstructorNamespaced, typeParams) - } - if typeParams.OpenAPIType != nil { - g.generateClientgenExtract(sw, typeParams, !typeParams.Tags.NoStatus) - } - } else { - if hasTypeMetaField(t) { - sw.Do(constructorWithTypeMeta, typeParams) - } else { - sw.Do(constructor, typeParams) - } - } - g.generateWithFuncs(t, typeParams, sw, nil) - return sw.Error() -} - -func hasTypeMetaField(t *types.Type) bool { - for _, member := range t.Members { - if typeMeta.Name == member.Type.Name && member.Embedded { - return true - } - } - return false -} - -func blocklisted(t *types.Type, member types.Member) bool { - if objectMeta.Name == t.Name && member.Name == "ManagedFields" { - return true - } - if objectMeta.Name == t.Name && member.Name == "SelfLink" { - return true - } - // Hide any fields which are en route to deletion. - if strings.HasPrefix(member.Name, "ZZZ_") { - return true - } - return false -} - -func (g *applyConfigurationGenerator) generateWithFuncs(t *types.Type, typeParams TypeParams, sw *generator.SnippetWriter, embed *memberParams) { - for _, member := range t.Members { - if blocklisted(t, member) { - continue - } - memberType := g.refGraph.applyConfigForType(member.Type) - if g.refGraph.isApplyConfig(member.Type) { - memberType = &types.Type{Kind: types.Pointer, Elem: memberType} - } - if jsonTags, ok := lookupJSONTags(member); ok { - memberParams := memberParams{ - TypeParams: typeParams, - Member: member, - MemberType: memberType, - JSONTags: jsonTags, - EmbeddedIn: embed, - } - if memberParams.Member.Embedded { - g.generateWithFuncs(member.Type, typeParams, sw, &memberParams) - if !jsonTags.inline { - // non-inlined embeds are nillable and need a "ensure exists" utility function - sw.Do(ensureEmbedExists, memberParams) - } - continue - } - - // For slices where the items are generated apply configuration types, accept varargs of - // pointers of the type as "with" function arguments so the "with" function can be used like so: - // WithFoos(Foo().WithName("x"), Foo().WithName("y")) - if t := deref(member.Type); t.Kind == types.Slice && g.refGraph.isApplyConfig(t.Elem) { - memberParams.ArgType = &types.Type{Kind: types.Pointer, Elem: memberType.Elem} - g.generateMemberWithForSlice(sw, member, memberParams) - continue - } - // Note: There are no maps where the values are generated apply configurations (because - // associative lists are used instead). So if a type like this is ever introduced, the - // default "with" function generator will produce a working (but not entirely convenient "with" function) - // that would be used like so: - // WithMap(map[string]FooApplyConfiguration{*Foo().WithName("x")}) - - switch memberParams.Member.Type.Kind { - case types.Slice: - memberParams.ArgType = memberType.Elem - g.generateMemberWithForSlice(sw, member, memberParams) - case types.Map: - g.generateMemberWithForMap(sw, memberParams) - default: - g.generateMemberWith(sw, memberParams) - } - } - } -} - -func (g *applyConfigurationGenerator) generateStruct(sw *generator.SnippetWriter, typeParams TypeParams) { - sw.Do("// $.ApplyConfig.ApplyConfiguration|public$ represents an declarative configuration of the $.ApplyConfig.Type|public$ type for use\n", typeParams) - sw.Do("// with apply.\n", typeParams) - sw.Do("type $.ApplyConfig.ApplyConfiguration|public$ struct {\n", typeParams) - for _, structMember := range typeParams.Struct.Members { - if blocklisted(typeParams.Struct, structMember) { - continue - } - if structMemberTags, ok := lookupJSONTags(structMember); ok { - if !structMemberTags.inline { - structMemberTags.omitempty = true - } - params := memberParams{ - TypeParams: typeParams, - Member: structMember, - MemberType: g.refGraph.applyConfigForType(structMember.Type), - JSONTags: structMemberTags, - } - if structMember.Embedded { - if structMemberTags.inline { - sw.Do("$.MemberType|raw$ `json:\"$.JSONTags$\"`\n", params) - } else { - sw.Do("*$.MemberType|raw$ `json:\"$.JSONTags$\"`\n", params) - } - } else if isNillable(structMember.Type) { - sw.Do("$.Member.Name$ $.MemberType|raw$ `json:\"$.JSONTags$\"`\n", params) - } else { - sw.Do("$.Member.Name$ *$.MemberType|raw$ `json:\"$.JSONTags$\"`\n", params) - } - } - } - sw.Do("}\n", typeParams) -} - -func deref(t *types.Type) *types.Type { - for t.Kind == types.Pointer { - t = t.Elem - } - return t -} - -func isNillable(t *types.Type) bool { - return t.Kind == types.Slice || t.Kind == types.Map -} - -func (g *applyConfigurationGenerator) generateMemberWith(sw *generator.SnippetWriter, memberParams memberParams) { - sw.Do("// With$.Member.Name$ sets the $.Member.Name$ field in the declarative configuration to the given value\n", memberParams) - sw.Do("// and returns the receiver, so that objects can be built by chaining \"With\" function invocations.\n", memberParams) - sw.Do("// If called multiple times, the $.Member.Name$ field is set to the value of the last call.\n", memberParams) - sw.Do("func (b *$.ApplyConfig.ApplyConfiguration|public$) With$.Member.Name$(value $.MemberType|raw$) *$.ApplyConfig.ApplyConfiguration|public$ {\n", memberParams) - g.ensureEnbedExistsIfApplicable(sw, memberParams) - if g.refGraph.isApplyConfig(memberParams.Member.Type) || isNillable(memberParams.Member.Type) { - sw.Do("b.$.Member.Name$ = value\n", memberParams) - } else { - sw.Do("b.$.Member.Name$ = &value\n", memberParams) - } - sw.Do(" return b\n", memberParams) - sw.Do("}\n", memberParams) -} - -func (g *applyConfigurationGenerator) generateMemberWithForSlice(sw *generator.SnippetWriter, member types.Member, memberParams memberParams) { - memberIsPointerToSlice := member.Type.Kind == types.Pointer - if memberIsPointerToSlice { - sw.Do(ensureNonEmbedSliceExists, memberParams) - } - - sw.Do("// With$.Member.Name$ adds the given value to the $.Member.Name$ field in the declarative configuration\n", memberParams) - sw.Do("// and returns the receiver, so that objects can be build by chaining \"With\" function invocations.\n", memberParams) - sw.Do("// If called multiple times, values provided by each call will be appended to the $.Member.Name$ field.\n", memberParams) - sw.Do("func (b *$.ApplyConfig.ApplyConfiguration|public$) With$.Member.Name$(values ...$.ArgType|raw$) *$.ApplyConfig.ApplyConfiguration|public$ {\n", memberParams) - g.ensureEnbedExistsIfApplicable(sw, memberParams) - - if memberIsPointerToSlice { - sw.Do("b.ensure$.MemberType.Elem|public$Exists()\n", memberParams) - } - - sw.Do(" for i := range values {\n", memberParams) - if memberParams.ArgType.Kind == types.Pointer { - sw.Do("if values[i] == nil {\n", memberParams) - sw.Do(" panic(\"nil value passed to With$.Member.Name$\")\n", memberParams) - sw.Do("}\n", memberParams) - - if memberIsPointerToSlice { - sw.Do("*b.$.Member.Name$ = append(*b.$.Member.Name$, *values[i])\n", memberParams) - } else { - sw.Do("b.$.Member.Name$ = append(b.$.Member.Name$, *values[i])\n", memberParams) - } - } else { - if memberIsPointerToSlice { - sw.Do("*b.$.Member.Name$ = append(*b.$.Member.Name$, values[i])\n", memberParams) - } else { - sw.Do("b.$.Member.Name$ = append(b.$.Member.Name$, values[i])\n", memberParams) - } - } - sw.Do(" }\n", memberParams) - sw.Do(" return b\n", memberParams) - sw.Do("}\n", memberParams) -} - -func (g *applyConfigurationGenerator) generateMemberWithForMap(sw *generator.SnippetWriter, memberParams memberParams) { - sw.Do("// With$.Member.Name$ puts the entries into the $.Member.Name$ field in the declarative configuration\n", memberParams) - sw.Do("// and returns the receiver, so that objects can be build by chaining \"With\" function invocations.\n", memberParams) - sw.Do("// If called multiple times, the entries provided by each call will be put on the $.Member.Name$ field,\n", memberParams) - sw.Do("// overwriting an existing map entries in $.Member.Name$ field with the same key.\n", memberParams) - sw.Do("func (b *$.ApplyConfig.ApplyConfiguration|public$) With$.Member.Name$(entries $.MemberType|raw$) *$.ApplyConfig.ApplyConfiguration|public$ {\n", memberParams) - g.ensureEnbedExistsIfApplicable(sw, memberParams) - sw.Do(" if b.$.Member.Name$ == nil && len(entries) > 0 {\n", memberParams) - sw.Do(" b.$.Member.Name$ = make($.MemberType|raw$, len(entries))\n", memberParams) - sw.Do(" }\n", memberParams) - sw.Do(" for k, v := range entries {\n", memberParams) - sw.Do(" b.$.Member.Name$[k] = v\n", memberParams) - sw.Do(" }\n", memberParams) - sw.Do(" return b\n", memberParams) - sw.Do("}\n", memberParams) -} - -func (g *applyConfigurationGenerator) ensureEnbedExistsIfApplicable(sw *generator.SnippetWriter, memberParams memberParams) { - // Embedded types that are not inlined must be nillable so they are not included in the apply configuration - // when all their fields are omitted. - if memberParams.EmbeddedIn != nil && !memberParams.EmbeddedIn.JSONTags.inline { - sw.Do("b.ensure$.MemberType.Elem|public$Exists()\n", memberParams.EmbeddedIn) - } -} - -var ensureEmbedExists = ` -func (b *$.ApplyConfig.ApplyConfiguration|public$) ensure$.MemberType.Elem|public$Exists() { - if b.$.MemberType.Elem|public$ == nil { - b.$.MemberType.Elem|public$ = &$.MemberType.Elem|raw${} - } -} -` - -var ensureNonEmbedSliceExists = ` -func (b *$.ApplyConfig.ApplyConfiguration|public$) ensure$.MemberType.Elem|public$Exists() { - if b.$.Member.Name$ == nil { - b.$.Member.Name$ = &[]$.MemberType.Elem|raw${} - } -} -` - -var clientgenTypeConstructorNamespaced = ` -// $.ApplyConfig.Type|public$ constructs an declarative configuration of the $.ApplyConfig.Type|public$ type for use with -// apply. -func $.ApplyConfig.Type|public$(name, namespace string) *$.ApplyConfig.ApplyConfiguration|public$ { - b := &$.ApplyConfig.ApplyConfiguration|public${} - b.WithName(name) - b.WithNamespace(namespace) - b.WithKind("$.ApplyConfig.Type|singularKind$") - b.WithAPIVersion("$.APIVersion$") - return b -} -` - -var clientgenTypeConstructorNonNamespaced = ` -// $.ApplyConfig.Type|public$ constructs an declarative configuration of the $.ApplyConfig.Type|public$ type for use with -// apply. -func $.ApplyConfig.Type|public$(name string) *$.ApplyConfig.ApplyConfiguration|public$ { - b := &$.ApplyConfig.ApplyConfiguration|public${} - b.WithName(name) - b.WithKind("$.ApplyConfig.Type|singularKind$") - b.WithAPIVersion("$.APIVersion$") - return b -} -` - -var constructorWithTypeMeta = ` -// $.ApplyConfig.ApplyConfiguration|public$ constructs an declarative configuration of the $.ApplyConfig.Type|public$ type for use with -// apply. -func $.ApplyConfig.Type|public$() *$.ApplyConfig.ApplyConfiguration|public$ { - b := &$.ApplyConfig.ApplyConfiguration|public${} - b.WithKind("$.ApplyConfig.Type|singularKind$") - b.WithAPIVersion("$.APIVersion$") - return b -} -` - -var constructor = ` -// $.ApplyConfig.ApplyConfiguration|public$ constructs an declarative configuration of the $.ApplyConfig.Type|public$ type for use with -// apply. -func $.ApplyConfig.Type|public$() *$.ApplyConfig.ApplyConfiguration|public$ { - return &$.ApplyConfig.ApplyConfiguration|public${} -} -` - -func (g *applyConfigurationGenerator) generateClientgenExtract(sw *generator.SnippetWriter, typeParams TypeParams, includeStatus bool) { - sw.Do(` -// Extract$.ApplyConfig.Type|public$ extracts the applied configuration owned by fieldManager from -// $.Struct|private$. If no managedFields are found in $.Struct|private$ for fieldManager, a -// $.ApplyConfig.ApplyConfiguration|public$ is returned with only the Name, Namespace (if applicable), -// APIVersion and Kind populated. It is possible that no managed fields were found for because other -// field managers have taken ownership of all the fields previously owned by fieldManager, or because -// the fieldManager never owned fields any fields. -// $.Struct|private$ must be a unmodified $.Struct|public$ API object that was retrieved from the Kubernetes API. -// Extract$.ApplyConfig.Type|public$ provides a way to perform a extract/modify-in-place/apply workflow. -// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously -// applied if another fieldManager has updated or force applied any of the previously applied fields. -// Experimental! -func Extract$.ApplyConfig.Type|public$($.Struct|private$ *$.Struct|raw$, fieldManager string) (*$.ApplyConfig.ApplyConfiguration|public$, error) { - return extract$.ApplyConfig.Type|public$($.Struct|private$, fieldManager, "") -}`, typeParams) - if includeStatus { - sw.Do(` -// Extract$.ApplyConfig.Type|public$Status is the same as Extract$.ApplyConfig.Type|public$ except -// that it extracts the status subresource applied configuration. -// Experimental! -func Extract$.ApplyConfig.Type|public$Status($.Struct|private$ *$.Struct|raw$, fieldManager string) (*$.ApplyConfig.ApplyConfiguration|public$, error) { - return extract$.ApplyConfig.Type|public$($.Struct|private$, fieldManager, "status") -} -`, typeParams) - } - sw.Do(` -func extract$.ApplyConfig.Type|public$($.Struct|private$ *$.Struct|raw$, fieldManager string, subresource string) (*$.ApplyConfig.ApplyConfiguration|public$, error) { - b := &$.ApplyConfig.ApplyConfiguration|public${} - err := $.ExtractInto|raw$($.Struct|private$, $.ParserFunc|raw$().Type("$.OpenAPIType$"), fieldManager, b, subresource) - if err != nil { - return nil, err - } - b.WithName($.Struct|private$.Name) -`, typeParams) - if !typeParams.Tags.NonNamespaced { - sw.Do("b.WithNamespace($.Struct|private$.Namespace)\n", typeParams) - } - sw.Do(` - b.WithKind("$.ApplyConfig.Type|singularKind$") - b.WithAPIVersion("$.APIVersion$") - return b, nil -} -`, typeParams) -} diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/internal.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/internal.go deleted file mode 100644 index 2871b9d7..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/internal.go +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - - "gopkg.in/yaml.v2" - - "k8s.io/kube-openapi/pkg/schemaconv" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// utilGenerator generates the ForKind() utility function. -type internalGenerator struct { - generator.DefaultGen - outputPackage string - imports namer.ImportTracker - typeModels *typeModels - filtered bool -} - -var _ generator.Generator = &internalGenerator{} - -func (g *internalGenerator) Filter(*generator.Context, *types.Type) bool { - // generate file exactly once - if !g.filtered { - g.filtered = true - return true - } - return false -} - -func (g *internalGenerator) Namers(*generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - "singularKind": namer.NewPublicNamer(0), - } -} - -func (g *internalGenerator) Imports(*generator.Context) (imports []string) { - return g.imports.ImportLines() -} - -func (g *internalGenerator) GenerateType(c *generator.Context, _ *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "{{", "}}") - - schema, err := schemaconv.ToSchema(g.typeModels.models) - if err != nil { - return err - } - schemaYAML, err := yaml.Marshal(schema) - if err != nil { - return err - } - sw.Do(schemaBlock, map[string]interface{}{ - "schemaYAML": string(schemaYAML), - "smdParser": smdParser, - "smdNewParser": smdNewParser, - "yamlObject": yamlObject, - "yamlUnmarshal": yamlUnmarshal, - }) - - return sw.Error() -} - -var schemaBlock = ` -func Parser() *{{.smdParser|raw}} { - parserOnce.Do(func() { - var err error - parser, err = {{.smdNewParser|raw}}(schemaYAML) - if err != nil { - panic(fmt.Sprintf("Failed to parse schema: %v", err)) - } - }) - return parser -} - -var parserOnce sync.Once -var parser *{{.smdParser|raw}} -var schemaYAML = {{.yamlObject|raw}}(` + "`{{.schemaYAML}}`" + `) -` diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/jsontagutil.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/jsontagutil.go deleted file mode 100644 index 2a643290..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/jsontagutil.go +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "reflect" - "strings" - - "k8s.io/gengo/types" -) - -// TODO: This implements the same functionality as https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go#L236 -// but is based on the highly efficient approach from https://golang.org/src/encoding/json/encode.go - -// JSONTags represents a go json field tag. -type JSONTags struct { - name string - omit bool - inline bool - omitempty bool -} - -func (t JSONTags) String() string { - var tag string - if !t.inline { - tag += t.name - } - if t.omitempty { - tag += ",omitempty" - } - if t.inline { - tag += ",inline" - } - return tag -} - -func lookupJSONTags(m types.Member) (JSONTags, bool) { - tag := reflect.StructTag(m.Tags).Get("json") - if tag == "" || tag == "-" { - return JSONTags{}, false - } - name, opts := parseTag(tag) - if name == "" { - name = m.Name - } - return JSONTags{ - name: name, - omit: false, - inline: opts.Contains("inline"), - omitempty: opts.Contains("omitempty"), - }, true -} - -type tagOptions string - -// parseTag splits a struct field's json tag into its name and -// comma-separated options. -func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, "" -} - -// Contains reports whether a comma-separated listAlias of options -// contains a particular substr flag. substr must be surrounded by a -// string boundary or commas. -func (o tagOptions) Contains(optionName string) bool { - if len(o) == 0 { - return false - } - s := string(o) - for s != "" { - var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } - if s == optionName { - return true - } - s = next - } - return false -} diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/openapi.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/openapi.go deleted file mode 100644 index 00d119dd..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/openapi.go +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "encoding/json" - "fmt" - "os" - "strings" - - openapiv2 "github.com/google/gnostic-models/openapiv2" - "k8s.io/gengo/types" - utilproto "k8s.io/kube-openapi/pkg/util/proto" - "k8s.io/kube-openapi/pkg/validation/spec" -) - -type typeModels struct { - models utilproto.Models - gvkToOpenAPIType map[gvk]string -} - -type gvk struct { - group, version, kind string -} - -func newTypeModels(openAPISchemaFilePath string, pkgTypes map[string]*types.Package) (*typeModels, error) { - if len(openAPISchemaFilePath) == 0 { - return emptyModels, nil // No Extract() functions will be generated. - } - - rawOpenAPISchema, err := os.ReadFile(openAPISchemaFilePath) - if err != nil { - return nil, fmt.Errorf("failed to read openapi-schema file: %w", err) - } - - // Read in the provided openAPI schema. - openAPISchema := &spec.Swagger{} - err = json.Unmarshal(rawOpenAPISchema, openAPISchema) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal typeModels JSON: %w", err) - } - - // Build a mapping from openAPI type name to GVK. - // Find the root types needed by by client-go for apply. - gvkToOpenAPIType := map[gvk]string{} - rootDefs := map[string]spec.Schema{} - for _, p := range pkgTypes { - gv := groupVersion(p) - for _, t := range p.Types { - tags := genclientTags(t) - hasApply := tags.HasVerb("apply") || tags.HasVerb("applyStatus") - if tags.GenerateClient && hasApply { - openAPIType := friendlyName(typeName(t)) - gvk := gvk{ - group: gv.Group.String(), - version: gv.Version.String(), - kind: t.Name.Name, - } - rootDefs[openAPIType] = openAPISchema.Definitions[openAPIType] - gvkToOpenAPIType[gvk] = openAPIType - } - } - } - - // Trim the schema down to just the types needed by client-go for apply. - requiredDefs := make(map[string]spec.Schema) - for name, def := range rootDefs { - requiredDefs[name] = def - findReferenced(&def, openAPISchema.Definitions, requiredDefs) - } - openAPISchema.Definitions = requiredDefs - - // Convert the openAPI schema to the models format and validate it. - models, err := toValidatedModels(openAPISchema) - if err != nil { - return nil, err - } - return &typeModels{models: models, gvkToOpenAPIType: gvkToOpenAPIType}, nil -} - -var emptyModels = &typeModels{ - models: &utilproto.Definitions{}, - gvkToOpenAPIType: map[gvk]string{}, -} - -func toValidatedModels(openAPISchema *spec.Swagger) (utilproto.Models, error) { - // openapi_v2.ParseDocument only accepts a []byte of the JSON or YAML file to be parsed. - // so we do an inefficient marshal back to json and then read it back in as yaml - // but get the benefit of running the models through utilproto.NewOpenAPIData to - // validate all the references between types - rawMinimalOpenAPISchema, err := json.Marshal(openAPISchema) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal openAPI as JSON: %w", err) - } - - document, err := openapiv2.ParseDocument(rawMinimalOpenAPISchema) - if err != nil { - return nil, fmt.Errorf("failed to parse OpenAPI document for file: %w", err) - } - // Construct the models and validate all references are valid. - models, err := utilproto.NewOpenAPIData(document) - if err != nil { - return nil, fmt.Errorf("failed to create OpenAPI models for file: %w", err) - } - return models, nil -} - -// findReferenced recursively finds all schemas referenced from the given def. -// toValidatedModels makes sure no references get missed. -func findReferenced(def *spec.Schema, allSchemas, referencedOut map[string]spec.Schema) { - // follow $ref, if any - refPtr := def.Ref.GetPointer() - if refPtr != nil && !refPtr.IsEmpty() { - name := refPtr.String() - if !strings.HasPrefix(name, "/definitions/") { - return - } - name = strings.TrimPrefix(name, "/definitions/") - schema, ok := allSchemas[name] - if !ok { - panic(fmt.Sprintf("allSchemas schema is missing referenced type: %s", name)) - } - if _, ok := referencedOut[name]; !ok { - referencedOut[name] = schema - findReferenced(&schema, allSchemas, referencedOut) - } - } - - // follow any nested schemas - if def.Items != nil { - if def.Items.Schema != nil { - findReferenced(def.Items.Schema, allSchemas, referencedOut) - } - for _, item := range def.Items.Schemas { - findReferenced(&item, allSchemas, referencedOut) - } - } - if def.AllOf != nil { - for _, s := range def.AllOf { - findReferenced(&s, allSchemas, referencedOut) - } - } - if def.AnyOf != nil { - for _, s := range def.AnyOf { - findReferenced(&s, allSchemas, referencedOut) - } - } - if def.OneOf != nil { - for _, s := range def.OneOf { - findReferenced(&s, allSchemas, referencedOut) - } - } - if def.Not != nil { - findReferenced(def.Not, allSchemas, referencedOut) - } - if def.Properties != nil { - for _, prop := range def.Properties { - findReferenced(&prop, allSchemas, referencedOut) - } - } - if def.AdditionalProperties != nil && def.AdditionalProperties.Schema != nil { - findReferenced(def.AdditionalProperties.Schema, allSchemas, referencedOut) - } - if def.PatternProperties != nil { - for _, s := range def.PatternProperties { - findReferenced(&s, allSchemas, referencedOut) - } - } - if def.Dependencies != nil { - for _, d := range def.Dependencies { - if d.Schema != nil { - findReferenced(d.Schema, allSchemas, referencedOut) - } - } - } - if def.AdditionalItems != nil && def.AdditionalItems.Schema != nil { - findReferenced(def.AdditionalItems.Schema, allSchemas, referencedOut) - } - if def.Definitions != nil { - for _, s := range def.Definitions { - findReferenced(&s, allSchemas, referencedOut) - } - } -} diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/packages.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/packages.go deleted file mode 100644 index bfeffda5..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/packages.go +++ /dev/null @@ -1,297 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "path" - "path/filepath" - "sort" - "strings" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - "k8s.io/klog/v2" - - applygenargs "k8s.io/code-generator/cmd/applyconfiguration-gen/args" - "k8s.io/code-generator/cmd/client-gen/generators/util" - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" -) - -const ( - // ApplyConfigurationTypeSuffix is the suffix of generated apply configuration types. - ApplyConfigurationTypeSuffix = "ApplyConfiguration" -) - -// NameSystems returns the name system used by the generators in this package. -func NameSystems() namer.NameSystems { - return namer.NameSystems{ - "public": namer.NewPublicNamer(0), - "private": namer.NewPrivateNamer(0), - "raw": namer.NewRawNamer("", nil), - } -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -// Packages makes the client package definition. -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - pkgTypes := packageTypesForInputDirs(context, arguments.InputDirs, arguments.OutputPackagePath) - customArgs := arguments.CustomArgs.(*applygenargs.CustomArgs) - initialTypes := customArgs.ExternalApplyConfigurations - refs := refGraphForReachableTypes(context.Universe, pkgTypes, initialTypes) - typeModels, err := newTypeModels(customArgs.OpenAPISchemaFilePath, pkgTypes) - if err != nil { - klog.Fatalf("Failed build type models from typeModels %s: %v", customArgs.OpenAPISchemaFilePath, err) - } - - groupVersions := make(map[string]clientgentypes.GroupVersions) - groupGoNames := make(map[string]string) - applyConfigsForGroupVersion := make(map[clientgentypes.GroupVersion][]applyConfig) - - var packageList generator.Packages - for pkg, p := range pkgTypes { - gv := groupVersion(p) - - pkgType := types.Name{Name: gv.Group.PackageName(), Package: pkg} - - var toGenerate []applyConfig - for _, t := range p.Types { - // If we don't have an ObjectMeta field, we lack the information required to make the Apply or ApplyStatus call - // to the kube-apiserver, so we don't need to generate the type at all - clientTags := genclientTags(t) - if clientTags.GenerateClient && !hasObjectMetaField(t) { - klog.V(5).Infof("skipping type %v because does not have ObjectMeta", t) - continue - } - if typePkg, ok := refs[t.Name]; ok { - toGenerate = append(toGenerate, applyConfig{ - Type: t, - ApplyConfiguration: types.Ref(typePkg, t.Name.Name+ApplyConfigurationTypeSuffix), - }) - } - } - if len(toGenerate) == 0 { - continue // Don't generate empty packages - } - sort.Sort(applyConfigSort(toGenerate)) - - // generate the apply configurations - packageList = append(packageList, generatorForApplyConfigurationsPackage(arguments.OutputPackagePath, boilerplate, pkgType, gv, toGenerate, refs, typeModels)) - - // group all the generated apply configurations by gv so ForKind() can be generated - groupPackageName := gv.Group.NonEmpty() - groupVersionsEntry, ok := groupVersions[groupPackageName] - if !ok { - groupVersionsEntry = clientgentypes.GroupVersions{ - PackageName: groupPackageName, - Group: gv.Group, - } - } - groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, clientgentypes.PackageVersion{ - Version: gv.Version, - Package: path.Clean(p.Path), - }) - - groupGoNames[groupPackageName] = goName(gv, p) - applyConfigsForGroupVersion[gv] = toGenerate - groupVersions[groupPackageName] = groupVersionsEntry - } - - // generate ForKind() utility function - packageList = append(packageList, generatorForUtils(arguments.OutputPackagePath, boilerplate, groupVersions, applyConfigsForGroupVersion, groupGoNames)) - // generate internal embedded schema, required for generated Extract functions - packageList = append(packageList, generatorForInternal(filepath.Join(arguments.OutputPackagePath, "internal"), boilerplate, typeModels)) - - return packageList -} - -func friendlyName(name string) string { - nameParts := strings.Split(name, "/") - // Reverse first part. e.g., io.k8s... instead of k8s.io... - if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") { - parts := strings.Split(nameParts[0], ".") - for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 { - parts[i], parts[j] = parts[j], parts[i] - } - nameParts[0] = strings.Join(parts, ".") - } - return strings.Join(nameParts, ".") -} - -func typeName(t *types.Type) string { - typePackage := t.Name.Package - if strings.Contains(typePackage, "/vendor/") { - typePackage = typePackage[strings.Index(typePackage, "/vendor/")+len("/vendor/"):] - } - return fmt.Sprintf("%s.%s", typePackage, t.Name.Name) -} - -func generatorForApplyConfigurationsPackage(outputPackagePath string, boilerplate []byte, packageName types.Name, gv clientgentypes.GroupVersion, typesToGenerate []applyConfig, refs refGraph, models *typeModels) *generator.DefaultPackage { - return &generator.DefaultPackage{ - PackageName: gv.Version.PackageName(), - PackagePath: packageName.Package, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - for _, toGenerate := range typesToGenerate { - var openAPIType *string - gvk := gvk{ - group: gv.Group.String(), - version: gv.Version.String(), - kind: toGenerate.Type.Name.Name, - } - if v, ok := models.gvkToOpenAPIType[gvk]; ok { - openAPIType = &v - } - - generators = append(generators, &applyConfigurationGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: strings.ToLower(toGenerate.Type.Name.Name), - }, - outputPackage: outputPackagePath, - localPackage: packageName, - groupVersion: gv, - applyConfig: toGenerate, - imports: generator.NewImportTracker(), - refGraph: refs, - openAPIType: openAPIType, - }) - } - return generators - }, - } -} - -func generatorForUtils(outPackagePath string, boilerplate []byte, groupVersions map[string]clientgentypes.GroupVersions, applyConfigsForGroupVersion map[clientgentypes.GroupVersion][]applyConfig, groupGoNames map[string]string) *generator.DefaultPackage { - return &generator.DefaultPackage{ - PackageName: filepath.Base(outPackagePath), - PackagePath: outPackagePath, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = append(generators, &utilGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: "utils", - }, - outputPackage: outPackagePath, - imports: generator.NewImportTracker(), - groupVersions: groupVersions, - typesForGroupVersion: applyConfigsForGroupVersion, - groupGoNames: groupGoNames, - }) - return generators - }, - } -} - -func generatorForInternal(outPackagePath string, boilerplate []byte, models *typeModels) *generator.DefaultPackage { - return &generator.DefaultPackage{ - PackageName: filepath.Base(outPackagePath), - PackagePath: outPackagePath, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = append(generators, &internalGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: "internal", - }, - outputPackage: outPackagePath, - imports: generator.NewImportTracker(), - typeModels: models, - }) - return generators - }, - } -} - -func goName(gv clientgentypes.GroupVersion, p *types.Package) string { - goName := namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0]) - if override := types.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil { - goName = namer.IC(override[0]) - } - return goName -} - -func packageTypesForInputDirs(context *generator.Context, inputDirs []string, outputPath string) map[string]*types.Package { - pkgTypes := map[string]*types.Package{} - for _, inputDir := range inputDirs { - p := context.Universe.Package(inputDir) - internal := isInternalPackage(p) - if internal { - klog.Warningf("Skipping internal package: %s", p.Path) - continue - } - // This is how the client generator finds the package we are creating. It uses the API package name, not the group name. - // This matches the approach of the client-gen, so the two generator can work together. - // For example, if openshift/api/cloudnetwork/v1 contains an apigroup cloud.network.openshift.io, the client-gen - // builds a package called cloudnetwork/v1 to contain it. This change makes the applyconfiguration-gen use the same. - _, gvPackageString := util.ParsePathGroupVersion(p.Path) - pkg := filepath.Join(outputPath, strings.ToLower(gvPackageString)) - pkgTypes[pkg] = p - } - return pkgTypes -} - -func groupVersion(p *types.Package) (gv clientgentypes.GroupVersion) { - parts := strings.Split(p.Path, "/") - gv.Group = clientgentypes.Group(parts[len(parts)-2]) - gv.Version = clientgentypes.Version(parts[len(parts)-1]) - - // If there's a comment of the form "// +groupName=somegroup" or - // "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the - // group when generating. - if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { - gv.Group = clientgentypes.Group(override[0]) - } - return gv -} - -// isInternalPackage returns true if the package is an internal package -func isInternalPackage(p *types.Package) bool { - for _, t := range p.Types { - for _, member := range t.Members { - if member.Name == "ObjectMeta" { - return isInternal(member) - } - } - } - return false -} - -// isInternal returns true if the tags for a member do not contain a json tag -func isInternal(m types.Member) bool { - _, ok := lookupJSONTags(m) - return !ok -} - -func hasObjectMetaField(t *types.Type) bool { - for _, member := range t.Members { - if objectMeta.Name == member.Type.Name && member.Embedded { - return true - } - } - return false -} diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/refgraph.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/refgraph.go deleted file mode 100644 index d1f95112..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/refgraph.go +++ /dev/null @@ -1,179 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" -) - -// refGraph maps existing types to the package the corresponding applyConfig types will be generated in -// so that references between apply configurations can be correctly generated. -type refGraph map[types.Name]string - -// refGraphForReachableTypes returns a refGraph that contains all reachable types from -// the root clientgen types of the provided packages. -func refGraphForReachableTypes(universe types.Universe, pkgTypes map[string]*types.Package, initialTypes map[types.Name]string) refGraph { - var refs refGraph = initialTypes - - // Include only types that are reachable from the root clientgen types. - // We don't want to generate apply configurations for types that are not reachable from a root - // clientgen type. - reachableTypes := map[types.Name]*types.Type{} - for _, p := range pkgTypes { - for _, t := range p.Types { - tags := genclientTags(t) - hasApply := tags.HasVerb("apply") || tags.HasVerb("applyStatus") - if tags.GenerateClient && hasApply { - findReachableTypes(t, reachableTypes) - } - // If any apply extensions have custom inputs, add them. - for _, extension := range tags.Extensions { - if extension.HasVerb("apply") { - if len(extension.InputTypeOverride) > 0 { - inputType := *t - if name, pkg := extension.Input(); len(pkg) > 0 { - inputType = *(universe.Type(types.Name{Package: pkg, Name: name})) - } else { - inputType.Name.Name = extension.InputTypeOverride - } - findReachableTypes(&inputType, reachableTypes) - } - } - } - } - } - for pkg, p := range pkgTypes { - for _, t := range p.Types { - if _, ok := reachableTypes[t.Name]; !ok { - continue - } - if requiresApplyConfiguration(t) { - refs[t.Name] = pkg - } - } - } - - return refs -} - -// applyConfigForType find the type used in the generate apply configurations for a field. -// This may either be an existing type or one of the other generated applyConfig types. -func (t refGraph) applyConfigForType(field *types.Type) *types.Type { - switch field.Kind { - case types.Struct: - if pkg, ok := t[field.Name]; ok { // TODO(jpbetz): Refs to types defined in a separate system (e.g. TypeMeta if generating a 3rd party controller) end up referencing the go struct, not the apply configuration type - return types.Ref(pkg, field.Name.Name+ApplyConfigurationTypeSuffix) - } - return field - case types.Map: - if _, ok := t[field.Elem.Name]; ok { - return &types.Type{ - Kind: types.Map, - Elem: t.applyConfigForType(field.Elem), - Key: t.applyConfigForType(field.Key), - } - } - return field - case types.Slice: - if _, ok := t[field.Elem.Name]; ok { - return &types.Type{ - Kind: types.Slice, - Elem: t.applyConfigForType(field.Elem), - } - } - return field - case types.Pointer: - return t.applyConfigForType(field.Elem) - default: - return field - } -} - -func (t refGraph) isApplyConfig(field *types.Type) bool { - switch field.Kind { - case types.Struct: - _, ok := t[field.Name] - return ok - case types.Pointer: - return t.isApplyConfig(field.Elem) - } - return false -} - -// genclientTags returns the genclient Tags for the given type. -func genclientTags(t *types.Type) util.Tags { - return util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) -} - -// findReachableTypes finds all types transitively reachable from a given root type, including -// the root type itself. -func findReachableTypes(t *types.Type, referencedTypes map[types.Name]*types.Type) { - if _, ok := referencedTypes[t.Name]; ok { - return - } - referencedTypes[t.Name] = t - - if t.Elem != nil { - findReachableTypes(t.Elem, referencedTypes) - } - if t.Underlying != nil { - findReachableTypes(t.Underlying, referencedTypes) - } - if t.Key != nil { - findReachableTypes(t.Key, referencedTypes) - } - for _, m := range t.Members { - findReachableTypes(m.Type, referencedTypes) - } -} - -// excludeTypes contains well known types that we do not generate apply configurations for. -// Hard coding because we only have two, very specific types that serve a special purpose -// in the type system here. -var excludeTypes = map[types.Name]struct{}{ - rawExtension.Name: {}, - unknown.Name: {}, - // DO NOT ADD TO THIS LIST. If we need to exclude other types, we should consider allowing the - // go type declarations to be annotated as excluded from this generator. -} - -// requiresApplyConfiguration returns true if a type applyConfig should be generated for the given type. -// types applyConfig are only generated for struct types that contain fields with json tags. -func requiresApplyConfiguration(t *types.Type) bool { - for t.Kind == types.Alias { - t = t.Underlying - } - if t.Kind != types.Struct { - return false - } - if _, ok := excludeTypes[t.Name]; ok { - return false - } - var hasJSONTaggedMembers bool - for _, member := range t.Members { - if _, ok := lookupJSONTags(member); ok { - hasJSONTaggedMembers = true - } - } - if !hasJSONTaggedMembers { - return false - } - - return true -} diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/types.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/types.go deleted file mode 100644 index 66578ae0..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/types.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import "k8s.io/gengo/types" - -var ( - applyConfiguration = types.Ref("k8s.io/apimachinery/pkg/runtime", "ApplyConfiguration") - groupVersionKind = types.Ref("k8s.io/apimachinery/pkg/runtime/schema", "GroupVersionKind") - typeMeta = types.Ref("k8s.io/apimachinery/pkg/apis/meta/v1", "TypeMeta") - objectMeta = types.Ref("k8s.io/apimachinery/pkg/apis/meta/v1", "ObjectMeta") - rawExtension = types.Ref("k8s.io/apimachinery/pkg/runtime", "RawExtension") - unknown = types.Ref("k8s.io/apimachinery/pkg/runtime", "Unknown") - extractInto = types.Ref("k8s.io/apimachinery/pkg/util/managedfields", "ExtractInto") - smdNewParser = types.Ref("sigs.k8s.io/structured-merge-diff/v4/typed", "NewParser") - smdParser = types.Ref("sigs.k8s.io/structured-merge-diff/v4/typed", "Parser") - yamlObject = types.Ref("sigs.k8s.io/structured-merge-diff/v4/typed", "YAMLObject") - yamlUnmarshal = types.Ref("gopkg.in/yaml.v2", "Unmarshal") -) diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/util.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/util.go deleted file mode 100644 index 258293af..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/generators/util.go +++ /dev/null @@ -1,163 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "sort" - "strings" - - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// utilGenerator generates the ForKind() utility function. -type utilGenerator struct { - generator.DefaultGen - outputPackage string - imports namer.ImportTracker - groupVersions map[string]clientgentypes.GroupVersions - groupGoNames map[string]string - typesForGroupVersion map[clientgentypes.GroupVersion][]applyConfig - filtered bool -} - -var _ generator.Generator = &utilGenerator{} - -func (g *utilGenerator) Filter(*generator.Context, *types.Type) bool { - // generate file exactly once - if !g.filtered { - g.filtered = true - return true - } - return false -} - -func (g *utilGenerator) Namers(*generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - "singularKind": namer.NewPublicNamer(0), - } -} - -func (g *utilGenerator) Imports(*generator.Context) (imports []string) { - return g.imports.ImportLines() -} - -type group struct { - GroupGoName string - Name string - Versions []*version -} - -type groupSort []group - -func (g groupSort) Len() int { return len(g) } -func (g groupSort) Less(i, j int) bool { - return strings.ToLower(g[i].Name) < strings.ToLower(g[j].Name) -} -func (g groupSort) Swap(i, j int) { g[i], g[j] = g[j], g[i] } - -type version struct { - Name string - GoName string - Resources []applyConfig -} - -type versionSort []*version - -func (v versionSort) Len() int { return len(v) } -func (v versionSort) Less(i, j int) bool { - return strings.ToLower(v[i].Name) < strings.ToLower(v[j].Name) -} -func (v versionSort) Swap(i, j int) { v[i], v[j] = v[j], v[i] } - -type applyConfig struct { - Type *types.Type - ApplyConfiguration *types.Type -} - -type applyConfigSort []applyConfig - -func (v applyConfigSort) Len() int { return len(v) } -func (v applyConfigSort) Less(i, j int) bool { - return strings.ToLower(v[i].Type.Name.Name) < strings.ToLower(v[j].Type.Name.Name) -} -func (v applyConfigSort) Swap(i, j int) { v[i], v[j] = v[j], v[i] } - -func (g *utilGenerator) GenerateType(c *generator.Context, _ *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "{{", "}}") - - var groups []group - schemeGVs := make(map[*version]*types.Type) - - for groupPackageName, groupVersions := range g.groupVersions { - group := group{ - GroupGoName: g.groupGoNames[groupPackageName], - Name: groupVersions.Group.NonEmpty(), - Versions: []*version{}, - } - for _, v := range groupVersions.Versions { - gv := clientgentypes.GroupVersion{Group: groupVersions.Group, Version: v.Version} - version := &version{ - Name: v.Version.NonEmpty(), - GoName: namer.IC(v.Version.NonEmpty()), - Resources: g.typesForGroupVersion[gv], - } - schemeGVs[version] = c.Universe.Variable(types.Name{ - Package: g.typesForGroupVersion[gv][0].Type.Name.Package, - Name: "SchemeGroupVersion", - }) - group.Versions = append(group.Versions, version) - } - sort.Sort(versionSort(group.Versions)) - groups = append(groups, group) - } - sort.Sort(groupSort(groups)) - - m := map[string]interface{}{ - "groups": groups, - "schemeGVs": schemeGVs, - "schemaGroupVersionKind": groupVersionKind, - "applyConfiguration": applyConfiguration, - } - sw.Do(forKindFunc, m) - - return sw.Error() -} - -var forKindFunc = ` -// ForKind returns an apply configuration type for the given GroupVersionKind, or nil if no -// apply configuration type exists for the given GroupVersionKind. -func ForKind(kind {{.schemaGroupVersionKind|raw}}) interface{} { - switch kind { - {{range $group := .groups -}}{{$GroupGoName := .GroupGoName -}} - {{range $version := .Versions -}} - // Group={{$group.Name}}, Version={{.Name}} - {{range .Resources -}} - case {{index $.schemeGVs $version|raw}}.WithKind("{{.Type|singularKind}}"): - return &{{.ApplyConfiguration|raw}}{} - {{end}} - {{end}} - {{end -}} - } - return nil -} -` diff --git a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/main.go b/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/main.go deleted file mode 100644 index b4e26404..00000000 --- a/vendor/k8s.io/code-generator/cmd/applyconfiguration-gen/main.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -// typebuilder-gen is a tool for auto-generating apply builder functions. -package main - -import ( - "flag" - - "github.com/spf13/pflag" - "k8s.io/klog/v2" - - generatorargs "k8s.io/code-generator/cmd/applyconfiguration-gen/args" - "k8s.io/code-generator/cmd/applyconfiguration-gen/generators" -) - -func main() { - klog.InitFlags(nil) - genericArgs, customArgs := generatorargs.NewDefaults() - genericArgs.AddFlags(pflag.CommandLine) - customArgs.AddFlags(pflag.CommandLine, "k8s.io/kubernetes/pkg/apis") // TODO: move this input path out of applyconfiguration-gen - if err := flag.Set("logtostderr", "true"); err != nil { - klog.Fatalf("Error: %v", err) - } - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - if err := generatorargs.Validate(genericArgs); err != nil { - klog.Fatalf("Error: %v", err) - } - - // Run it. - if err := genericArgs.Execute( - generators.NameSystems(), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Fatalf("Error: %v", err) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/OWNERS b/vendor/k8s.io/code-generator/cmd/client-gen/OWNERS deleted file mode 100644 index 967eb2a7..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/OWNERS +++ /dev/null @@ -1,11 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - wojtek-t - - caesarxuchao -reviewers: - - wojtek-t - - caesarxuchao - - jpbetz -emeritus_approvers: - - lavalamp diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/README.md b/vendor/k8s.io/code-generator/cmd/client-gen/README.md deleted file mode 100644 index b8206127..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/README.md +++ /dev/null @@ -1,2 +0,0 @@ -See [generating-clientset.md](https://git.k8s.io/community/contributors/devel/sig-api-machinery/generating-clientset.md) - diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/args/args.go b/vendor/k8s.io/code-generator/cmd/client-gen/args/args.go deleted file mode 100644 index 4460ad26..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/args/args.go +++ /dev/null @@ -1,133 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "fmt" - "path" - - "github.com/spf13/pflag" - "k8s.io/gengo/args" - - "k8s.io/code-generator/cmd/client-gen/types" - codegenutil "k8s.io/code-generator/pkg/util" -) - -var DefaultInputDirs = []string{} - -// CustomArgs is a wrapper for arguments to client-gen. -type CustomArgs struct { - // A sorted list of group versions to generate. For each of them the package path is found - // in GroupVersionToInputPath. - Groups []types.GroupVersions - - // Overrides for which types should be included in the client. - IncludedTypesOverrides map[types.GroupVersion][]string - - // ClientsetName is the name of the clientset to be generated. It's - // populated from command-line arguments. - ClientsetName string - // ClientsetAPIPath is the default API HTTP path for generated clients. - ClientsetAPIPath string - // ClientsetOnly determines if we should generate the clients for groups and - // types along with the clientset. It's populated from command-line - // arguments. - ClientsetOnly bool - // FakeClient determines if client-gen generates the fake clients. - FakeClient bool - // PluralExceptions specify list of exceptions used when pluralizing certain types. - // For example 'Endpoints:Endpoints', otherwise the pluralizer will generate 'Endpointes'. - PluralExceptions []string - - // ApplyConfigurationPackage is the package of apply builders generated by typebuilder-gen. - // If non-empty, Apply functions are generated for each type and reference the apply builders. - // If empty (""), Apply functions are not generated. - ApplyConfigurationPackage string -} - -func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { - genericArgs := args.Default().WithoutDefaultFlagParsing() - customArgs := &CustomArgs{ - ClientsetName: "internalclientset", - ClientsetAPIPath: "/apis", - ClientsetOnly: false, - FakeClient: true, - PluralExceptions: []string{"Endpoints:Endpoints"}, - ApplyConfigurationPackage: "", - } - genericArgs.CustomArgs = customArgs - genericArgs.InputDirs = DefaultInputDirs - - if pkg := codegenutil.CurrentPackage(); len(pkg) != 0 { - genericArgs.OutputPackagePath = path.Join(pkg, "pkg/client/clientset") - } - - return genericArgs, customArgs -} - -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet, inputBase string) { - gvsBuilder := NewGroupVersionsBuilder(&ca.Groups) - pflag.Var(NewGVPackagesValue(gvsBuilder, nil), "input", "group/versions that client-gen will generate clients for. At most one version per group is allowed. Specified in the format \"group1/version1,group2/version2...\".") - pflag.Var(NewGVTypesValue(&ca.IncludedTypesOverrides, []string{}), "included-types-overrides", "list of group/version/type for which client should be generated. By default, client is generated for all types which have genclient in types.go. This overrides that. For each groupVersion in this list, only the types mentioned here will be included. The default check of genclient will be used for other group versions.") - pflag.Var(NewInputBasePathValue(gvsBuilder, inputBase), "input-base", "base path to look for the api group.") - pflag.StringVarP(&ca.ClientsetName, "clientset-name", "n", ca.ClientsetName, "the name of the generated clientset package.") - pflag.StringVarP(&ca.ClientsetAPIPath, "clientset-api-path", "", ca.ClientsetAPIPath, "the value of default API HTTP path, starting with / and without trailing /.") - pflag.BoolVar(&ca.ClientsetOnly, "clientset-only", ca.ClientsetOnly, "when set, client-gen only generates the clientset shell, without generating the individual typed clients") - pflag.BoolVar(&ca.FakeClient, "fake-clientset", ca.FakeClient, "when set, client-gen will generate the fake clientset that can be used in tests") - - fs.StringSliceVar(&ca.PluralExceptions, "plural-exceptions", ca.PluralExceptions, "list of comma separated plural exception definitions in Type:PluralizedType form") - fs.StringVar(&ca.ApplyConfigurationPackage, "apply-configuration-package", ca.ApplyConfigurationPackage, "optional package of apply configurations, generated by applyconfiguration-gen, that are required to generate Apply functions for each type in the clientset. By default Apply functions are not generated.") - - // support old flags - fs.SetNormalizeFunc(mapFlagName("clientset-path", "output-package", fs.GetNormalizeFunc())) -} - -func Validate(genericArgs *args.GeneratorArgs) error { - customArgs := genericArgs.CustomArgs.(*CustomArgs) - - if len(genericArgs.OutputPackagePath) == 0 { - return fmt.Errorf("output package cannot be empty") - } - if len(customArgs.ClientsetName) == 0 { - return fmt.Errorf("clientset name cannot be empty") - } - if len(customArgs.ClientsetAPIPath) == 0 { - return fmt.Errorf("clientset API path cannot be empty") - } - - return nil -} - -// GroupVersionPackages returns a map from GroupVersion to the package with the types.go. -func (ca *CustomArgs) GroupVersionPackages() map[types.GroupVersion]string { - res := map[types.GroupVersion]string{} - for _, pkg := range ca.Groups { - for _, v := range pkg.Versions { - res[types.GroupVersion{Group: pkg.Group, Version: v.Version}] = v.Package - } - } - return res -} - -func mapFlagName(from, to string, old func(fs *pflag.FlagSet, name string) pflag.NormalizedName) func(fs *pflag.FlagSet, name string) pflag.NormalizedName { - return func(fs *pflag.FlagSet, name string) pflag.NormalizedName { - if name == from { - name = to - } - return old(fs, name) - } -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go b/vendor/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go deleted file mode 100644 index 50d29a95..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go +++ /dev/null @@ -1,173 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "bytes" - "encoding/csv" - "flag" - "path" - "sort" - "strings" - - "k8s.io/code-generator/cmd/client-gen/generators/util" - "k8s.io/code-generator/cmd/client-gen/types" -) - -type inputBasePathValue struct { - builder *groupVersionsBuilder -} - -var _ flag.Value = &inputBasePathValue{} - -func NewInputBasePathValue(builder *groupVersionsBuilder, def string) *inputBasePathValue { - v := &inputBasePathValue{ - builder: builder, - } - v.Set(def) - return v -} - -func (s *inputBasePathValue) Set(val string) error { - s.builder.importBasePath = val - return s.builder.update() -} - -func (s *inputBasePathValue) Type() string { - return "string" -} - -func (s *inputBasePathValue) String() string { - return s.builder.importBasePath -} - -type gvPackagesValue struct { - builder *groupVersionsBuilder - groups []string - changed bool -} - -func NewGVPackagesValue(builder *groupVersionsBuilder, def []string) *gvPackagesValue { - gvp := new(gvPackagesValue) - gvp.builder = builder - if def != nil { - if err := gvp.set(def); err != nil { - panic(err) - } - } - return gvp -} - -var _ flag.Value = &gvPackagesValue{} - -func (s *gvPackagesValue) set(vs []string) error { - if s.changed { - s.groups = append(s.groups, vs...) - } else { - s.groups = append([]string(nil), vs...) - } - - s.builder.groups = s.groups - return s.builder.update() -} - -func (s *gvPackagesValue) Set(val string) error { - vs, err := readAsCSV(val) - if err != nil { - return err - } - if err := s.set(vs); err != nil { - return err - } - s.changed = true - return nil -} - -func (s *gvPackagesValue) Type() string { - return "stringSlice" -} - -func (s *gvPackagesValue) String() string { - str, _ := writeAsCSV(s.groups) - return "[" + str + "]" -} - -type groupVersionsBuilder struct { - value *[]types.GroupVersions - groups []string - importBasePath string -} - -func NewGroupVersionsBuilder(groups *[]types.GroupVersions) *groupVersionsBuilder { - return &groupVersionsBuilder{ - value: groups, - } -} - -func (p *groupVersionsBuilder) update() error { - var seenGroups = make(map[types.Group]*types.GroupVersions) - for _, v := range p.groups { - pth, gvString := util.ParsePathGroupVersion(v) - gv, err := types.ToGroupVersion(gvString) - if err != nil { - return err - } - - versionPkg := types.PackageVersion{Package: path.Join(p.importBasePath, pth, gv.Group.NonEmpty(), gv.Version.String()), Version: gv.Version} - if group, ok := seenGroups[gv.Group]; ok { - seenGroups[gv.Group].Versions = append(group.Versions, versionPkg) - } else { - seenGroups[gv.Group] = &types.GroupVersions{ - PackageName: gv.Group.NonEmpty(), - Group: gv.Group, - Versions: []types.PackageVersion{versionPkg}, - } - } - } - - var groupNames []string - for groupName := range seenGroups { - groupNames = append(groupNames, groupName.String()) - } - sort.Strings(groupNames) - *p.value = []types.GroupVersions{} - for _, groupName := range groupNames { - *p.value = append(*p.value, *seenGroups[types.Group(groupName)]) - } - - return nil -} - -func readAsCSV(val string) ([]string, error) { - if val == "" { - return []string{}, nil - } - stringReader := strings.NewReader(val) - csvReader := csv.NewReader(stringReader) - return csvReader.Read() -} - -func writeAsCSV(vals []string) (string, error) { - b := &bytes.Buffer{} - w := csv.NewWriter(b) - err := w.Write(vals) - if err != nil { - return "", err - } - w.Flush() - return strings.TrimSuffix(b.String(), "\n"), nil -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/args/gvtype.go b/vendor/k8s.io/code-generator/cmd/client-gen/args/gvtype.go deleted file mode 100644 index e4e3ccb5..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/args/gvtype.go +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "flag" - "fmt" - "strings" - - "k8s.io/code-generator/cmd/client-gen/types" -) - -type gvTypeValue struct { - gvToTypes *map[types.GroupVersion][]string - changed bool -} - -func NewGVTypesValue(gvToTypes *map[types.GroupVersion][]string, def []string) *gvTypeValue { - gvt := new(gvTypeValue) - gvt.gvToTypes = gvToTypes - if def != nil { - if err := gvt.set(def); err != nil { - panic(err) - } - } - return gvt -} - -var _ flag.Value = &gvTypeValue{} - -func (s *gvTypeValue) set(vs []string) error { - if !s.changed { - *s.gvToTypes = map[types.GroupVersion][]string{} - } - - for _, input := range vs { - gvString, typeStr, err := parseGroupVersionType(input) - if err != nil { - return err - } - gv, err := types.ToGroupVersion(gvString) - if err != nil { - return err - } - types, ok := (*s.gvToTypes)[gv] - if !ok { - types = []string{} - } - types = append(types, typeStr) - (*s.gvToTypes)[gv] = types - } - - return nil -} - -func (s *gvTypeValue) Set(val string) error { - vs, err := readAsCSV(val) - if err != nil { - return err - } - if err := s.set(vs); err != nil { - return err - } - s.changed = true - return nil -} - -func (s *gvTypeValue) Type() string { - return "stringSlice" -} - -func (s *gvTypeValue) String() string { - strs := make([]string, 0, len(*s.gvToTypes)) - for gv, ts := range *s.gvToTypes { - for _, t := range ts { - strs = append(strs, gv.Group.String()+"/"+gv.Version.String()+"/"+t) - } - } - str, _ := writeAsCSV(strs) - return "[" + str + "]" -} - -func parseGroupVersionType(gvtString string) (gvString string, typeStr string, err error) { - invalidFormatErr := fmt.Errorf("invalid value: %s, should be of the form group/version/type", gvtString) - subs := strings.Split(gvtString, "/") - length := len(subs) - switch length { - case 2: - // gvtString of the form group/type, e.g. api/Service,extensions/ReplicaSet - return subs[0] + "/", subs[1], nil - case 3: - return strings.Join(subs[:length-1], "/"), subs[length-1], nil - default: - return "", "", invalidFormatErr - } -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go deleted file mode 100644 index ef4466d8..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go +++ /dev/null @@ -1,393 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// Package generators has the generators for the client-gen utility. -package generators - -import ( - "path/filepath" - "strings" - - clientgenargs "k8s.io/code-generator/cmd/client-gen/args" - "k8s.io/code-generator/cmd/client-gen/generators/fake" - "k8s.io/code-generator/cmd/client-gen/generators/scheme" - "k8s.io/code-generator/cmd/client-gen/generators/util" - "k8s.io/code-generator/cmd/client-gen/path" - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - codegennamer "k8s.io/code-generator/pkg/namer" - genutil "k8s.io/code-generator/pkg/util" - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/klog/v2" -) - -// NameSystems returns the name system used by the generators in this package. -func NameSystems(pluralExceptions map[string]string) namer.NameSystems { - lowercaseNamer := namer.NewAllLowercasePluralNamer(pluralExceptions) - - publicNamer := &ExceptionNamer{ - Exceptions: map[string]string{ - // these exceptions are used to deconflict the generated code - // you can put your fully qualified package like - // to generate a name that doesn't conflict with your group. - // "k8s.io/apis/events/v1beta1.Event": "EventResource" - }, - KeyFunc: func(t *types.Type) string { - return t.Name.Package + "." + t.Name.Name - }, - Delegate: namer.NewPublicNamer(0), - } - privateNamer := &ExceptionNamer{ - Exceptions: map[string]string{ - // these exceptions are used to deconflict the generated code - // you can put your fully qualified package like - // to generate a name that doesn't conflict with your group. - // "k8s.io/apis/events/v1beta1.Event": "eventResource" - }, - KeyFunc: func(t *types.Type) string { - return t.Name.Package + "." + t.Name.Name - }, - Delegate: namer.NewPrivateNamer(0), - } - publicPluralNamer := &ExceptionNamer{ - Exceptions: map[string]string{ - // these exceptions are used to deconflict the generated code - // you can put your fully qualified package like - // to generate a name that doesn't conflict with your group. - // "k8s.io/apis/events/v1beta1.Event": "EventResource" - }, - KeyFunc: func(t *types.Type) string { - return t.Name.Package + "." + t.Name.Name - }, - Delegate: namer.NewPublicPluralNamer(pluralExceptions), - } - privatePluralNamer := &ExceptionNamer{ - Exceptions: map[string]string{ - // you can put your fully qualified package like - // to generate a name that doesn't conflict with your group. - // "k8s.io/apis/events/v1beta1.Event": "eventResource" - // these exceptions are used to deconflict the generated code - "k8s.io/apis/events/v1beta1.Event": "eventResources", - "k8s.io/kubernetes/pkg/apis/events.Event": "eventResources", - }, - KeyFunc: func(t *types.Type) string { - return t.Name.Package + "." + t.Name.Name - }, - Delegate: namer.NewPrivatePluralNamer(pluralExceptions), - } - - return namer.NameSystems{ - "singularKind": namer.NewPublicNamer(0), - "public": publicNamer, - "private": privateNamer, - "raw": namer.NewRawNamer("", nil), - "publicPlural": publicPluralNamer, - "privatePlural": privatePluralNamer, - "allLowercasePlural": lowercaseNamer, - "resource": codegennamer.NewTagOverrideNamer("resourceName", lowercaseNamer), - } -} - -// ExceptionNamer allows you specify exceptional cases with exact names. This allows you to have control -// for handling various conflicts, like group and resource names for instance. -type ExceptionNamer struct { - Exceptions map[string]string - KeyFunc func(*types.Type) string - - Delegate namer.Namer -} - -// Name provides the requested name for a type. -func (n *ExceptionNamer) Name(t *types.Type) string { - key := n.KeyFunc(t) - if exception, ok := n.Exceptions[key]; ok { - return exception - } - return n.Delegate.Name(t) -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, groupPackageName string, groupGoName string, apiPath string, srcTreePath string, inputPackage string, applyBuilderPackage string, boilerplate []byte) generator.Package { - groupVersionClientPackage := filepath.Join(clientsetPackage, "typed", strings.ToLower(groupPackageName), strings.ToLower(gv.Version.NonEmpty())) - return &generator.DefaultPackage{ - PackageName: strings.ToLower(gv.Version.NonEmpty()), - PackagePath: groupVersionClientPackage, - HeaderText: boilerplate, - PackageDocumentation: []byte("// This package has the automatically generated typed clients.\n"), - // GeneratorFunc returns a list of generators. Each generator makes a - // single file. - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = []generator.Generator{ - // Always generate a "doc.go" file. - generator.DefaultGen{OptionalName: "doc"}, - } - // Since we want a file per type that we generate a client for, we - // have to provide a function for this. - for _, t := range typeList { - generators = append(generators, &genClientForType{ - DefaultGen: generator.DefaultGen{ - OptionalName: strings.ToLower(c.Namers["private"].Name(t)), - }, - outputPackage: groupVersionClientPackage, - inputPackage: inputPackage, - clientsetPackage: clientsetPackage, - applyConfigurationPackage: applyBuilderPackage, - group: gv.Group.NonEmpty(), - version: gv.Version.String(), - groupGoName: groupGoName, - typeToMatch: t, - imports: generator.NewImportTracker(), - }) - } - - generators = append(generators, &genGroup{ - DefaultGen: generator.DefaultGen{ - OptionalName: groupPackageName + "_client", - }, - outputPackage: groupVersionClientPackage, - inputPackage: inputPackage, - clientsetPackage: clientsetPackage, - group: gv.Group.NonEmpty(), - version: gv.Version.String(), - groupGoName: groupGoName, - apiPath: apiPath, - types: typeList, - imports: generator.NewImportTracker(), - }) - - expansionFileName := "generated_expansion" - generators = append(generators, &genExpansion{ - groupPackagePath: filepath.Join(srcTreePath, groupVersionClientPackage), - DefaultGen: generator.DefaultGen{ - OptionalName: expansionFileName, - }, - types: typeList, - }) - - return generators - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - return util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)).GenerateClient - }, - } -} - -func packageForClientset(customArgs *clientgenargs.CustomArgs, clientsetPackage string, groupGoNames map[clientgentypes.GroupVersion]string, boilerplate []byte) generator.Package { - return &generator.DefaultPackage{ - PackageName: customArgs.ClientsetName, - PackagePath: clientsetPackage, - HeaderText: boilerplate, - // GeneratorFunc returns a list of generators. Each generator generates a - // single file. - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = []generator.Generator{ - &genClientset{ - DefaultGen: generator.DefaultGen{ - OptionalName: "clientset", - }, - groups: customArgs.Groups, - groupGoNames: groupGoNames, - clientsetPackage: clientsetPackage, - outputPackage: customArgs.ClientsetName, - imports: generator.NewImportTracker(), - }, - } - return generators - }, - } -} - -func packageForScheme(customArgs *clientgenargs.CustomArgs, clientsetPackage string, srcTreePath string, groupGoNames map[clientgentypes.GroupVersion]string, boilerplate []byte) generator.Package { - schemePackage := filepath.Join(clientsetPackage, "scheme") - - // create runtime.Registry for internal client because it has to know about group versions - internalClient := false -NextGroup: - for _, group := range customArgs.Groups { - for _, v := range group.Versions { - if v.String() == "" { - internalClient = true - break NextGroup - } - } - } - - return &generator.DefaultPackage{ - PackageName: "scheme", - PackagePath: schemePackage, - HeaderText: boilerplate, - PackageDocumentation: []byte("// This package contains the scheme of the automatically generated clientset.\n"), - // GeneratorFunc returns a list of generators. Each generator generates a - // single file. - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = []generator.Generator{ - // Always generate a "doc.go" file. - generator.DefaultGen{OptionalName: "doc"}, - - &scheme.GenScheme{ - DefaultGen: generator.DefaultGen{ - OptionalName: "register", - }, - InputPackages: customArgs.GroupVersionPackages(), - OutputPackage: schemePackage, - OutputPath: filepath.Join(srcTreePath, schemePackage), - Groups: customArgs.Groups, - GroupGoNames: groupGoNames, - ImportTracker: generator.NewImportTracker(), - CreateRegistry: internalClient, - }, - } - return generators - }, - } -} - -// applyGroupOverrides applies group name overrides to each package, if applicable. If there is a -// comment of the form "// +groupName=somegroup" or "// +groupName=somegroup.foo.bar.io", use the -// first field (somegroup) as the name of the group in Go code, e.g. as the func name in a clientset. -// -// If the first field of the groupName is not unique within the clientset, use "// +groupName=unique -func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.CustomArgs) { - // Create a map from "old GV" to "new GV" so we know what changes we need to make. - changes := make(map[clientgentypes.GroupVersion]clientgentypes.GroupVersion) - for gv, inputDir := range customArgs.GroupVersionPackages() { - p := universe.Package(genutil.Vendorless(inputDir)) - if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { - newGV := clientgentypes.GroupVersion{ - Group: clientgentypes.Group(override[0]), - Version: gv.Version, - } - changes[gv] = newGV - } - } - - // Modify customArgs.Groups based on the groupName overrides. - newGroups := make([]clientgentypes.GroupVersions, 0, len(customArgs.Groups)) - for _, gvs := range customArgs.Groups { - gv := clientgentypes.GroupVersion{ - Group: gvs.Group, - Version: gvs.Versions[0].Version, // we only need a version, and the first will do - } - if newGV, ok := changes[gv]; ok { - // There's an override, so use it. - newGVS := clientgentypes.GroupVersions{ - PackageName: gvs.PackageName, - Group: newGV.Group, - Versions: gvs.Versions, - } - newGroups = append(newGroups, newGVS) - } else { - // No override. - newGroups = append(newGroups, gvs) - } - } - customArgs.Groups = newGroups -} - -// Packages makes the client package definition. -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - customArgs, ok := arguments.CustomArgs.(*clientgenargs.CustomArgs) - if !ok { - klog.Fatalf("cannot convert arguments.CustomArgs to clientgenargs.CustomArgs") - } - includedTypesOverrides := customArgs.IncludedTypesOverrides - - applyGroupOverrides(context.Universe, customArgs) - - gvToTypes := map[clientgentypes.GroupVersion][]*types.Type{} - groupGoNames := make(map[clientgentypes.GroupVersion]string) - for gv, inputDir := range customArgs.GroupVersionPackages() { - p := context.Universe.Package(path.Vendorless(inputDir)) - - // If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as - // the Go group identifier in CamelCase. It defaults - groupGoNames[gv] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0]) - if override := types.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil { - groupGoNames[gv] = namer.IC(override[0]) - } - - // Package are indexed with the vendor prefix stripped - for n, t := range p.Types { - // filter out types which are not included in user specified overrides. - typesOverride, ok := includedTypesOverrides[gv] - if ok { - found := false - for _, typeStr := range typesOverride { - if typeStr == n { - found = true - break - } - } - if !found { - continue - } - } else { - // User has not specified any override for this group version. - // filter out types which don't have genclient. - if tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)); !tags.GenerateClient { - continue - } - } - if _, found := gvToTypes[gv]; !found { - gvToTypes[gv] = []*types.Type{} - } - gvToTypes[gv] = append(gvToTypes[gv], t) - } - } - - var packageList []generator.Package - clientsetPackage := filepath.Join(arguments.OutputPackagePath, customArgs.ClientsetName) - - packageList = append(packageList, packageForClientset(customArgs, clientsetPackage, groupGoNames, boilerplate)) - packageList = append(packageList, packageForScheme(customArgs, clientsetPackage, arguments.OutputBase, groupGoNames, boilerplate)) - if customArgs.FakeClient { - packageList = append(packageList, fake.PackageForClientset(customArgs, clientsetPackage, groupGoNames, boilerplate)) - } - - // If --clientset-only=true, we don't regenerate the individual typed clients. - if customArgs.ClientsetOnly { - return generator.Packages(packageList) - } - - orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} - gvPackages := customArgs.GroupVersionPackages() - for _, group := range customArgs.Groups { - for _, version := range group.Versions { - gv := clientgentypes.GroupVersion{Group: group.Group, Version: version.Version} - types := gvToTypes[gv] - inputPath := gvPackages[gv] - packageList = append(packageList, packageForGroup(gv, orderer.OrderTypes(types), clientsetPackage, group.PackageName, groupGoNames[gv], customArgs.ClientsetAPIPath, arguments.OutputBase, inputPath, customArgs.ApplyConfigurationPackage, boilerplate)) - if customArgs.FakeClient { - packageList = append(packageList, fake.PackageForGroup(gv, orderer.OrderTypes(types), clientsetPackage, group.PackageName, groupGoNames[gv], inputPath, customArgs.ApplyConfigurationPackage, boilerplate)) - } - } - } - - return generator.Packages(packageList) -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go deleted file mode 100644 index 17949091..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package fake - -import ( - "path/filepath" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/types" - - clientgenargs "k8s.io/code-generator/cmd/client-gen/args" - scheme "k8s.io/code-generator/cmd/client-gen/generators/scheme" - "k8s.io/code-generator/cmd/client-gen/generators/util" - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" -) - -func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, groupPackageName string, groupGoName string, inputPackage string, applyBuilderPackage string, boilerplate []byte) generator.Package { - outputPackage := filepath.Join(clientsetPackage, "typed", strings.ToLower(groupPackageName), strings.ToLower(gv.Version.NonEmpty()), "fake") - // TODO: should make this a function, called by here and in client-generator.go - realClientPackage := filepath.Join(clientsetPackage, "typed", strings.ToLower(groupPackageName), strings.ToLower(gv.Version.NonEmpty())) - return &generator.DefaultPackage{ - PackageName: "fake", - PackagePath: outputPackage, - HeaderText: boilerplate, - PackageDocumentation: []byte( - `// Package fake has the automatically generated clients. -`), - // GeneratorFunc returns a list of generators. Each generator makes a - // single file. - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = []generator.Generator{ - // Always generate a "doc.go" file. - generator.DefaultGen{OptionalName: "doc"}, - } - // Since we want a file per type that we generate a client for, we - // have to provide a function for this. - for _, t := range typeList { - generators = append(generators, &genFakeForType{ - DefaultGen: generator.DefaultGen{ - OptionalName: "fake_" + strings.ToLower(c.Namers["private"].Name(t)), - }, - outputPackage: outputPackage, - inputPackage: inputPackage, - group: gv.Group.NonEmpty(), - version: gv.Version.String(), - groupGoName: groupGoName, - typeToMatch: t, - imports: generator.NewImportTracker(), - applyConfigurationPackage: applyBuilderPackage, - }) - } - - generators = append(generators, &genFakeForGroup{ - DefaultGen: generator.DefaultGen{ - OptionalName: "fake_" + groupPackageName + "_client", - }, - outputPackage: outputPackage, - realClientPackage: realClientPackage, - group: gv.Group.NonEmpty(), - version: gv.Version.String(), - groupGoName: groupGoName, - types: typeList, - imports: generator.NewImportTracker(), - }) - return generators - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - return util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)).GenerateClient - }, - } -} - -func PackageForClientset(customArgs *clientgenargs.CustomArgs, clientsetPackage string, groupGoNames map[clientgentypes.GroupVersion]string, boilerplate []byte) generator.Package { - return &generator.DefaultPackage{ - // TODO: we'll generate fake clientset for different release in the future. - // Package name and path are hard coded for now. - PackageName: "fake", - PackagePath: filepath.Join(clientsetPackage, "fake"), - HeaderText: boilerplate, - PackageDocumentation: []byte( - `// This package has the automatically generated fake clientset. -`), - // GeneratorFunc returns a list of generators. Each generator generates a - // single file. - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = []generator.Generator{ - // Always generate a "doc.go" file. - generator.DefaultGen{OptionalName: "doc"}, - - &genClientset{ - DefaultGen: generator.DefaultGen{ - OptionalName: "clientset_generated", - }, - groups: customArgs.Groups, - groupGoNames: groupGoNames, - fakeClientsetPackage: clientsetPackage, - outputPackage: "fake", - imports: generator.NewImportTracker(), - realClientsetPackage: clientsetPackage, - }, - &scheme.GenScheme{ - DefaultGen: generator.DefaultGen{ - OptionalName: "register", - }, - InputPackages: customArgs.GroupVersionPackages(), - OutputPackage: clientsetPackage, - Groups: customArgs.Groups, - GroupGoNames: groupGoNames, - ImportTracker: generator.NewImportTracker(), - PrivateScheme: true, - }, - } - return generators - }, - } -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go deleted file mode 100644 index cd731cb9..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go +++ /dev/null @@ -1,170 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package fake - -import ( - "fmt" - "io" - "path/filepath" - "strings" - - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// genClientset generates a package for a clientset. -type genClientset struct { - generator.DefaultGen - groups []clientgentypes.GroupVersions - groupGoNames map[clientgentypes.GroupVersion]string - fakeClientsetPackage string - outputPackage string - imports namer.ImportTracker - clientsetGenerated bool - // the import path of the generated real clientset. - realClientsetPackage string -} - -var _ generator.Generator = &genClientset{} - -func (g *genClientset) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -// We only want to call GenerateType() once. -func (g *genClientset) Filter(c *generator.Context, t *types.Type) bool { - ret := !g.clientsetGenerated - g.clientsetGenerated = true - return ret -} - -func (g *genClientset) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - for _, group := range g.groups { - for _, version := range group.Versions { - groupClientPackage := filepath.Join(g.fakeClientsetPackage, "typed", strings.ToLower(group.PackageName), strings.ToLower(version.NonEmpty())) - fakeGroupClientPackage := filepath.Join(groupClientPackage, "fake") - - groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{Group: group.Group, Version: version.Version}]) - imports = append(imports, fmt.Sprintf("%s%s \"%s\"", groupAlias, strings.ToLower(version.NonEmpty()), groupClientPackage)) - imports = append(imports, fmt.Sprintf("fake%s%s \"%s\"", groupAlias, strings.ToLower(version.NonEmpty()), fakeGroupClientPackage)) - } - } - // the package that has the clientset Interface - imports = append(imports, fmt.Sprintf("clientset \"%s\"", g.realClientsetPackage)) - // imports for the code in commonTemplate - imports = append(imports, - "k8s.io/client-go/testing", - "k8s.io/client-go/discovery", - "fakediscovery \"k8s.io/client-go/discovery/fake\"", - "k8s.io/apimachinery/pkg/runtime", - "k8s.io/apimachinery/pkg/watch", - ) - - return -} - -func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - // TODO: We actually don't need any type information to generate the clientset, - // perhaps we can adapt the go2ild framework to this kind of usage. - sw := generator.NewSnippetWriter(w, c, "$", "$") - - allGroups := clientgentypes.ToGroupVersionInfo(g.groups, g.groupGoNames) - - sw.Do(common, nil) - sw.Do(checkImpl, nil) - - for _, group := range allGroups { - m := map[string]interface{}{ - "group": group.Group, - "version": group.Version, - "PackageAlias": group.PackageAlias, - "GroupGoName": group.GroupGoName, - "Version": namer.IC(group.Version.String()), - } - - sw.Do(clientsetInterfaceImplTemplate, m) - } - - return sw.Error() -} - -// This part of code is version-independent, unchanging. -var common = ` -// NewSimpleClientset returns a clientset that will respond with the provided objects. -// It's backed by a very simple object tracker that processes creates, updates and deletions as-is, -// without applying any validations and/or defaults. It shouldn't be considered a replacement -// for a real clientset and is mostly useful in simple unit tests. -func NewSimpleClientset(objects ...runtime.Object) *Clientset { - o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) - for _, obj := range objects { - if err := o.Add(obj); err != nil { - panic(err) - } - } - - cs := &Clientset{tracker: o} - cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} - cs.AddReactor("*", "*", testing.ObjectReaction(o)) - cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { - gvr := action.GetResource() - ns := action.GetNamespace() - watch, err := o.Watch(gvr, ns) - if err != nil { - return false, nil, err - } - return true, watch, nil - }) - - return cs -} - -// Clientset implements clientset.Interface. Meant to be embedded into a -// struct to get a default implementation. This makes faking out just the method -// you want to test easier. -type Clientset struct { - testing.Fake - discovery *fakediscovery.FakeDiscovery - tracker testing.ObjectTracker -} - -func (c *Clientset) Discovery() discovery.DiscoveryInterface { - return c.discovery -} - -func (c *Clientset) Tracker() testing.ObjectTracker { - return c.tracker -} -` - -var checkImpl = ` -var ( - _ clientset.Interface = &Clientset{} - _ testing.FakeClient = &Clientset{} -) -` - -var clientsetInterfaceImplTemplate = ` -// $.GroupGoName$$.Version$ retrieves the $.GroupGoName$$.Version$Client -func (c *Clientset) $.GroupGoName$$.Version$() $.PackageAlias$.$.GroupGoName$$.Version$Interface { - return &fake$.PackageAlias$.Fake$.GroupGoName$$.Version${Fake: &c.Fake} -} -` diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_group.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_group.go deleted file mode 100644 index 8f4d5785..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_group.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package fake - -import ( - "fmt" - "io" - "path/filepath" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" -) - -// genFakeForGroup produces a file for a group client, e.g. ExtensionsClient for the extension group. -type genFakeForGroup struct { - generator.DefaultGen - outputPackage string - realClientPackage string - group string - version string - groupGoName string - // types in this group - types []*types.Type - imports namer.ImportTracker - // If the genGroup has been called. This generator should only execute once. - called bool -} - -var _ generator.Generator = &genFakeForGroup{} - -// We only want to call GenerateType() once per group. -func (g *genFakeForGroup) Filter(c *generator.Context, t *types.Type) bool { - if !g.called { - g.called = true - return true - } - return false -} - -func (g *genFakeForGroup) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *genFakeForGroup) Imports(c *generator.Context) (imports []string) { - imports = g.imports.ImportLines() - if len(g.types) != 0 { - imports = append(imports, fmt.Sprintf("%s \"%s\"", strings.ToLower(filepath.Base(g.realClientPackage)), g.realClientPackage)) - } - return imports -} - -func (g *genFakeForGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - m := map[string]interface{}{ - "GroupGoName": g.groupGoName, - "Version": namer.IC(g.version), - "Fake": c.Universe.Type(types.Name{Package: "k8s.io/client-go/testing", Name: "Fake"}), - "RESTClientInterface": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Interface"}), - "RESTClient": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "RESTClient"}), - } - - sw.Do(groupClientTemplate, m) - for _, t := range g.types { - tags, err := util.ParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if err != nil { - return err - } - wrapper := map[string]interface{}{ - "type": t, - "GroupGoName": g.groupGoName, - "Version": namer.IC(g.version), - "realClientPackage": strings.ToLower(filepath.Base(g.realClientPackage)), - } - if tags.NonNamespaced { - sw.Do(getterImplNonNamespaced, wrapper) - continue - } - sw.Do(getterImplNamespaced, wrapper) - } - sw.Do(getRESTClient, m) - return sw.Error() -} - -var groupClientTemplate = ` -type Fake$.GroupGoName$$.Version$ struct { - *$.Fake|raw$ -} -` - -var getterImplNamespaced = ` -func (c *Fake$.GroupGoName$$.Version$) $.type|publicPlural$(namespace string) $.realClientPackage$.$.type|public$Interface { - return &Fake$.type|publicPlural${c, namespace} -} -` - -var getterImplNonNamespaced = ` -func (c *Fake$.GroupGoName$$.Version$) $.type|publicPlural$() $.realClientPackage$.$.type|public$Interface { - return &Fake$.type|publicPlural${c} -} -` - -var getRESTClient = ` -// RESTClient returns a RESTClient that is used to communicate -// with API server by this client implementation. -func (c *Fake$.GroupGoName$$.Version$) RESTClient() $.RESTClientInterface|raw$ { - var ret *$.RESTClient|raw$ - return ret -} -` diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_type.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_type.go deleted file mode 100644 index 28b829cc..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_type.go +++ /dev/null @@ -1,570 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package fake - -import ( - "io" - gopath "path" - "path/filepath" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" -) - -// genFakeForType produces a file for each top-level type. -type genFakeForType struct { - generator.DefaultGen - outputPackage string - group string - version string - groupGoName string - inputPackage string - typeToMatch *types.Type - imports namer.ImportTracker - applyConfigurationPackage string -} - -var _ generator.Generator = &genFakeForType{} - -// Filter ignores all but one type because we're making a single file per type. -func (g *genFakeForType) Filter(c *generator.Context, t *types.Type) bool { return t == g.typeToMatch } - -func (g *genFakeForType) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *genFakeForType) Imports(c *generator.Context) (imports []string) { - return g.imports.ImportLines() -} - -// Ideally, we'd like genStatus to return true if there is a subresource path -// registered for "status" in the API server, but we do not have that -// information, so genStatus returns true if the type has a status field. -func genStatus(t *types.Type) bool { - // Default to true if we have a Status member - hasStatus := false - for _, m := range t.Members { - if m.Name == "Status" { - hasStatus = true - break - } - } - - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return hasStatus && !tags.NoStatus -} - -// hasObjectMeta returns true if the type has a ObjectMeta field. -func hasObjectMeta(t *types.Type) bool { - for _, m := range t.Members { - if m.Embedded && m.Name == "ObjectMeta" { - return true - } - } - return false -} - -// GenerateType makes the body of a file implementing the individual typed client for type t. -func (g *genFakeForType) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - pkg := filepath.Base(t.Name.Package) - tags, err := util.ParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if err != nil { - return err - } - - const pkgClientGoTesting = "k8s.io/client-go/testing" - m := map[string]interface{}{ - "type": t, - "inputType": t, - "resultType": t, - "subresourcePath": "", - "package": pkg, - "Package": namer.IC(pkg), - "namespaced": !tags.NonNamespaced, - "Group": namer.IC(g.group), - "GroupGoName": g.groupGoName, - "Version": namer.IC(g.version), - "version": g.version, - "SchemeGroupVersion": c.Universe.Type(types.Name{Package: t.Name.Package, Name: "SchemeGroupVersion"}), - "CreateOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "CreateOptions"}), - "DeleteOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "DeleteOptions"}), - "GetOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "GetOptions"}), - "ListOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ListOptions"}), - "PatchOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "PatchOptions"}), - "ApplyOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ApplyOptions"}), - "UpdateOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "UpdateOptions"}), - "Everything": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/labels", Name: "Everything"}), - "PatchType": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/types", Name: "PatchType"}), - "ApplyPatchType": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/types", Name: "ApplyPatchType"}), - "watchInterface": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/watch", Name: "Interface"}), - "jsonMarshal": c.Universe.Type(types.Name{Package: "encoding/json", Name: "Marshal"}), - - "NewRootListAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootListAction"}), - "NewListAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewListAction"}), - "NewRootGetAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootGetAction"}), - "NewGetAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewGetAction"}), - "NewRootDeleteAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootDeleteAction"}), - "NewRootDeleteActionWithOptions": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootDeleteActionWithOptions"}), - "NewDeleteAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewDeleteAction"}), - "NewDeleteActionWithOptions": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewDeleteActionWithOptions"}), - "NewRootDeleteCollectionAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootDeleteCollectionAction"}), - "NewDeleteCollectionAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewDeleteCollectionAction"}), - "NewRootUpdateAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootUpdateAction"}), - "NewUpdateAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewUpdateAction"}), - "NewRootCreateAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootCreateAction"}), - "NewCreateAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewCreateAction"}), - "NewRootWatchAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootWatchAction"}), - "NewWatchAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewWatchAction"}), - "NewCreateSubresourceAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewCreateSubresourceAction"}), - "NewRootCreateSubresourceAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootCreateSubresourceAction"}), - "NewUpdateSubresourceAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewUpdateSubresourceAction"}), - "NewGetSubresourceAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewGetSubresourceAction"}), - "NewRootGetSubresourceAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootGetSubresourceAction"}), - "NewRootUpdateSubresourceAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootUpdateSubresourceAction"}), - "NewRootPatchAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootPatchAction"}), - "NewPatchAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewPatchAction"}), - "NewRootPatchSubresourceAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewRootPatchSubresourceAction"}), - "NewPatchSubresourceAction": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "NewPatchSubresourceAction"}), - "ExtractFromListOptions": c.Universe.Function(types.Name{Package: pkgClientGoTesting, Name: "ExtractFromListOptions"}), - } - - generateApply := len(g.applyConfigurationPackage) > 0 - if generateApply { - // Generated apply builder type references required for generated Apply function - _, gvString := util.ParsePathGroupVersion(g.inputPackage) - m["inputApplyConfig"] = types.Ref(gopath.Join(g.applyConfigurationPackage, gvString), t.Name.Name+"ApplyConfiguration") - } - - if tags.NonNamespaced { - sw.Do(structNonNamespaced, m) - } else { - sw.Do(structNamespaced, m) - } - - if tags.NoVerbs { - return sw.Error() - } - sw.Do(resource, m) - sw.Do(kind, m) - - if tags.HasVerb("get") { - sw.Do(getTemplate, m) - } - if tags.HasVerb("list") { - if hasObjectMeta(t) { - sw.Do(listUsingOptionsTemplate, m) - } else { - sw.Do(listTemplate, m) - } - } - if tags.HasVerb("watch") { - sw.Do(watchTemplate, m) - } - - if tags.HasVerb("create") { - sw.Do(createTemplate, m) - } - if tags.HasVerb("update") { - sw.Do(updateTemplate, m) - } - if tags.HasVerb("updateStatus") && genStatus(t) { - sw.Do(updateStatusTemplate, m) - } - if tags.HasVerb("delete") { - sw.Do(deleteTemplate, m) - } - if tags.HasVerb("deleteCollection") { - sw.Do(deleteCollectionTemplate, m) - } - if tags.HasVerb("patch") { - sw.Do(patchTemplate, m) - } - if tags.HasVerb("apply") && generateApply { - sw.Do(applyTemplate, m) - } - if tags.HasVerb("applyStatus") && generateApply && genStatus(t) { - sw.Do(applyStatusTemplate, m) - } - _, typeGVString := util.ParsePathGroupVersion(g.inputPackage) - - // generate extended client methods - for _, e := range tags.Extensions { - if e.HasVerb("apply") && !generateApply { - continue - } - inputType := *t - resultType := *t - inputGVString := typeGVString - if len(e.InputTypeOverride) > 0 { - if name, pkg := e.Input(); len(pkg) > 0 { - _, inputGVString = util.ParsePathGroupVersion(pkg) - newType := c.Universe.Type(types.Name{Package: pkg, Name: name}) - inputType = *newType - } else { - inputType.Name.Name = e.InputTypeOverride - } - } - if len(e.ResultTypeOverride) > 0 { - if name, pkg := e.Result(); len(pkg) > 0 { - newType := c.Universe.Type(types.Name{Package: pkg, Name: name}) - resultType = *newType - } else { - resultType.Name.Name = e.ResultTypeOverride - } - } - m["inputType"] = &inputType - m["resultType"] = &resultType - m["subresourcePath"] = e.SubResourcePath - if e.HasVerb("apply") { - m["inputApplyConfig"] = types.Ref(gopath.Join(g.applyConfigurationPackage, inputGVString), inputType.Name.Name+"ApplyConfiguration") - } - - if e.HasVerb("get") { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, getSubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, getTemplate), m) - } - } - - if e.HasVerb("list") { - - sw.Do(adjustTemplate(e.VerbName, e.VerbType, listTemplate), m) - } - - // TODO: Figure out schemantic for watching a sub-resource. - if e.HasVerb("watch") { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, watchTemplate), m) - } - - if e.HasVerb("create") { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, createSubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, createTemplate), m) - } - } - - if e.HasVerb("update") { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, updateSubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, updateTemplate), m) - } - } - - // TODO: Figure out schemantic for deleting a sub-resource (what arguments - // are passed, does it need two names? etc. - if e.HasVerb("delete") { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, deleteTemplate), m) - } - - if e.HasVerb("patch") { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, patchTemplate), m) - } - - if e.HasVerb("apply") && generateApply { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, applySubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, applyTemplate), m) - } - } - } - - return sw.Error() -} - -// adjustTemplate adjust the origin verb template using the expansion name. -// TODO: Make the verbs in templates parametrized so the strings.Replace() is -// not needed. -func adjustTemplate(name, verbType, template string) string { - return strings.Replace(template, " "+strings.Title(verbType), " "+name, -1) -} - -// template for the struct that implements the type's interface -var structNamespaced = ` -// Fake$.type|publicPlural$ implements $.type|public$Interface -type Fake$.type|publicPlural$ struct { - Fake *Fake$.GroupGoName$$.Version$ - ns string -} -` - -// template for the struct that implements the type's interface -var structNonNamespaced = ` -// Fake$.type|publicPlural$ implements $.type|public$Interface -type Fake$.type|publicPlural$ struct { - Fake *Fake$.GroupGoName$$.Version$ -} -` - -var resource = ` -var $.type|allLowercasePlural$Resource = $.SchemeGroupVersion|raw$.WithResource("$.type|resource$") -` - -var kind = ` -var $.type|allLowercasePlural$Kind = $.SchemeGroupVersion|raw$.WithKind("$.type|singularKind$") -` - -var listTemplate = ` -// List takes label and field selectors, and returns the list of $.type|publicPlural$ that match those selectors. -func (c *Fake$.type|publicPlural$) List(ctx context.Context, opts $.ListOptions|raw$) (result *$.type|raw$List, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewListAction|raw$($.type|allLowercasePlural$Resource, $.type|allLowercasePlural$Kind, c.ns, opts), &$.type|raw$List{}) - $else$Invokes($.NewRootListAction|raw$($.type|allLowercasePlural$Resource, $.type|allLowercasePlural$Kind, opts), &$.type|raw$List{})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.type|raw$List), err -} -` - -var listUsingOptionsTemplate = ` -// List takes label and field selectors, and returns the list of $.type|publicPlural$ that match those selectors. -func (c *Fake$.type|publicPlural$) List(ctx context.Context, opts $.ListOptions|raw$) (result *$.type|raw$List, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewListAction|raw$($.type|allLowercasePlural$Resource, $.type|allLowercasePlural$Kind, c.ns, opts), &$.type|raw$List{}) - $else$Invokes($.NewRootListAction|raw$($.type|allLowercasePlural$Resource, $.type|allLowercasePlural$Kind, opts), &$.type|raw$List{})$end$ - if obj == nil { - return nil, err - } - - label, _, _ := $.ExtractFromListOptions|raw$(opts) - if label == nil { - label = $.Everything|raw$() - } - list := &$.type|raw$List{ListMeta: obj.(*$.type|raw$List).ListMeta} - for _, item := range obj.(*$.type|raw$List).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} -` - -var getTemplate = ` -// Get takes name of the $.type|private$, and returns the corresponding $.resultType|private$ object, and an error if there is any. -func (c *Fake$.type|publicPlural$) Get(ctx context.Context, name string, options $.GetOptions|raw$) (result *$.resultType|raw$, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewGetAction|raw$($.type|allLowercasePlural$Resource, c.ns, name), &$.resultType|raw${}) - $else$Invokes($.NewRootGetAction|raw$($.type|allLowercasePlural$Resource, name), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var getSubresourceTemplate = ` -// Get takes name of the $.type|private$, and returns the corresponding $.resultType|private$ object, and an error if there is any. -func (c *Fake$.type|publicPlural$) Get(ctx context.Context, $.type|private$Name string, options $.GetOptions|raw$) (result *$.resultType|raw$, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewGetSubresourceAction|raw$($.type|allLowercasePlural$Resource, c.ns, "$.subresourcePath$", $.type|private$Name), &$.resultType|raw${}) - $else$Invokes($.NewRootGetSubresourceAction|raw$($.type|allLowercasePlural$Resource, "$.subresourcePath$", $.type|private$Name), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var deleteTemplate = ` -// Delete takes name of the $.type|private$ and deletes it. Returns an error if one occurs. -func (c *Fake$.type|publicPlural$) Delete(ctx context.Context, name string, opts $.DeleteOptions|raw$) error { - _, err := c.Fake. - $if .namespaced$Invokes($.NewDeleteActionWithOptions|raw$($.type|allLowercasePlural$Resource, c.ns, name, opts), &$.type|raw${}) - $else$Invokes($.NewRootDeleteActionWithOptions|raw$($.type|allLowercasePlural$Resource, name, opts), &$.type|raw${})$end$ - return err -} -` - -var deleteCollectionTemplate = ` -// DeleteCollection deletes a collection of objects. -func (c *Fake$.type|publicPlural$) DeleteCollection(ctx context.Context, opts $.DeleteOptions|raw$, listOpts $.ListOptions|raw$) error { - $if .namespaced$action := $.NewDeleteCollectionAction|raw$($.type|allLowercasePlural$Resource, c.ns, listOpts) - $else$action := $.NewRootDeleteCollectionAction|raw$($.type|allLowercasePlural$Resource, listOpts) - $end$ - _, err := c.Fake.Invokes(action, &$.type|raw$List{}) - return err -} -` -var createTemplate = ` -// Create takes the representation of a $.inputType|private$ and creates it. Returns the server's representation of the $.resultType|private$, and an error, if there is any. -func (c *Fake$.type|publicPlural$) Create(ctx context.Context, $.inputType|private$ *$.inputType|raw$, opts $.CreateOptions|raw$) (result *$.resultType|raw$, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewCreateAction|raw$($.inputType|allLowercasePlural$Resource, c.ns, $.inputType|private$), &$.resultType|raw${}) - $else$Invokes($.NewRootCreateAction|raw$($.inputType|allLowercasePlural$Resource, $.inputType|private$), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var createSubresourceTemplate = ` -// Create takes the representation of a $.inputType|private$ and creates it. Returns the server's representation of the $.resultType|private$, and an error, if there is any. -func (c *Fake$.type|publicPlural$) Create(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.CreateOptions|raw$) (result *$.resultType|raw$, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewCreateSubresourceAction|raw$($.type|allLowercasePlural$Resource, $.type|private$Name, "$.subresourcePath$", c.ns, $.inputType|private$), &$.resultType|raw${}) - $else$Invokes($.NewRootCreateSubresourceAction|raw$($.type|allLowercasePlural$Resource, $.type|private$Name, "$.subresourcePath$", $.inputType|private$), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var updateTemplate = ` -// Update takes the representation of a $.inputType|private$ and updates it. Returns the server's representation of the $.resultType|private$, and an error, if there is any. -func (c *Fake$.type|publicPlural$) Update(ctx context.Context, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (result *$.resultType|raw$, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewUpdateAction|raw$($.inputType|allLowercasePlural$Resource, c.ns, $.inputType|private$), &$.resultType|raw${}) - $else$Invokes($.NewRootUpdateAction|raw$($.inputType|allLowercasePlural$Resource, $.inputType|private$), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var updateSubresourceTemplate = ` -// Update takes the representation of a $.inputType|private$ and updates it. Returns the server's representation of the $.resultType|private$, and an error, if there is any. -func (c *Fake$.type|publicPlural$) Update(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (result *$.resultType|raw$, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewUpdateSubresourceAction|raw$($.type|allLowercasePlural$Resource, "$.subresourcePath$", c.ns, $.inputType|private$), &$.inputType|raw${}) - $else$Invokes($.NewRootUpdateSubresourceAction|raw$($.type|allLowercasePlural$Resource, "$.subresourcePath$", $.inputType|private$), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var updateStatusTemplate = ` -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *Fake$.type|publicPlural$) UpdateStatus(ctx context.Context, $.type|private$ *$.type|raw$, opts $.UpdateOptions|raw$) (*$.type|raw$, error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewUpdateSubresourceAction|raw$($.type|allLowercasePlural$Resource, "status", c.ns, $.type|private$), &$.type|raw${}) - $else$Invokes($.NewRootUpdateSubresourceAction|raw$($.type|allLowercasePlural$Resource, "status", $.type|private$), &$.type|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.type|raw$), err -} -` - -var watchTemplate = ` -// Watch returns a $.watchInterface|raw$ that watches the requested $.type|privatePlural$. -func (c *Fake$.type|publicPlural$) Watch(ctx context.Context, opts $.ListOptions|raw$) ($.watchInterface|raw$, error) { - return c.Fake. - $if .namespaced$InvokesWatch($.NewWatchAction|raw$($.type|allLowercasePlural$Resource, c.ns, opts)) - $else$InvokesWatch($.NewRootWatchAction|raw$($.type|allLowercasePlural$Resource, opts))$end$ -} -` - -var patchTemplate = ` -// Patch applies the patch and returns the patched $.resultType|private$. -func (c *Fake$.type|publicPlural$) Patch(ctx context.Context, name string, pt $.PatchType|raw$, data []byte, opts $.PatchOptions|raw$, subresources ...string) (result *$.resultType|raw$, err error) { - obj, err := c.Fake. - $if .namespaced$Invokes($.NewPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, c.ns, name, pt, data, subresources... ), &$.resultType|raw${}) - $else$Invokes($.NewRootPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, name, pt, data, subresources...), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var applyTemplate = ` -// Apply takes the given apply declarative configuration, applies it and returns the applied $.resultType|private$. -func (c *Fake$.type|publicPlural$) Apply(ctx context.Context, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error) { - if $.inputType|private$ == nil { - return nil, fmt.Errorf("$.inputType|private$ provided to Apply must not be nil") - } - data, err := $.jsonMarshal|raw$($.inputType|private$) - if err != nil { - return nil, err - } - name := $.inputType|private$.Name - if name == nil { - return nil, fmt.Errorf("$.inputType|private$.Name must be provided to Apply") - } - obj, err := c.Fake. - $if .namespaced$Invokes($.NewPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, c.ns, *name, $.ApplyPatchType|raw$, data), &$.resultType|raw${}) - $else$Invokes($.NewRootPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, *name, $.ApplyPatchType|raw$, data), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var applyStatusTemplate = ` -// ApplyStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *Fake$.type|publicPlural$) ApplyStatus(ctx context.Context, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error) { - if $.inputType|private$ == nil { - return nil, fmt.Errorf("$.inputType|private$ provided to Apply must not be nil") - } - data, err := $.jsonMarshal|raw$($.inputType|private$) - if err != nil { - return nil, err - } - name := $.inputType|private$.Name - if name == nil { - return nil, fmt.Errorf("$.inputType|private$.Name must be provided to Apply") - } - obj, err := c.Fake. - $if .namespaced$Invokes($.NewPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, c.ns, *name, $.ApplyPatchType|raw$, data, "status"), &$.resultType|raw${}) - $else$Invokes($.NewRootPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, *name, $.ApplyPatchType|raw$, data, "status"), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` - -var applySubresourceTemplate = ` -// Apply takes top resource name and the apply declarative configuration for $.subresourcePath$, -// applies it and returns the applied $.resultType|private$, and an error, if there is any. -func (c *Fake$.type|publicPlural$) Apply(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error) { - if $.inputType|private$ == nil { - return nil, fmt.Errorf("$.inputType|private$ provided to Apply must not be nil") - } - data, err := $.jsonMarshal|raw$($.inputType|private$) - if err != nil { - return nil, err - } - obj, err := c.Fake. - $if .namespaced$Invokes($.NewPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, c.ns, $.type|private$Name, $.ApplyPatchType|raw$, data, "status"), &$.resultType|raw${}) - $else$Invokes($.NewRootPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, $.type|private$Name, $.ApplyPatchType|raw$, data, "status"), &$.resultType|raw${})$end$ - if obj == nil { - return nil, err - } - return obj.(*$.resultType|raw$), err -} -` diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go deleted file mode 100644 index 6bf1ca37..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go +++ /dev/null @@ -1,209 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "io" - "path/filepath" - "strings" - - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// genClientset generates a package for a clientset. -type genClientset struct { - generator.DefaultGen - groups []clientgentypes.GroupVersions - groupGoNames map[clientgentypes.GroupVersion]string - clientsetPackage string - outputPackage string - imports namer.ImportTracker - clientsetGenerated bool -} - -var _ generator.Generator = &genClientset{} - -func (g *genClientset) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -// We only want to call GenerateType() once. -func (g *genClientset) Filter(c *generator.Context, t *types.Type) bool { - ret := !g.clientsetGenerated - g.clientsetGenerated = true - return ret -} - -func (g *genClientset) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - for _, group := range g.groups { - for _, version := range group.Versions { - typedClientPath := filepath.Join(g.clientsetPackage, "typed", strings.ToLower(group.PackageName), strings.ToLower(version.NonEmpty())) - groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{Group: group.Group, Version: version.Version}]) - imports = append(imports, fmt.Sprintf("%s%s \"%s\"", groupAlias, strings.ToLower(version.NonEmpty()), typedClientPath)) - } - } - return -} - -func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - // TODO: We actually don't need any type information to generate the clientset, - // perhaps we can adapt the go2ild framework to this kind of usage. - sw := generator.NewSnippetWriter(w, c, "$", "$") - - allGroups := clientgentypes.ToGroupVersionInfo(g.groups, g.groupGoNames) - m := map[string]interface{}{ - "allGroups": allGroups, - "Config": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}), - "DefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: "k8s.io/client-go/rest", Name: "DefaultKubernetesUserAgent"}), - "RESTClientInterface": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Interface"}), - "RESTHTTPClientFor": c.Universe.Function(types.Name{Package: "k8s.io/client-go/rest", Name: "HTTPClientFor"}), - "DiscoveryInterface": c.Universe.Type(types.Name{Package: "k8s.io/client-go/discovery", Name: "DiscoveryInterface"}), - "DiscoveryClient": c.Universe.Type(types.Name{Package: "k8s.io/client-go/discovery", Name: "DiscoveryClient"}), - "NewDiscoveryClientForConfigAndClient": c.Universe.Function(types.Name{Package: "k8s.io/client-go/discovery", Name: "NewDiscoveryClientForConfigAndClient"}), - "NewDiscoveryClientForConfigOrDie": c.Universe.Function(types.Name{Package: "k8s.io/client-go/discovery", Name: "NewDiscoveryClientForConfigOrDie"}), - "NewDiscoveryClient": c.Universe.Function(types.Name{Package: "k8s.io/client-go/discovery", Name: "NewDiscoveryClient"}), - "flowcontrolNewTokenBucketRateLimiter": c.Universe.Function(types.Name{Package: "k8s.io/client-go/util/flowcontrol", Name: "NewTokenBucketRateLimiter"}), - } - sw.Do(clientsetInterface, m) - sw.Do(clientsetTemplate, m) - for _, g := range allGroups { - sw.Do(clientsetInterfaceImplTemplate, g) - } - sw.Do(getDiscoveryTemplate, m) - sw.Do(newClientsetForConfigTemplate, m) - sw.Do(newClientsetForConfigAndClientTemplate, m) - sw.Do(newClientsetForConfigOrDieTemplate, m) - sw.Do(newClientsetForRESTClientTemplate, m) - - return sw.Error() -} - -var clientsetInterface = ` -type Interface interface { - Discovery() $.DiscoveryInterface|raw$ - $range .allGroups$$.GroupGoName$$.Version$() $.PackageAlias$.$.GroupGoName$$.Version$Interface - $end$ -} -` - -var clientsetTemplate = ` -// Clientset contains the clients for groups. -type Clientset struct { - *$.DiscoveryClient|raw$ - $range .allGroups$$.LowerCaseGroupGoName$$.Version$ *$.PackageAlias$.$.GroupGoName$$.Version$Client - $end$ -} -` - -var clientsetInterfaceImplTemplate = ` -// $.GroupGoName$$.Version$ retrieves the $.GroupGoName$$.Version$Client -func (c *Clientset) $.GroupGoName$$.Version$() $.PackageAlias$.$.GroupGoName$$.Version$Interface { - return c.$.LowerCaseGroupGoName$$.Version$ -} -` - -var getDiscoveryTemplate = ` -// Discovery retrieves the DiscoveryClient -func (c *Clientset) Discovery() $.DiscoveryInterface|raw$ { - if c == nil { - return nil - } - return c.DiscoveryClient -} -` - -var newClientsetForConfigTemplate = ` -// NewForConfig creates a new Clientset for the given config. -// If config's RateLimiter is not set and QPS and Burst are acceptable, -// NewForConfig will generate a rate-limiter in configShallowCopy. -// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), -// where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(c *$.Config|raw$) (*Clientset, error) { - configShallowCopy := *c - - if configShallowCopy.UserAgent == "" { - configShallowCopy.UserAgent = $.DefaultKubernetesUserAgent|raw$() - } - - // share the transport between all clients - httpClient, err := $.RESTHTTPClientFor|raw$(&configShallowCopy) - if err != nil { - return nil, err - } - - return NewForConfigAndClient(&configShallowCopy, httpClient) -} -` - -var newClientsetForConfigAndClientTemplate = ` -// NewForConfigAndClient creates a new Clientset for the given config and http client. -// Note the http client provided takes precedence over the configured transport values. -// If config's RateLimiter is not set and QPS and Burst are acceptable, -// NewForConfigAndClient will generate a rate-limiter in configShallowCopy. -func NewForConfigAndClient(c *$.Config|raw$, httpClient *http.Client) (*Clientset, error) { - configShallowCopy := *c - if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { - if configShallowCopy.Burst <= 0 { - return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") - } - configShallowCopy.RateLimiter = $.flowcontrolNewTokenBucketRateLimiter|raw$(configShallowCopy.QPS, configShallowCopy.Burst) - } - - var cs Clientset - var err error -$range .allGroups$ cs.$.LowerCaseGroupGoName$$.Version$, err =$.PackageAlias$.NewForConfigAndClient(&configShallowCopy, httpClient) - if err!=nil { - return nil, err - } -$end$ - cs.DiscoveryClient, err = $.NewDiscoveryClientForConfigAndClient|raw$(&configShallowCopy, httpClient) - if err!=nil { - return nil, err - } - return &cs, nil -} -` - -var newClientsetForConfigOrDieTemplate = ` -// NewForConfigOrDie creates a new Clientset for the given config and -// panics if there is an error in the config. -func NewForConfigOrDie(c *$.Config|raw$) *Clientset { - cs, err := NewForConfig(c) - if err!=nil { - panic(err) - } - return cs -} -` - -var newClientsetForRESTClientTemplate = ` -// New creates a new Clientset for the given RESTClient. -func New(c $.RESTClientInterface|raw$) *Clientset { - var cs Clientset -$range .allGroups$ cs.$.LowerCaseGroupGoName$$.Version$ =$.PackageAlias$.New(c) -$end$ - cs.DiscoveryClient = $.NewDiscoveryClient|raw$(c) - return &cs -} -` diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_expansion.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_expansion.go deleted file mode 100644 index f47c079e..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_expansion.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "os" - "path/filepath" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/types" -) - -// genExpansion produces a file for a group client, e.g. ExtensionsClient for the extension group. -type genExpansion struct { - generator.DefaultGen - groupPackagePath string - // types in a group - types []*types.Type -} - -// We only want to call GenerateType() once per group. -func (g *genExpansion) Filter(c *generator.Context, t *types.Type) bool { - return len(g.types) == 0 || t == g.types[0] -} - -func (g *genExpansion) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - for _, t := range g.types { - if _, err := os.Stat(filepath.Join(g.groupPackagePath, strings.ToLower(t.Name.Name+"_expansion.go"))); os.IsNotExist(err) { - sw.Do(expansionInterfaceTemplate, t) - } - } - return sw.Error() -} - -var expansionInterfaceTemplate = ` -type $.|public$Expansion interface {} -` diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_group.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_group.go deleted file mode 100644 index 30284990..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_group.go +++ /dev/null @@ -1,267 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "path/filepath" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" - "k8s.io/code-generator/cmd/client-gen/path" -) - -// genGroup produces a file for a group client, e.g. ExtensionsClient for the extension group. -type genGroup struct { - generator.DefaultGen - outputPackage string - group string - version string - groupGoName string - apiPath string - // types in this group - types []*types.Type - imports namer.ImportTracker - inputPackage string - clientsetPackage string - // If the genGroup has been called. This generator should only execute once. - called bool -} - -var _ generator.Generator = &genGroup{} - -// We only want to call GenerateType() once per group. -func (g *genGroup) Filter(c *generator.Context, t *types.Type) bool { - if !g.called { - g.called = true - return true - } - return false -} - -func (g *genGroup) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *genGroup) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - imports = append(imports, filepath.Join(g.clientsetPackage, "scheme")) - return -} - -func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - apiPath := func(group string) string { - if group == "core" { - return `"/api"` - } - return `"` + g.apiPath + `"` - } - - groupName := g.group - if g.group == "core" { - groupName = "" - } - // allow user to define a group name that's different from the one parsed from the directory. - p := c.Universe.Package(path.Vendorless(g.inputPackage)) - if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { - groupName = override[0] - } - - m := map[string]interface{}{ - "group": g.group, - "version": g.version, - "groupName": groupName, - "GroupGoName": g.groupGoName, - "Version": namer.IC(g.version), - "types": g.types, - "apiPath": apiPath(g.group), - "schemaGroupVersion": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupVersion"}), - "runtimeAPIVersionInternal": c.Universe.Variable(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "APIVersionInternal"}), - "restConfig": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}), - "restDefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: "k8s.io/client-go/rest", Name: "DefaultKubernetesUserAgent"}), - "restRESTClientInterface": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Interface"}), - "RESTHTTPClientFor": c.Universe.Function(types.Name{Package: "k8s.io/client-go/rest", Name: "HTTPClientFor"}), - "restRESTClientFor": c.Universe.Function(types.Name{Package: "k8s.io/client-go/rest", Name: "RESTClientFor"}), - "restRESTClientForConfigAndClient": c.Universe.Function(types.Name{Package: "k8s.io/client-go/rest", Name: "RESTClientForConfigAndClient"}), - "SchemeGroupVersion": c.Universe.Variable(types.Name{Package: path.Vendorless(g.inputPackage), Name: "SchemeGroupVersion"}), - } - sw.Do(groupInterfaceTemplate, m) - sw.Do(groupClientTemplate, m) - for _, t := range g.types { - tags, err := util.ParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if err != nil { - return err - } - wrapper := map[string]interface{}{ - "type": t, - "GroupGoName": g.groupGoName, - "Version": namer.IC(g.version), - } - if tags.NonNamespaced { - sw.Do(getterImplNonNamespaced, wrapper) - } else { - sw.Do(getterImplNamespaced, wrapper) - } - } - sw.Do(newClientForConfigTemplate, m) - sw.Do(newClientForConfigAndClientTemplate, m) - sw.Do(newClientForConfigOrDieTemplate, m) - sw.Do(newClientForRESTClientTemplate, m) - if g.version == "" { - sw.Do(setInternalVersionClientDefaultsTemplate, m) - } else { - sw.Do(setClientDefaultsTemplate, m) - } - sw.Do(getRESTClient, m) - - return sw.Error() -} - -var groupInterfaceTemplate = ` -type $.GroupGoName$$.Version$Interface interface { - RESTClient() $.restRESTClientInterface|raw$ - $range .types$ $.|publicPlural$Getter - $end$ -} -` - -var groupClientTemplate = ` -// $.GroupGoName$$.Version$Client is used to interact with features provided by the $.groupName$ group. -type $.GroupGoName$$.Version$Client struct { - restClient $.restRESTClientInterface|raw$ -} -` - -var getterImplNamespaced = ` -func (c *$.GroupGoName$$.Version$Client) $.type|publicPlural$(namespace string) $.type|public$Interface { - return new$.type|publicPlural$(c, namespace) -} -` - -var getterImplNonNamespaced = ` -func (c *$.GroupGoName$$.Version$Client) $.type|publicPlural$() $.type|public$Interface { - return new$.type|publicPlural$(c) -} -` - -var newClientForConfigTemplate = ` -// NewForConfig creates a new $.GroupGoName$$.Version$Client for the given config. -// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), -// where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(c *$.restConfig|raw$) (*$.GroupGoName$$.Version$Client, error) { - config := *c - if err := setConfigDefaults(&config); err != nil { - return nil, err - } - httpClient, err := $.RESTHTTPClientFor|raw$(&config) - if err != nil { - return nil, err - } - return NewForConfigAndClient(&config, httpClient) -} -` - -var newClientForConfigAndClientTemplate = ` -// NewForConfigAndClient creates a new $.GroupGoName$$.Version$Client for the given config and http client. -// Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *$.restConfig|raw$, h *http.Client) (*$.GroupGoName$$.Version$Client, error) { - config := *c - if err := setConfigDefaults(&config); err != nil { - return nil, err - } - client, err := $.restRESTClientForConfigAndClient|raw$(&config, h) - if err != nil { - return nil, err - } - return &$.GroupGoName$$.Version$Client{client}, nil -} -` - -var newClientForConfigOrDieTemplate = ` -// NewForConfigOrDie creates a new $.GroupGoName$$.Version$Client for the given config and -// panics if there is an error in the config. -func NewForConfigOrDie(c *$.restConfig|raw$) *$.GroupGoName$$.Version$Client { - client, err := NewForConfig(c) - if err != nil { - panic(err) - } - return client -} -` - -var getRESTClient = ` -// RESTClient returns a RESTClient that is used to communicate -// with API server by this client implementation. -func (c *$.GroupGoName$$.Version$Client) RESTClient() $.restRESTClientInterface|raw$ { - if c == nil { - return nil - } - return c.restClient -} -` - -var newClientForRESTClientTemplate = ` -// New creates a new $.GroupGoName$$.Version$Client for the given RESTClient. -func New(c $.restRESTClientInterface|raw$) *$.GroupGoName$$.Version$Client { - return &$.GroupGoName$$.Version$Client{c} -} -` - -var setInternalVersionClientDefaultsTemplate = ` -func setConfigDefaults(config *$.restConfig|raw$) error { - config.APIPath = $.apiPath$ - if config.UserAgent == "" { - config.UserAgent = $.restDefaultKubernetesUserAgent|raw$() - } - if config.GroupVersion == nil || config.GroupVersion.Group != scheme.Scheme.PrioritizedVersionsForGroup("$.groupName$")[0].Group { - gv := scheme.Scheme.PrioritizedVersionsForGroup("$.groupName$")[0] - config.GroupVersion = &gv - } - config.NegotiatedSerializer = scheme.Codecs - - if config.QPS == 0 { - config.QPS = 5 - } - if config.Burst == 0 { - config.Burst = 10 - } - - return nil -} -` - -var setClientDefaultsTemplate = ` -func setConfigDefaults(config *$.restConfig|raw$) error { - gv := $.SchemeGroupVersion|raw$ - config.GroupVersion = &gv - config.APIPath = $.apiPath$ - config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() - - if config.UserAgent == "" { - config.UserAgent = $.restDefaultKubernetesUserAgent|raw$() - } - - return nil -} -` diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_type.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_type.go deleted file mode 100644 index fe63dd19..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/generator_for_type.go +++ /dev/null @@ -1,760 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "path" - "path/filepath" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" -) - -// genClientForType produces a file for each top-level type. -type genClientForType struct { - generator.DefaultGen - outputPackage string - inputPackage string - clientsetPackage string - applyConfigurationPackage string - group string - version string - groupGoName string - typeToMatch *types.Type - imports namer.ImportTracker -} - -var _ generator.Generator = &genClientForType{} - -// Filter ignores all but one type because we're making a single file per type. -func (g *genClientForType) Filter(c *generator.Context, t *types.Type) bool { - return t == g.typeToMatch -} - -func (g *genClientForType) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *genClientForType) Imports(c *generator.Context) (imports []string) { - return g.imports.ImportLines() -} - -// Ideally, we'd like genStatus to return true if there is a subresource path -// registered for "status" in the API server, but we do not have that -// information, so genStatus returns true if the type has a status field. -func genStatus(t *types.Type) bool { - // Default to true if we have a Status member - hasStatus := false - for _, m := range t.Members { - if m.Name == "Status" { - hasStatus = true - break - } - } - return hasStatus && !util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)).NoStatus -} - -// GenerateType makes the body of a file implementing the individual typed client for type t. -func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - generateApply := len(g.applyConfigurationPackage) > 0 - defaultVerbTemplates := buildDefaultVerbTemplates(generateApply) - subresourceDefaultVerbTemplates := buildSubresourceDefaultVerbTemplates(generateApply) - sw := generator.NewSnippetWriter(w, c, "$", "$") - pkg := filepath.Base(t.Name.Package) - tags, err := util.ParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if err != nil { - return err - } - type extendedInterfaceMethod struct { - template string - args map[string]interface{} - } - _, typeGVString := util.ParsePathGroupVersion(g.inputPackage) - extendedMethods := []extendedInterfaceMethod{} - for _, e := range tags.Extensions { - if e.HasVerb("apply") && !generateApply { - continue - } - inputType := *t - resultType := *t - inputGVString := typeGVString - // TODO: Extract this to some helper method as this code is copied into - // 2 other places. - if len(e.InputTypeOverride) > 0 { - if name, pkg := e.Input(); len(pkg) > 0 { - _, inputGVString = util.ParsePathGroupVersion(pkg) - newType := c.Universe.Type(types.Name{Package: pkg, Name: name}) - inputType = *newType - } else { - inputType.Name.Name = e.InputTypeOverride - } - } - if len(e.ResultTypeOverride) > 0 { - if name, pkg := e.Result(); len(pkg) > 0 { - newType := c.Universe.Type(types.Name{Package: pkg, Name: name}) - resultType = *newType - } else { - resultType.Name.Name = e.ResultTypeOverride - } - } - var updatedVerbtemplate string - if _, exists := subresourceDefaultVerbTemplates[e.VerbType]; e.IsSubresource() && exists { - updatedVerbtemplate = e.VerbName + "(" + strings.TrimPrefix(subresourceDefaultVerbTemplates[e.VerbType], strings.Title(e.VerbType)+"(") - } else { - updatedVerbtemplate = e.VerbName + "(" + strings.TrimPrefix(defaultVerbTemplates[e.VerbType], strings.Title(e.VerbType)+"(") - } - extendedMethod := extendedInterfaceMethod{ - template: updatedVerbtemplate, - args: map[string]interface{}{ - "type": t, - "inputType": &inputType, - "resultType": &resultType, - "CreateOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "CreateOptions"}), - "GetOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "GetOptions"}), - "ListOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ListOptions"}), - "UpdateOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "UpdateOptions"}), - "ApplyOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ApplyOptions"}), - "PatchType": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/types", Name: "PatchType"}), - "jsonMarshal": c.Universe.Type(types.Name{Package: "encoding/json", Name: "Marshal"}), - }, - } - if e.HasVerb("apply") { - extendedMethod.args["inputApplyConfig"] = types.Ref(path.Join(g.applyConfigurationPackage, inputGVString), inputType.Name.Name+"ApplyConfiguration") - } - extendedMethods = append(extendedMethods, extendedMethod) - } - m := map[string]interface{}{ - "type": t, - "inputType": t, - "resultType": t, - "package": pkg, - "Package": namer.IC(pkg), - "namespaced": !tags.NonNamespaced, - "Group": namer.IC(g.group), - "subresource": false, - "subresourcePath": "", - "GroupGoName": g.groupGoName, - "Version": namer.IC(g.version), - "CreateOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "CreateOptions"}), - "DeleteOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "DeleteOptions"}), - "GetOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "GetOptions"}), - "ListOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ListOptions"}), - "PatchOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "PatchOptions"}), - "ApplyOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ApplyOptions"}), - "UpdateOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "UpdateOptions"}), - "PatchType": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/types", Name: "PatchType"}), - "ApplyPatchType": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/types", Name: "ApplyPatchType"}), - "watchInterface": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/watch", Name: "Interface"}), - "RESTClientInterface": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Interface"}), - "schemeParameterCodec": c.Universe.Variable(types.Name{Package: filepath.Join(g.clientsetPackage, "scheme"), Name: "ParameterCodec"}), - "jsonMarshal": c.Universe.Type(types.Name{Package: "encoding/json", Name: "Marshal"}), - } - - if generateApply { - // Generated apply configuration type references required for generated Apply function - _, gvString := util.ParsePathGroupVersion(g.inputPackage) - m["inputApplyConfig"] = types.Ref(path.Join(g.applyConfigurationPackage, gvString), t.Name.Name+"ApplyConfiguration") - } - - sw.Do(getterComment, m) - if tags.NonNamespaced { - sw.Do(getterNonNamespaced, m) - } else { - sw.Do(getterNamespaced, m) - } - - sw.Do(interfaceTemplate1, m) - if !tags.NoVerbs { - if !genStatus(t) { - tags.SkipVerbs = append(tags.SkipVerbs, "updateStatus") - tags.SkipVerbs = append(tags.SkipVerbs, "applyStatus") - } - interfaceSuffix := "" - if len(extendedMethods) > 0 { - interfaceSuffix = "\n" - } - sw.Do("\n"+generateInterface(defaultVerbTemplates, tags)+interfaceSuffix, m) - // add extended verbs into interface - for _, v := range extendedMethods { - sw.Do(v.template+interfaceSuffix, v.args) - } - - } - sw.Do(interfaceTemplate4, m) - - if tags.NonNamespaced { - sw.Do(structNonNamespaced, m) - sw.Do(newStructNonNamespaced, m) - } else { - sw.Do(structNamespaced, m) - sw.Do(newStructNamespaced, m) - } - - if tags.NoVerbs { - return sw.Error() - } - - if tags.HasVerb("get") { - sw.Do(getTemplate, m) - } - if tags.HasVerb("list") { - sw.Do(listTemplate, m) - } - if tags.HasVerb("watch") { - sw.Do(watchTemplate, m) - } - - if tags.HasVerb("create") { - sw.Do(createTemplate, m) - } - if tags.HasVerb("update") { - sw.Do(updateTemplate, m) - } - if tags.HasVerb("updateStatus") { - sw.Do(updateStatusTemplate, m) - } - if tags.HasVerb("delete") { - sw.Do(deleteTemplate, m) - } - if tags.HasVerb("deleteCollection") { - sw.Do(deleteCollectionTemplate, m) - } - if tags.HasVerb("patch") { - sw.Do(patchTemplate, m) - } - if tags.HasVerb("apply") && generateApply { - sw.Do(applyTemplate, m) - } - if tags.HasVerb("applyStatus") && generateApply { - sw.Do(applyStatusTemplate, m) - } - - // generate expansion methods - for _, e := range tags.Extensions { - if e.HasVerb("apply") && !generateApply { - continue - } - inputType := *t - resultType := *t - inputGVString := typeGVString - if len(e.InputTypeOverride) > 0 { - if name, pkg := e.Input(); len(pkg) > 0 { - _, inputGVString = util.ParsePathGroupVersion(pkg) - newType := c.Universe.Type(types.Name{Package: pkg, Name: name}) - inputType = *newType - } else { - inputType.Name.Name = e.InputTypeOverride - } - } - if len(e.ResultTypeOverride) > 0 { - if name, pkg := e.Result(); len(pkg) > 0 { - newType := c.Universe.Type(types.Name{Package: pkg, Name: name}) - resultType = *newType - } else { - resultType.Name.Name = e.ResultTypeOverride - } - } - m["inputType"] = &inputType - m["resultType"] = &resultType - m["subresourcePath"] = e.SubResourcePath - if e.HasVerb("apply") { - m["inputApplyConfig"] = types.Ref(path.Join(g.applyConfigurationPackage, inputGVString), inputType.Name.Name+"ApplyConfiguration") - } - - if e.HasVerb("get") { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, getSubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, getTemplate), m) - } - } - - if e.HasVerb("list") { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, listSubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, listTemplate), m) - } - } - - // TODO: Figure out schemantic for watching a sub-resource. - if e.HasVerb("watch") { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, watchTemplate), m) - } - - if e.HasVerb("create") { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, createSubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, createTemplate), m) - } - } - - if e.HasVerb("update") { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, updateSubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, updateTemplate), m) - } - } - - // TODO: Figure out schemantic for deleting a sub-resource (what arguments - // are passed, does it need two names? etc. - if e.HasVerb("delete") { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, deleteTemplate), m) - } - - if e.HasVerb("patch") { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, patchTemplate), m) - } - - if e.HasVerb("apply") { - if e.IsSubresource() { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, applySubresourceTemplate), m) - } else { - sw.Do(adjustTemplate(e.VerbName, e.VerbType, applyTemplate), m) - } - } - } - - return sw.Error() -} - -// adjustTemplate adjust the origin verb template using the expansion name. -// TODO: Make the verbs in templates parametrized so the strings.Replace() is -// not needed. -func adjustTemplate(name, verbType, template string) string { - return strings.Replace(template, " "+strings.Title(verbType), " "+name, -1) -} - -func generateInterface(defaultVerbTemplates map[string]string, tags util.Tags) string { - // need an ordered list here to guarantee order of generated methods. - out := []string{} - for _, m := range util.SupportedVerbs { - if tags.HasVerb(m) && len(defaultVerbTemplates[m]) > 0 { - out = append(out, defaultVerbTemplates[m]) - } - } - return strings.Join(out, "\n") -} - -func buildSubresourceDefaultVerbTemplates(generateApply bool) map[string]string { - m := map[string]string{ - "create": `Create(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.CreateOptions|raw$) (*$.resultType|raw$, error)`, - "list": `List(ctx context.Context, $.type|private$Name string, opts $.ListOptions|raw$) (*$.resultType|raw$List, error)`, - "update": `Update(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (*$.resultType|raw$, error)`, - "get": `Get(ctx context.Context, $.type|private$Name string, options $.GetOptions|raw$) (*$.resultType|raw$, error)`, - } - if generateApply { - m["apply"] = `Apply(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (*$.resultType|raw$, error)` - } - return m -} - -func buildDefaultVerbTemplates(generateApply bool) map[string]string { - m := map[string]string{ - "create": `Create(ctx context.Context, $.inputType|private$ *$.inputType|raw$, opts $.CreateOptions|raw$) (*$.resultType|raw$, error)`, - "update": `Update(ctx context.Context, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (*$.resultType|raw$, error)`, - "updateStatus": `UpdateStatus(ctx context.Context, $.inputType|private$ *$.type|raw$, opts $.UpdateOptions|raw$) (*$.type|raw$, error)`, - "delete": `Delete(ctx context.Context, name string, opts $.DeleteOptions|raw$) error`, - "deleteCollection": `DeleteCollection(ctx context.Context, opts $.DeleteOptions|raw$, listOpts $.ListOptions|raw$) error`, - "get": `Get(ctx context.Context, name string, opts $.GetOptions|raw$) (*$.resultType|raw$, error)`, - "list": `List(ctx context.Context, opts $.ListOptions|raw$) (*$.resultType|raw$List, error)`, - "watch": `Watch(ctx context.Context, opts $.ListOptions|raw$) ($.watchInterface|raw$, error)`, - "patch": `Patch(ctx context.Context, name string, pt $.PatchType|raw$, data []byte, opts $.PatchOptions|raw$, subresources ...string) (result *$.resultType|raw$, err error)`, - } - if generateApply { - m["apply"] = `Apply(ctx context.Context, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error)` - m["applyStatus"] = `ApplyStatus(ctx context.Context, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error)` - } - return m -} - -// group client will implement this interface. -var getterComment = ` -// $.type|publicPlural$Getter has a method to return a $.type|public$Interface. -// A group's client should implement this interface.` - -var getterNamespaced = ` -type $.type|publicPlural$Getter interface { - $.type|publicPlural$(namespace string) $.type|public$Interface -} -` - -var getterNonNamespaced = ` -type $.type|publicPlural$Getter interface { - $.type|publicPlural$() $.type|public$Interface -} -` - -// this type's interface, typed client will implement this interface. -var interfaceTemplate1 = ` -// $.type|public$Interface has methods to work with $.type|public$ resources. -type $.type|public$Interface interface {` - -var interfaceTemplate4 = ` - $.type|public$Expansion -} -` - -// template for the struct that implements the type's interface -var structNamespaced = ` -// $.type|privatePlural$ implements $.type|public$Interface -type $.type|privatePlural$ struct { - client $.RESTClientInterface|raw$ - ns string -} -` - -// template for the struct that implements the type's interface -var structNonNamespaced = ` -// $.type|privatePlural$ implements $.type|public$Interface -type $.type|privatePlural$ struct { - client $.RESTClientInterface|raw$ -} -` - -var newStructNamespaced = ` -// new$.type|publicPlural$ returns a $.type|publicPlural$ -func new$.type|publicPlural$(c *$.GroupGoName$$.Version$Client, namespace string) *$.type|privatePlural$ { - return &$.type|privatePlural${ - client: c.RESTClient(), - ns: namespace, - } -} -` - -var newStructNonNamespaced = ` -// new$.type|publicPlural$ returns a $.type|publicPlural$ -func new$.type|publicPlural$(c *$.GroupGoName$$.Version$Client) *$.type|privatePlural$ { - return &$.type|privatePlural${ - client: c.RESTClient(), - } -} -` -var listTemplate = ` -// List takes label and field selectors, and returns the list of $.resultType|publicPlural$ that match those selectors. -func (c *$.type|privatePlural$) List(ctx context.Context, opts $.ListOptions|raw$) (result *$.resultType|raw$List, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil{ - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &$.resultType|raw$List{} - err = c.client.Get(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Timeout(timeout). - Do(ctx). - Into(result) - return -} -` - -var listSubresourceTemplate = ` -// List takes $.type|raw$ name, label and field selectors, and returns the list of $.resultType|publicPlural$ that match those selectors. -func (c *$.type|privatePlural$) List(ctx context.Context, $.type|private$Name string, opts $.ListOptions|raw$) (result *$.resultType|raw$List, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil{ - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &$.resultType|raw$List{} - err = c.client.Get(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name($.type|private$Name). - SubResource("$.subresourcePath$"). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Timeout(timeout). - Do(ctx). - Into(result) - return -} -` - -var getTemplate = ` -// Get takes name of the $.type|private$, and returns the corresponding $.resultType|private$ object, and an error if there is any. -func (c *$.type|privatePlural$) Get(ctx context.Context, name string, options $.GetOptions|raw$) (result *$.resultType|raw$, err error) { - result = &$.resultType|raw${} - err = c.client.Get(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name(name). - VersionedParams(&options, $.schemeParameterCodec|raw$). - Do(ctx). - Into(result) - return -} -` - -var getSubresourceTemplate = ` -// Get takes name of the $.type|private$, and returns the corresponding $.resultType|raw$ object, and an error if there is any. -func (c *$.type|privatePlural$) Get(ctx context.Context, $.type|private$Name string, options $.GetOptions|raw$) (result *$.resultType|raw$, err error) { - result = &$.resultType|raw${} - err = c.client.Get(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name($.type|private$Name). - SubResource("$.subresourcePath$"). - VersionedParams(&options, $.schemeParameterCodec|raw$). - Do(ctx). - Into(result) - return -} -` - -var deleteTemplate = ` -// Delete takes name of the $.type|private$ and deletes it. Returns an error if one occurs. -func (c *$.type|privatePlural$) Delete(ctx context.Context, name string, opts $.DeleteOptions|raw$) error { - return c.client.Delete(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} -` - -var deleteCollectionTemplate = ` -// DeleteCollection deletes a collection of objects. -func (c *$.type|privatePlural$) DeleteCollection(ctx context.Context, opts $.DeleteOptions|raw$, listOpts $.ListOptions|raw$) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil{ - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - VersionedParams(&listOpts, $.schemeParameterCodec|raw$). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} -` - -var createSubresourceTemplate = ` -// Create takes the representation of a $.inputType|private$ and creates it. Returns the server's representation of the $.resultType|private$, and an error, if there is any. -func (c *$.type|privatePlural$) Create(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.CreateOptions|raw$) (result *$.resultType|raw$, err error) { - result = &$.resultType|raw${} - err = c.client.Post(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name($.type|private$Name). - SubResource("$.subresourcePath$"). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Body($.inputType|private$). - Do(ctx). - Into(result) - return -} -` - -var createTemplate = ` -// Create takes the representation of a $.inputType|private$ and creates it. Returns the server's representation of the $.resultType|private$, and an error, if there is any. -func (c *$.type|privatePlural$) Create(ctx context.Context, $.inputType|private$ *$.inputType|raw$, opts $.CreateOptions|raw$) (result *$.resultType|raw$, err error) { - result = &$.resultType|raw${} - err = c.client.Post(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Body($.inputType|private$). - Do(ctx). - Into(result) - return -} -` - -var updateSubresourceTemplate = ` -// Update takes the top resource name and the representation of a $.inputType|private$ and updates it. Returns the server's representation of the $.resultType|private$, and an error, if there is any. -func (c *$.type|privatePlural$) Update(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (result *$.resultType|raw$, err error) { - result = &$.resultType|raw${} - err = c.client.Put(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name($.type|private$Name). - SubResource("$.subresourcePath$"). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Body($.inputType|private$). - Do(ctx). - Into(result) - return -} -` - -var updateTemplate = ` -// Update takes the representation of a $.inputType|private$ and updates it. Returns the server's representation of the $.resultType|private$, and an error, if there is any. -func (c *$.type|privatePlural$) Update(ctx context.Context, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (result *$.resultType|raw$, err error) { - result = &$.resultType|raw${} - err = c.client.Put(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name($.inputType|private$.Name). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Body($.inputType|private$). - Do(ctx). - Into(result) - return -} -` - -var updateStatusTemplate = ` -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *$.type|privatePlural$) UpdateStatus(ctx context.Context, $.type|private$ *$.type|raw$, opts $.UpdateOptions|raw$) (result *$.type|raw$, err error) { - result = &$.type|raw${} - err = c.client.Put(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name($.type|private$.Name). - SubResource("status"). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Body($.type|private$). - Do(ctx). - Into(result) - return -} -` - -var watchTemplate = ` -// Watch returns a $.watchInterface|raw$ that watches the requested $.type|privatePlural$. -func (c *$.type|privatePlural$) Watch(ctx context.Context, opts $.ListOptions|raw$) ($.watchInterface|raw$, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil{ - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Timeout(timeout). - Watch(ctx) -} -` - -var patchTemplate = ` -// Patch applies the patch and returns the patched $.resultType|private$. -func (c *$.type|privatePlural$) Patch(ctx context.Context, name string, pt $.PatchType|raw$, data []byte, opts $.PatchOptions|raw$, subresources ...string) (result *$.resultType|raw$, err error) { - result = &$.resultType|raw${} - err = c.client.Patch(pt). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, $.schemeParameterCodec|raw$). - Body(data). - Do(ctx). - Into(result) - return -} -` - -var applyTemplate = ` -// Apply takes the given apply declarative configuration, applies it and returns the applied $.resultType|private$. -func (c *$.type|privatePlural$) Apply(ctx context.Context, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error) { - if $.inputType|private$ == nil { - return nil, fmt.Errorf("$.inputType|private$ provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := $.jsonMarshal|raw$($.inputType|private$) - if err != nil { - return nil, err - } - name := $.inputType|private$.Name - if name == nil { - return nil, fmt.Errorf("$.inputType|private$.Name must be provided to Apply") - } - result = &$.resultType|raw${} - err = c.client.Patch($.ApplyPatchType|raw$). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name(*name). - VersionedParams(&patchOpts, $.schemeParameterCodec|raw$). - Body(data). - Do(ctx). - Into(result) - return -} -` - -var applyStatusTemplate = ` -// ApplyStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *$.type|privatePlural$) ApplyStatus(ctx context.Context, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error) { - if $.inputType|private$ == nil { - return nil, fmt.Errorf("$.inputType|private$ provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := $.jsonMarshal|raw$($.inputType|private$) - if err != nil { - return nil, err - } - - name := $.inputType|private$.Name - if name == nil { - return nil, fmt.Errorf("$.inputType|private$.Name must be provided to Apply") - } - - result = &$.resultType|raw${} - err = c.client.Patch($.ApplyPatchType|raw$). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name(*name). - SubResource("status"). - VersionedParams(&patchOpts, $.schemeParameterCodec|raw$). - Body(data). - Do(ctx). - Into(result) - return -} -` - -var applySubresourceTemplate = ` -// Apply takes top resource name and the apply declarative configuration for $.subresourcePath$, -// applies it and returns the applied $.resultType|private$, and an error, if there is any. -func (c *$.type|privatePlural$) Apply(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error) { - if $.inputType|private$ == nil { - return nil, fmt.Errorf("$.inputType|private$ provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := $.jsonMarshal|raw$($.inputType|private$) - if err != nil { - return nil, err - } - - result = &$.resultType|raw${} - err = c.client.Patch($.ApplyPatchType|raw$). - $if .namespaced$Namespace(c.ns).$end$ - Resource("$.type|resource$"). - Name($.type|private$Name). - SubResource("$.subresourcePath$"). - VersionedParams(&patchOpts, $.schemeParameterCodec|raw$). - Body(data). - Do(ctx). - Into(result) - return -} -` diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go deleted file mode 100644 index a87d7571..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go +++ /dev/null @@ -1,187 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package scheme - -import ( - "fmt" - "io" - "os" - "path/filepath" - "strings" - - "k8s.io/code-generator/cmd/client-gen/path" - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// GenScheme produces a package for a clientset with the scheme, codecs and parameter codecs. -type GenScheme struct { - generator.DefaultGen - OutputPackage string - Groups []clientgentypes.GroupVersions - GroupGoNames map[clientgentypes.GroupVersion]string - InputPackages map[clientgentypes.GroupVersion]string - OutputPath string - ImportTracker namer.ImportTracker - PrivateScheme bool - CreateRegistry bool - schemeGenerated bool -} - -func (g *GenScheme) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.OutputPackage, g.ImportTracker), - } -} - -// We only want to call GenerateType() once. -func (g *GenScheme) Filter(c *generator.Context, t *types.Type) bool { - ret := !g.schemeGenerated - g.schemeGenerated = true - return ret -} - -func (g *GenScheme) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.ImportTracker.ImportLines()...) - for _, group := range g.Groups { - for _, version := range group.Versions { - packagePath := g.InputPackages[clientgentypes.GroupVersion{Group: group.Group, Version: version.Version}] - groupAlias := strings.ToLower(g.GroupGoNames[clientgentypes.GroupVersion{Group: group.Group, Version: version.Version}]) - if g.CreateRegistry { - // import the install package for internal clientsets instead of the type package with register.go - if version.Version != "" { - packagePath = filepath.Dir(packagePath) - } - packagePath = filepath.Join(packagePath, "install") - - imports = append(imports, fmt.Sprintf("%s \"%s\"", groupAlias, path.Vendorless(packagePath))) - break - } else { - imports = append(imports, fmt.Sprintf("%s%s \"%s\"", groupAlias, strings.ToLower(version.Version.NonEmpty()), path.Vendorless(packagePath))) - } - } - } - return -} - -func (g *GenScheme) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - allGroupVersions := clientgentypes.ToGroupVersionInfo(g.Groups, g.GroupGoNames) - allInstallGroups := clientgentypes.ToGroupInstallPackages(g.Groups, g.GroupGoNames) - - m := map[string]interface{}{ - "publicScheme": !g.PrivateScheme, - "allGroupVersions": allGroupVersions, - "allInstallGroups": allInstallGroups, - "customRegister": false, - "runtimeNewParameterCodec": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "NewParameterCodec"}), - "runtimeNewScheme": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "NewScheme"}), - "serializerNewCodecFactory": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/serializer", Name: "NewCodecFactory"}), - "runtimeScheme": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "Scheme"}), - "runtimeSchemeBuilder": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "SchemeBuilder"}), - "runtimeUtilMust": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/util/runtime", Name: "Must"}), - "schemaGroupVersion": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupVersion"}), - "metav1AddToGroupVersion": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "AddToGroupVersion"}), - } - globals := map[string]string{ - "Scheme": "Scheme", - "Codecs": "Codecs", - "ParameterCodec": "ParameterCodec", - "Registry": "Registry", - } - for k, v := range globals { - if g.PrivateScheme { - m[k] = strings.ToLower(v[0:1]) + v[1:] - } else { - m[k] = v - } - } - - sw.Do(globalsTemplate, m) - - if g.OutputPath != "" { - if _, err := os.Stat(filepath.Join(g.OutputPath, strings.ToLower("register_custom.go"))); err == nil { - m["customRegister"] = true - } - } - - if g.CreateRegistry { - sw.Do(registryRegistration, m) - } else { - sw.Do(simpleRegistration, m) - } - - return sw.Error() -} - -var globalsTemplate = ` -var $.Scheme$ = $.runtimeNewScheme|raw$() -var $.Codecs$ = $.serializerNewCodecFactory|raw$($.Scheme$) -$if .publicScheme$var $.ParameterCodec$ = $.runtimeNewParameterCodec|raw$($.Scheme$)$end -$` - -var registryRegistration = ` - -func init() { - $.metav1AddToGroupVersion|raw$($.Scheme$, $.schemaGroupVersion|raw${Version: "v1"}) - Install($.Scheme$) -} - -// Install registers the API group and adds types to a scheme -func Install(scheme *$.runtimeScheme|raw$) { - $- range .allInstallGroups$ - $.InstallPackageAlias$.Install(scheme) - $- end$ - $if .customRegister$ - ExtraInstall(scheme) - $end -$ -} -` - -var simpleRegistration = ` -var localSchemeBuilder = $.runtimeSchemeBuilder|raw${ - $- range .allGroupVersions$ - $.PackageAlias$.AddToScheme, - $- end$ - $if .customRegister$ - ExtraAddToScheme, - $end -$ -} - -// AddToScheme adds all types of this clientset into the given scheme. This allows composition -// of clientsets, like in: -// -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) -// -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) -// -// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types -// correctly. -var AddToScheme = localSchemeBuilder.AddToScheme - -func init() { - $.metav1AddToGroupVersion|raw$($.Scheme$, $.schemaGroupVersion|raw${Version: "v1"}) - $.runtimeUtilMust|raw$(AddToScheme($.Scheme$)) -} -` diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/util/tags.go b/vendor/k8s.io/code-generator/cmd/client-gen/generators/util/tags.go deleted file mode 100644 index e74de077..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/util/tags.go +++ /dev/null @@ -1,344 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package util - -import ( - "errors" - "fmt" - "strings" - - "k8s.io/gengo/types" -) - -var supportedTags = []string{ - "genclient", - "genclient:nonNamespaced", - "genclient:noVerbs", - "genclient:onlyVerbs", - "genclient:skipVerbs", - "genclient:noStatus", - "genclient:readonly", - "genclient:method", -} - -// SupportedVerbs is a list of supported verbs for +onlyVerbs and +skipVerbs. -var SupportedVerbs = []string{ - "create", - "update", - "updateStatus", - "delete", - "deleteCollection", - "get", - "list", - "watch", - "patch", - "apply", - "applyStatus", -} - -// ReadonlyVerbs represents a list of read-only verbs. -var ReadonlyVerbs = []string{ - "get", - "list", - "watch", -} - -// genClientPrefix is the default prefix for all genclient tags. -const genClientPrefix = "genclient:" - -// unsupportedExtensionVerbs is a list of verbs we don't support generating -// extension client functions for. -var unsupportedExtensionVerbs = []string{ - "updateStatus", - "deleteCollection", - "watch", - "delete", -} - -// inputTypeSupportedVerbs is a list of verb types that supports overriding the -// input argument type. -var inputTypeSupportedVerbs = []string{ - "create", - "update", - "apply", -} - -// resultTypeSupportedVerbs is a list of verb types that supports overriding the -// resulting type. -var resultTypeSupportedVerbs = []string{ - "create", - "update", - "get", - "list", - "patch", - "apply", -} - -// Extensions allows to extend the default set of client verbs -// (CRUD+watch+patch+list+deleteCollection) for a given type with custom defined -// verbs. Custom verbs can have custom input and result types and also allow to -// use a sub-resource in a request instead of top-level resource type. -// -// Example: -// -// +genclient:method=UpdateScale,verb=update,subresource=scale,input=Scale,result=Scale -// -// type ReplicaSet struct { ... } -// -// The 'method=UpdateScale' is the name of the client function. -// The 'verb=update' here means the client function will use 'PUT' action. -// The 'subresource=scale' means we will use SubResource template to generate this client function. -// The 'input' is the input type used for creation (function argument). -// The 'result' (not needed in this case) is the result type returned from the -// client function. -type extension struct { - // VerbName is the name of the custom verb (Scale, Instantiate, etc..) - VerbName string - // VerbType is the type of the verb (only verbs from SupportedVerbs are - // supported) - VerbType string - // SubResourcePath defines a path to a sub-resource to use in the request. - // (optional) - SubResourcePath string - // InputTypeOverride overrides the input parameter type for the verb. By - // default the original type is used. Overriding the input type only works for - // "create" and "update" verb types. The given type must exists in the same - // package as the original type. - // (optional) - InputTypeOverride string - // ResultTypeOverride overrides the resulting object type for the verb. By - // default the original type is used. Overriding the result type works. - // (optional) - ResultTypeOverride string -} - -// IsSubresource indicates if this extension should generate the sub-resource. -func (e *extension) IsSubresource() bool { - return len(e.SubResourcePath) > 0 -} - -// HasVerb checks if the extension matches the given verb. -func (e *extension) HasVerb(verb string) bool { - return e.VerbType == verb -} - -// Input returns the input override package path and the type. -func (e *extension) Input() (string, string) { - parts := strings.Split(e.InputTypeOverride, ".") - return parts[len(parts)-1], strings.Join(parts[0:len(parts)-1], ".") -} - -// Result returns the result override package path and the type. -func (e *extension) Result() (string, string) { - parts := strings.Split(e.ResultTypeOverride, ".") - return parts[len(parts)-1], strings.Join(parts[0:len(parts)-1], ".") -} - -// Tags represents a genclient configuration for a single type. -type Tags struct { - // +genclient - GenerateClient bool - // +genclient:nonNamespaced - NonNamespaced bool - // +genclient:noStatus - NoStatus bool - // +genclient:noVerbs - NoVerbs bool - // +genclient:skipVerbs=get,update - // +genclient:onlyVerbs=create,delete - SkipVerbs []string - // +genclient:method=UpdateScale,verb=update,subresource=scale,input=Scale,result=Scale - Extensions []extension -} - -// HasVerb returns true if we should include the given verb in final client interface and -// generate the function for it. -func (t Tags) HasVerb(verb string) bool { - if len(t.SkipVerbs) == 0 { - return true - } - for _, s := range t.SkipVerbs { - if verb == s { - return false - } - } - return true -} - -// MustParseClientGenTags calls ParseClientGenTags but instead of returning error it panics. -func MustParseClientGenTags(lines []string) Tags { - tags, err := ParseClientGenTags(lines) - if err != nil { - panic(err.Error()) - } - return tags -} - -// ParseClientGenTags parse the provided genclient tags and validates that no unknown -// tags are provided. -func ParseClientGenTags(lines []string) (Tags, error) { - ret := Tags{} - values := types.ExtractCommentTags("+", lines) - var value []string - value, ret.GenerateClient = values["genclient"] - // Check the old format and error when used to avoid generating client when //+genclient=false - if len(value) > 0 && len(value[0]) > 0 { - return ret, fmt.Errorf("+genclient=%s is invalid, use //+genclient if you want to generate client or omit it when you want to disable generation", value) - } - _, ret.NonNamespaced = values[genClientPrefix+"nonNamespaced"] - // Check the old format and error when used - if value := values["nonNamespaced"]; len(value) > 0 && len(value[0]) > 0 { - return ret, fmt.Errorf("+nonNamespaced=%s is invalid, use //+genclient:nonNamespaced instead", value[0]) - } - _, ret.NoVerbs = values[genClientPrefix+"noVerbs"] - _, ret.NoStatus = values[genClientPrefix+"noStatus"] - onlyVerbs := []string{} - if _, isReadonly := values[genClientPrefix+"readonly"]; isReadonly { - onlyVerbs = ReadonlyVerbs - } - // Check the old format and error when used - if value := values["readonly"]; len(value) > 0 && len(value[0]) > 0 { - return ret, fmt.Errorf("+readonly=%s is invalid, use //+genclient:readonly instead", value[0]) - } - if v, exists := values[genClientPrefix+"skipVerbs"]; exists { - ret.SkipVerbs = strings.Split(v[0], ",") - } - if v, exists := values[genClientPrefix+"onlyVerbs"]; exists || len(onlyVerbs) > 0 { - if len(v) > 0 { - onlyVerbs = append(onlyVerbs, strings.Split(v[0], ",")...) - } - skipVerbs := []string{} - for _, m := range SupportedVerbs { - skip := true - for _, o := range onlyVerbs { - if o == m { - skip = false - break - } - } - // Check for conflicts - for _, v := range skipVerbs { - if v == m { - return ret, fmt.Errorf("verb %q used both in genclient:skipVerbs and genclient:onlyVerbs", v) - } - } - if skip { - skipVerbs = append(skipVerbs, m) - } - } - ret.SkipVerbs = skipVerbs - } - var err error - if ret.Extensions, err = parseClientExtensions(values); err != nil { - return ret, err - } - return ret, validateClientGenTags(values) -} - -func parseClientExtensions(tags map[string][]string) ([]extension, error) { - var ret []extension - for name, values := range tags { - if !strings.HasPrefix(name, genClientPrefix+"method") { - continue - } - for _, value := range values { - // the value comes in this form: "Foo,verb=create" - ext := extension{} - parts := strings.Split(value, ",") - if len(parts) == 0 { - return nil, fmt.Errorf("invalid of empty extension verb name: %q", value) - } - // The first part represents the name of the extension - ext.VerbName = parts[0] - if len(ext.VerbName) == 0 { - return nil, fmt.Errorf("must specify a verb name (// +genclient:method=Foo,verb=create)") - } - // Parse rest of the arguments - params := parts[1:] - for _, p := range params { - parts := strings.Split(p, "=") - if len(parts) != 2 { - return nil, fmt.Errorf("invalid extension tag specification %q", p) - } - key, val := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]) - if len(val) == 0 { - return nil, fmt.Errorf("empty value of %q for %q extension", key, ext.VerbName) - } - switch key { - case "verb": - ext.VerbType = val - case "subresource": - ext.SubResourcePath = val - case "input": - ext.InputTypeOverride = val - case "result": - ext.ResultTypeOverride = val - default: - return nil, fmt.Errorf("unknown extension configuration key %q", key) - } - } - // Validate resulting extension configuration - if len(ext.VerbType) == 0 { - return nil, fmt.Errorf("verb type must be specified (use '// +genclient:method=%s,verb=create')", ext.VerbName) - } - if len(ext.ResultTypeOverride) > 0 { - supported := false - for _, v := range resultTypeSupportedVerbs { - if ext.VerbType == v { - supported = true - break - } - } - if !supported { - return nil, fmt.Errorf("%s: result type is not supported for %q verbs (supported verbs: %#v)", ext.VerbName, ext.VerbType, resultTypeSupportedVerbs) - } - } - if len(ext.InputTypeOverride) > 0 { - supported := false - for _, v := range inputTypeSupportedVerbs { - if ext.VerbType == v { - supported = true - break - } - } - if !supported { - return nil, fmt.Errorf("%s: input type is not supported for %q verbs (supported verbs: %#v)", ext.VerbName, ext.VerbType, inputTypeSupportedVerbs) - } - } - for _, t := range unsupportedExtensionVerbs { - if ext.VerbType == t { - return nil, fmt.Errorf("verb %q is not supported by extension generator", ext.VerbType) - } - } - ret = append(ret, ext) - } - } - return ret, nil -} - -// validateTags validates that only supported genclient tags were provided. -func validateClientGenTags(values map[string][]string) error { - for _, k := range supportedTags { - delete(values, k) - } - for key := range values { - if strings.HasPrefix(key, strings.TrimSuffix(genClientPrefix, ":")) { - return errors.New("unknown tag detected: " + key) - } - } - return nil -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/main.go b/vendor/k8s.io/code-generator/cmd/client-gen/main.go deleted file mode 100644 index 64a1274d..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/main.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// client-gen makes the individual typed clients using gengo. -package main - -import ( - "flag" - - "github.com/spf13/pflag" - "k8s.io/klog/v2" - - generatorargs "k8s.io/code-generator/cmd/client-gen/args" - "k8s.io/code-generator/cmd/client-gen/generators" - "k8s.io/code-generator/pkg/util" -) - -func main() { - klog.InitFlags(nil) - genericArgs, customArgs := generatorargs.NewDefaults() - - // Override defaults. - // TODO: move this out of client-gen - genericArgs.OutputPackagePath = "k8s.io/kubernetes/pkg/client/clientset_generated/" - - genericArgs.AddFlags(pflag.CommandLine) - customArgs.AddFlags(pflag.CommandLine, "k8s.io/kubernetes/pkg/apis") // TODO: move this input path out of client-gen - flag.Set("logtostderr", "true") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - // add group version package as input dirs for gengo - for _, pkg := range customArgs.Groups { - for _, v := range pkg.Versions { - genericArgs.InputDirs = append(genericArgs.InputDirs, v.Package) - } - } - - if err := generatorargs.Validate(genericArgs); err != nil { - klog.Fatalf("Error: %v", err) - } - - if err := genericArgs.Execute( - generators.NameSystems(util.PluralExceptionListToMapOrDie(customArgs.PluralExceptions)), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Fatalf("Error: %v", err) - } -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/path/path.go b/vendor/k8s.io/code-generator/cmd/client-gen/path/path.go deleted file mode 100644 index 19b269bd..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/path/path.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package path - -import "strings" - -// Vendorless removes the longest match of "*/vendor/" from the front of p. -// It is useful if a package locates in vendor/, e.g., -// k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1, because gengo -// indexes the package with its import path, e.g., -// k8s.io/apimachinery/pkg/apis/meta/v1, -func Vendorless(p string) string { - if pos := strings.LastIndex(p, "/vendor/"); pos != -1 { - return p[pos+len("/vendor/"):] - } - return p -} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/types/helpers.go b/vendor/k8s.io/code-generator/cmd/client-gen/types/helpers.go deleted file mode 100644 index 59f2fd44..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/types/helpers.go +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package types - -import ( - "fmt" - "regexp" - "sort" - "strings" - - "k8s.io/gengo/namer" -) - -// ToGroupVersion turns "group/version" string into a GroupVersion struct. It reports error -// if it cannot parse the string. -func ToGroupVersion(gv string) (GroupVersion, error) { - // this can be the internal version for the legacy kube types - // TODO once we've cleared the last uses as strings, this special case should be removed. - if (len(gv) == 0) || (gv == "/") { - return GroupVersion{}, nil - } - - switch strings.Count(gv, "/") { - case 0: - return GroupVersion{Group(gv), ""}, nil - case 1: - i := strings.Index(gv, "/") - return GroupVersion{Group(gv[:i]), Version(gv[i+1:])}, nil - default: - return GroupVersion{}, fmt.Errorf("unexpected GroupVersion string: %v", gv) - } -} - -type sortableSliceOfVersions []string - -func (a sortableSliceOfVersions) Len() int { return len(a) } -func (a sortableSliceOfVersions) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a sortableSliceOfVersions) Less(i, j int) bool { - vi, vj := strings.TrimLeft(a[i], "v"), strings.TrimLeft(a[j], "v") - major := regexp.MustCompile("^[0-9]+") - viMajor, vjMajor := major.FindString(vi), major.FindString(vj) - viRemaining, vjRemaining := strings.TrimLeft(vi, viMajor), strings.TrimLeft(vj, vjMajor) - switch { - case len(viRemaining) == 0 && len(vjRemaining) == 0: - return viMajor < vjMajor - case len(viRemaining) == 0 && len(vjRemaining) != 0: - // stable version is greater than unstable version - return false - case len(viRemaining) != 0 && len(vjRemaining) == 0: - // stable version is greater than unstable version - return true - } - // neither are stable versions - if viMajor != vjMajor { - return viMajor < vjMajor - } - // assuming at most we have one alpha or one beta version, so if vi contains "alpha", it's the lesser one. - return strings.Contains(viRemaining, "alpha") -} - -// Determine the default version among versions. If a user calls a group client -// without specifying the version (e.g., c.CoreV1(), instead of c.CoreV1()), the -// default version will be returned. -func defaultVersion(versions []PackageVersion) Version { - var versionStrings []string - for _, version := range versions { - versionStrings = append(versionStrings, version.Version.String()) - } - sort.Sort(sortableSliceOfVersions(versionStrings)) - return Version(versionStrings[len(versionStrings)-1]) -} - -// ToGroupVersionInfo is a helper function used by generators for groups. -func ToGroupVersionInfo(groups []GroupVersions, groupGoNames map[GroupVersion]string) []GroupVersionInfo { - var groupVersionPackages []GroupVersionInfo - for _, group := range groups { - for _, version := range group.Versions { - groupGoName := groupGoNames[GroupVersion{Group: group.Group, Version: version.Version}] - groupVersionPackages = append(groupVersionPackages, GroupVersionInfo{ - Group: Group(namer.IC(group.Group.NonEmpty())), - Version: Version(namer.IC(version.Version.String())), - PackageAlias: strings.ToLower(groupGoName + version.Version.NonEmpty()), - GroupGoName: groupGoName, - LowerCaseGroupGoName: namer.IL(groupGoName), - }) - } - } - return groupVersionPackages -} - -func ToGroupInstallPackages(groups []GroupVersions, groupGoNames map[GroupVersion]string) []GroupInstallPackage { - var groupInstallPackages []GroupInstallPackage - for _, group := range groups { - defaultVersion := defaultVersion(group.Versions) - groupGoName := groupGoNames[GroupVersion{Group: group.Group, Version: defaultVersion}] - groupInstallPackages = append(groupInstallPackages, GroupInstallPackage{ - Group: Group(namer.IC(group.Group.NonEmpty())), - InstallPackageAlias: strings.ToLower(groupGoName), - }) - } - return groupInstallPackages -} - -// NormalizeGroupVersion calls normalizes the GroupVersion. -//func NormalizeGroupVersion(gv GroupVersion) GroupVersion { -// return GroupVersion{Group: gv.Group.NonEmpty(), Version: gv.Version, NonEmptyVersion: normalization.Version(gv.Version)} -//} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/types/types.go b/vendor/k8s.io/code-generator/cmd/client-gen/types/types.go deleted file mode 100644 index a5cc37cf..00000000 --- a/vendor/k8s.io/code-generator/cmd/client-gen/types/types.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package types - -import "strings" - -type Version string - -func (v Version) String() string { - return string(v) -} - -func (v Version) NonEmpty() string { - if v == "" { - return "internalVersion" - } - return v.String() -} - -func (v Version) PackageName() string { - return strings.ToLower(v.NonEmpty()) -} - -type Group string - -func (g Group) String() string { - return string(g) -} - -func (g Group) NonEmpty() string { - if g == "api" { - return "core" - } - return string(g) -} - -func (g Group) PackageName() string { - parts := strings.Split(g.NonEmpty(), ".") - if parts[0] == "internal" && len(parts) > 1 { - return strings.ToLower(parts[1] + parts[0]) - } - return strings.ToLower(parts[0]) -} - -type PackageVersion struct { - Version - // The fully qualified package, e.g. k8s.io/kubernetes/pkg/apis/apps, where the types.go is found. - Package string -} - -type GroupVersion struct { - Group Group - Version Version -} - -func (gv GroupVersion) ToAPIVersion() string { - if len(gv.Group) > 0 && gv.Group.NonEmpty() != "core" { - return gv.Group.String() + "/" + gv.Version.String() - } else { - return gv.Version.String() - } -} - -type GroupVersions struct { - // The name of the package for this group, e.g. apps. - PackageName string - Group Group - Versions []PackageVersion -} - -// GroupVersionInfo contains all the info around a group version. -type GroupVersionInfo struct { - Group Group - Version Version - PackageAlias string - GroupGoName string - LowerCaseGroupGoName string -} - -type GroupInstallPackage struct { - Group Group - InstallPackageAlias string -} diff --git a/vendor/k8s.io/code-generator/cmd/conversion-gen/args/args.go b/vendor/k8s.io/code-generator/cmd/conversion-gen/args/args.go deleted file mode 100644 index c69280b1..00000000 --- a/vendor/k8s.io/code-generator/cmd/conversion-gen/args/args.go +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "fmt" - - "github.com/spf13/pflag" - "k8s.io/gengo/args" -) - -// DefaultBasePeerDirs are the peer-dirs nearly everybody will use, i.e. those coming from -// apimachinery. -var DefaultBasePeerDirs = []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1", - "k8s.io/apimachinery/pkg/conversion", - "k8s.io/apimachinery/pkg/runtime", -} - -// CustomArgs is used by the gengo framework to pass args specific to this generator. -type CustomArgs struct { - // Base peer dirs which nearly everybody will use, i.e. outside of Kubernetes core. Peer dirs - // are declared to make the generator pick up manually written conversion funcs from external - // packages. - BasePeerDirs []string - - // Custom peer dirs which are application specific. Peer dirs are declared to make the - // generator pick up manually written conversion funcs from external packages. - ExtraPeerDirs []string - - // Additional dirs to parse and load, but not consider for peers. This is - // useful when packages depend on other packages and want to call - // conversions across them. - ExtraDirs []string - - // SkipUnsafe indicates whether to generate unsafe conversions to improve the efficiency - // of these operations. The unsafe operation is a direct pointer assignment via unsafe - // (within the allowed uses of unsafe) and is equivalent to a proposed Golang change to - // allow structs that are identical to be assigned to each other. - SkipUnsafe bool -} - -// NewDefaults returns default arguments for the generator. -func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { - genericArgs := args.Default().WithoutDefaultFlagParsing() - customArgs := &CustomArgs{ - BasePeerDirs: DefaultBasePeerDirs, - SkipUnsafe: false, - } - genericArgs.CustomArgs = customArgs - genericArgs.OutputFileBaseName = "conversion_generated" - return genericArgs, customArgs -} - -// AddFlags add the generator flags to the flag set. -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { - pflag.CommandLine.StringSliceVar(&ca.BasePeerDirs, "base-peer-dirs", ca.BasePeerDirs, - "Comma-separated list of apimachinery import paths which are considered, after tag-specified peers, for conversions. Only change these if you have very good reasons.") - pflag.CommandLine.StringSliceVar(&ca.ExtraPeerDirs, "extra-peer-dirs", ca.ExtraPeerDirs, - "Application specific comma-separated list of import paths which are considered, after tag-specified peers and base-peer-dirs, for conversions.") - pflag.CommandLine.StringSliceVar(&ca.ExtraDirs, "extra-dirs", ca.ExtraDirs, - "Application specific comma-separated list of import paths which are loaded and considered for callable conversions, but are not considered peers for conversion.") - pflag.CommandLine.BoolVar(&ca.SkipUnsafe, "skip-unsafe", ca.SkipUnsafe, - "If true, will not generate code using unsafe pointer conversions; resulting code may be slower.") -} - -// Validate checks the given arguments. -func Validate(genericArgs *args.GeneratorArgs) error { - _ = genericArgs.CustomArgs.(*CustomArgs) - - if len(genericArgs.OutputFileBaseName) == 0 { - return fmt.Errorf("output file base name cannot be empty") - } - - return nil -} diff --git a/vendor/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go b/vendor/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go deleted file mode 100644 index 5b734797..00000000 --- a/vendor/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go +++ /dev/null @@ -1,1222 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "bytes" - "fmt" - "io" - "path/filepath" - "reflect" - "sort" - "strings" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/klog/v2" - - conversionargs "k8s.io/code-generator/cmd/conversion-gen/args" - genutil "k8s.io/code-generator/pkg/util" -) - -// These are the comment tags that carry parameters for conversion generation. -const ( - // e.g., "+k8s:conversion-gen=" in doc.go, where is the - // import path of the package the peer types are defined in. - // e.g., "+k8s:conversion-gen=false" in a type's comment will let - // conversion-gen skip that type. - tagName = "k8s:conversion-gen" - // e.g. "+k8s:conversion-gen:explicit-from=net/url.Values" in the type comment - // will result in generating conversion from net/url.Values. - explicitFromTagName = "k8s:conversion-gen:explicit-from" - // e.g., "+k8s:conversion-gen-external-types=" in doc.go, where - // is the relative path to the package the types are defined in. - externalTypesTagName = "k8s:conversion-gen-external-types" -) - -func extractTag(comments []string) []string { - return types.ExtractCommentTags("+", comments)[tagName] -} - -func extractExplicitFromTag(comments []string) []string { - return types.ExtractCommentTags("+", comments)[explicitFromTagName] -} - -func extractExternalTypesTag(comments []string) []string { - return types.ExtractCommentTags("+", comments)[externalTypesTagName] -} - -func isCopyOnly(comments []string) bool { - values := types.ExtractCommentTags("+", comments)["k8s:conversion-fn"] - return len(values) == 1 && values[0] == "copy-only" -} - -func isDrop(comments []string) bool { - values := types.ExtractCommentTags("+", comments)["k8s:conversion-fn"] - return len(values) == 1 && values[0] == "drop" -} - -// TODO: This is created only to reduce number of changes in a single PR. -// Remove it and use PublicNamer instead. -func conversionNamer() *namer.NameStrategy { - return &namer.NameStrategy{ - Join: func(pre string, in []string, post string) string { - return strings.Join(in, "_") - }, - PrependPackageNames: 1, - } -} - -func defaultFnNamer() *namer.NameStrategy { - return &namer.NameStrategy{ - Prefix: "SetDefaults_", - Join: func(pre string, in []string, post string) string { - return pre + strings.Join(in, "_") + post - }, - } -} - -// NameSystems returns the name system used by the generators in this package. -func NameSystems() namer.NameSystems { - return namer.NameSystems{ - "public": conversionNamer(), - "raw": namer.NewRawNamer("", nil), - "defaultfn": defaultFnNamer(), - } -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -func getPeerTypeFor(context *generator.Context, t *types.Type, potenialPeerPkgs []string) *types.Type { - for _, ppp := range potenialPeerPkgs { - p := context.Universe.Package(ppp) - if p == nil { - continue - } - if p.Has(t.Name.Name) { - return p.Type(t.Name.Name) - } - } - return nil -} - -type conversionPair struct { - inType *types.Type - outType *types.Type -} - -// All of the types in conversions map are of type "DeclarationOf" with -// the underlying type being "Func". -type conversionFuncMap map[conversionPair]*types.Type - -// Returns all manually-defined conversion functions in the package. -func getManualConversionFunctions(context *generator.Context, pkg *types.Package, manualMap conversionFuncMap) { - if pkg == nil { - klog.Warning("Skipping nil package passed to getManualConversionFunctions") - return - } - klog.V(5).Infof("Scanning for conversion functions in %v", pkg.Name) - - scopeName := types.Ref(conversionPackagePath, "Scope").Name - errorName := types.Ref("", "error").Name - buffer := &bytes.Buffer{} - sw := generator.NewSnippetWriter(buffer, context, "$", "$") - - for _, f := range pkg.Functions { - if f.Underlying == nil || f.Underlying.Kind != types.Func { - klog.Errorf("Malformed function: %#v", f) - continue - } - if f.Underlying.Signature == nil { - klog.Errorf("Function without signature: %#v", f) - continue - } - klog.V(8).Infof("Considering function %s", f.Name) - signature := f.Underlying.Signature - // Check whether the function is conversion function. - // Note that all of them have signature: - // func Convert_inType_To_outType(inType, outType, conversion.Scope) error - if signature.Receiver != nil { - klog.V(8).Infof("%s has a receiver", f.Name) - continue - } - if len(signature.Parameters) != 3 || signature.Parameters[2].Name != scopeName { - klog.V(8).Infof("%s has wrong parameters", f.Name) - continue - } - if len(signature.Results) != 1 || signature.Results[0].Name != errorName { - klog.V(8).Infof("%s has wrong results", f.Name) - continue - } - inType := signature.Parameters[0] - outType := signature.Parameters[1] - if inType.Kind != types.Pointer || outType.Kind != types.Pointer { - klog.V(8).Infof("%s has wrong parameter types", f.Name) - continue - } - // Now check if the name satisfies the convention. - // TODO: This should call the Namer directly. - args := argsFromType(inType.Elem, outType.Elem) - sw.Do("Convert_$.inType|public$_To_$.outType|public$", args) - if f.Name.Name == buffer.String() { - klog.V(4).Infof("Found conversion function %s", f.Name) - key := conversionPair{inType.Elem, outType.Elem} - // We might scan the same package twice, and that's OK. - if v, ok := manualMap[key]; ok && v != nil && v.Name.Package != pkg.Path { - panic(fmt.Sprintf("duplicate static conversion defined: %s -> %s from:\n%s.%s\n%s.%s", key.inType, key.outType, v.Name.Package, v.Name.Name, f.Name.Package, f.Name.Name)) - } - manualMap[key] = f - } else { - // prevent user error when they don't get the correct conversion signature - if strings.HasPrefix(f.Name.Name, "Convert_") { - klog.Errorf("Rename function %s %s -> %s to match expected conversion signature", f.Name.Package, f.Name.Name, buffer.String()) - } - klog.V(8).Infof("%s has wrong name", f.Name) - } - buffer.Reset() - } -} - -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - packages := generator.Packages{} - header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...) - - // Accumulate pre-existing conversion functions. - // TODO: This is too ad-hoc. We need a better way. - manualConversions := conversionFuncMap{} - - // Record types that are memory equivalent. A type is memory equivalent - // if it has the same memory layout and no nested manual conversion is - // defined. - // TODO: in the future, relax the nested manual conversion requirement - // if we can show that a large enough types are memory identical but - // have non-trivial conversion - memoryEquivalentTypes := equalMemoryTypes{} - - // We are generating conversions only for packages that are explicitly - // passed as InputDir. - processed := map[string]bool{} - for _, i := range context.Inputs { - // skip duplicates - if processed[i] { - continue - } - processed[i] = true - - klog.V(5).Infof("considering pkg %q", i) - pkg := context.Universe[i] - // typesPkg is where the versioned types are defined. Sometimes it is - // different from pkg. For example, kubernetes core/v1 types are defined - // in vendor/k8s.io/api/core/v1, while pkg is at pkg/api/v1. - typesPkg := pkg - if pkg == nil { - // If the input had no Go files, for example. - continue - } - - // Add conversion and defaulting functions. - getManualConversionFunctions(context, pkg, manualConversions) - - // Only generate conversions for packages which explicitly request it - // by specifying one or more "+k8s:conversion-gen=" - // in their doc.go file. - peerPkgs := extractTag(pkg.Comments) - if peerPkgs != nil { - klog.V(5).Infof(" tags: %q", peerPkgs) - if len(peerPkgs) == 1 && peerPkgs[0] == "false" { - // If a single +k8s:conversion-gen=false tag is defined, we still want - // the generator to fire for this package for explicit conversions, but - // we are clearing the peerPkgs to not generate any standard conversions. - peerPkgs = nil - } - } else { - klog.V(5).Infof(" no tag") - continue - } - skipUnsafe := false - extraDirs := []string{} - if customArgs, ok := arguments.CustomArgs.(*conversionargs.CustomArgs); ok { - if len(peerPkgs) > 0 { - peerPkgs = append(peerPkgs, customArgs.BasePeerDirs...) - peerPkgs = append(peerPkgs, customArgs.ExtraPeerDirs...) - } - extraDirs = customArgs.ExtraDirs - skipUnsafe = customArgs.SkipUnsafe - } - - // if the external types are not in the same package where the conversion functions to be generated - externalTypesValues := extractExternalTypesTag(pkg.Comments) - if externalTypesValues != nil { - if len(externalTypesValues) != 1 { - klog.Fatalf(" expect only one value for %q tag, got: %q", externalTypesTagName, externalTypesValues) - } - externalTypes := externalTypesValues[0] - klog.V(5).Infof(" external types tags: %q", externalTypes) - var err error - typesPkg, err = context.AddDirectory(externalTypes) - if err != nil { - klog.Fatalf("cannot import package %s", externalTypes) - } - // update context.Order to the latest context.Universe - orderer := namer.Orderer{Namer: namer.NewPublicNamer(1)} - context.Order = orderer.OrderUniverse(context.Universe) - } - - // if the source path is within a /vendor/ directory (for example, - // k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1), allow - // generation to output to the proper relative path (under vendor). - // Otherwise, the generator will create the file in the wrong location - // in the output directory. - // TODO: build a more fundamental concept in gengo for dealing with modifications - // to vendored packages. - for i := range peerPkgs { - peerPkgs[i] = genutil.Vendorless(peerPkgs[i]) - } - for i := range extraDirs { - extraDirs[i] = genutil.Vendorless(extraDirs[i]) - } - - // Make sure our peer-packages are added and fully parsed. - for _, pp := range append(peerPkgs, extraDirs...) { - context.AddDir(pp) - p := context.Universe[pp] - if nil == p { - klog.Fatalf("failed to find pkg: %s", pp) - } - getManualConversionFunctions(context, p, manualConversions) - } - - unsafeEquality := TypesEqual(memoryEquivalentTypes) - if skipUnsafe { - unsafeEquality = noEquality{} - } - - path := pkg.Path - // if the source path is within a /vendor/ directory (for example, - // k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1), allow - // generation to output to the proper relative path (under vendor). - // Otherwise, the generator will create the file in the wrong location - // in the output directory. - // TODO: build a more fundamental concept in gengo for dealing with modifications - // to vendored packages. - if strings.HasPrefix(pkg.SourcePath, arguments.OutputBase) { - expandedPath := strings.TrimPrefix(pkg.SourcePath, arguments.OutputBase) - if strings.Contains(expandedPath, "/vendor/") { - path = expandedPath - } - } - packages = append(packages, - &generator.DefaultPackage{ - PackageName: filepath.Base(pkg.Path), - PackagePath: path, - HeaderText: header, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - return []generator.Generator{ - NewGenConversion(arguments.OutputFileBaseName, typesPkg.Path, pkg.Path, manualConversions, peerPkgs, unsafeEquality), - } - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - return t.Name.Package == typesPkg.Path - }, - }) - } - - // If there is a manual conversion defined between two types, exclude it - // from being a candidate for unsafe conversion - for k, v := range manualConversions { - if isCopyOnly(v.CommentLines) { - klog.V(5).Infof("Conversion function %s will not block memory copy because it is copy-only", v.Name) - continue - } - // this type should be excluded from all equivalence, because the converter must be called. - memoryEquivalentTypes.Skip(k.inType, k.outType) - } - - return packages -} - -type equalMemoryTypes map[conversionPair]bool - -func (e equalMemoryTypes) Skip(a, b *types.Type) { - e[conversionPair{a, b}] = false - e[conversionPair{b, a}] = false -} - -func (e equalMemoryTypes) Equal(a, b *types.Type) bool { - // alreadyVisitedTypes holds all the types that have already been checked in the structural type recursion. - alreadyVisitedTypes := make(map[*types.Type]bool) - return e.cachingEqual(a, b, alreadyVisitedTypes) -} - -func (e equalMemoryTypes) cachingEqual(a, b *types.Type, alreadyVisitedTypes map[*types.Type]bool) bool { - if a == b { - return true - } - if equal, ok := e[conversionPair{a, b}]; ok { - return equal - } - if equal, ok := e[conversionPair{b, a}]; ok { - return equal - } - result := e.equal(a, b, alreadyVisitedTypes) - e[conversionPair{a, b}] = result - e[conversionPair{b, a}] = result - return result -} - -func (e equalMemoryTypes) equal(a, b *types.Type, alreadyVisitedTypes map[*types.Type]bool) bool { - in, out := unwrapAlias(a), unwrapAlias(b) - switch { - case in == out: - return true - case in.Kind == out.Kind: - // if the type exists already, return early to avoid recursion - if alreadyVisitedTypes[in] { - return true - } - alreadyVisitedTypes[in] = true - - switch in.Kind { - case types.Struct: - if len(in.Members) != len(out.Members) { - return false - } - for i, inMember := range in.Members { - outMember := out.Members[i] - if !e.cachingEqual(inMember.Type, outMember.Type, alreadyVisitedTypes) { - return false - } - } - return true - case types.Pointer: - return e.cachingEqual(in.Elem, out.Elem, alreadyVisitedTypes) - case types.Map: - return e.cachingEqual(in.Key, out.Key, alreadyVisitedTypes) && e.cachingEqual(in.Elem, out.Elem, alreadyVisitedTypes) - case types.Slice: - return e.cachingEqual(in.Elem, out.Elem, alreadyVisitedTypes) - case types.Interface: - // TODO: determine whether the interfaces are actually equivalent - for now, they must have the - // same type. - return false - case types.Builtin: - return in.Name.Name == out.Name.Name - } - } - return false -} - -func findMember(t *types.Type, name string) (types.Member, bool) { - if t.Kind != types.Struct { - return types.Member{}, false - } - for _, member := range t.Members { - if member.Name == name { - return member, true - } - } - return types.Member{}, false -} - -// unwrapAlias recurses down aliased types to find the bedrock type. -func unwrapAlias(in *types.Type) *types.Type { - for in.Kind == types.Alias { - in = in.Underlying - } - return in -} - -const ( - runtimePackagePath = "k8s.io/apimachinery/pkg/runtime" - conversionPackagePath = "k8s.io/apimachinery/pkg/conversion" -) - -type noEquality struct{} - -func (noEquality) Equal(_, _ *types.Type) bool { return false } - -type TypesEqual interface { - Equal(a, b *types.Type) bool -} - -// genConversion produces a file with a autogenerated conversions. -type genConversion struct { - generator.DefaultGen - // the package that contains the types that conversion func are going to be - // generated for - typesPackage string - // the package that the conversion funcs are going to be output to - outputPackage string - // packages that contain the peer of types in typesPacakge - peerPackages []string - manualConversions conversionFuncMap - imports namer.ImportTracker - types []*types.Type - explicitConversions []conversionPair - skippedFields map[*types.Type][]string - useUnsafe TypesEqual -} - -func NewGenConversion(sanitizedName, typesPackage, outputPackage string, manualConversions conversionFuncMap, peerPkgs []string, useUnsafe TypesEqual) generator.Generator { - return &genConversion{ - DefaultGen: generator.DefaultGen{ - OptionalName: sanitizedName, - }, - typesPackage: typesPackage, - outputPackage: outputPackage, - peerPackages: peerPkgs, - manualConversions: manualConversions, - imports: generator.NewImportTracker(), - types: []*types.Type{}, - explicitConversions: []conversionPair{}, - skippedFields: map[*types.Type][]string{}, - useUnsafe: useUnsafe, - } -} - -func (g *genConversion) Namers(c *generator.Context) namer.NameSystems { - // Have the raw namer for this file track what it imports. - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - "publicIT": &namerPlusImportTracking{ - delegate: conversionNamer(), - tracker: g.imports, - }, - } -} - -type namerPlusImportTracking struct { - delegate namer.Namer - tracker namer.ImportTracker -} - -func (n *namerPlusImportTracking) Name(t *types.Type) string { - n.tracker.AddType(t) - return n.delegate.Name(t) -} - -func (g *genConversion) convertibleOnlyWithinPackage(inType, outType *types.Type) bool { - var t *types.Type - var other *types.Type - if inType.Name.Package == g.typesPackage { - t, other = inType, outType - } else { - t, other = outType, inType - } - - if t.Name.Package != g.typesPackage { - return false - } - // If the type has opted out, skip it. - tagvals := extractTag(t.CommentLines) - if tagvals != nil { - if tagvals[0] != "false" { - klog.Fatalf("Type %v: unsupported %s value: %q", t, tagName, tagvals[0]) - } - klog.V(5).Infof("type %v requests no conversion generation, skipping", t) - return false - } - // TODO: Consider generating functions for other kinds too. - if t.Kind != types.Struct { - return false - } - // Also, filter out private types. - if namer.IsPrivateGoName(other.Name.Name) { - return false - } - return true -} - -func getExplicitFromTypes(t *types.Type) []types.Name { - comments := append(t.SecondClosestCommentLines, t.CommentLines...) - paths := extractExplicitFromTag(comments) - result := []types.Name{} - for _, path := range paths { - items := strings.Split(path, ".") - if len(items) != 2 { - klog.Errorf("Unexpected k8s:conversion-gen:explicit-from tag: %s", path) - continue - } - switch { - case items[0] == "net/url" && items[1] == "Values": - default: - klog.Fatalf("Not supported k8s:conversion-gen:explicit-from tag: %s", path) - } - result = append(result, types.Name{Package: items[0], Name: items[1]}) - } - return result -} - -func (g *genConversion) Filter(c *generator.Context, t *types.Type) bool { - convertibleWithPeer := func() bool { - peerType := getPeerTypeFor(c, t, g.peerPackages) - if peerType == nil { - return false - } - if !g.convertibleOnlyWithinPackage(t, peerType) { - return false - } - g.types = append(g.types, t) - return true - }() - - explicitlyConvertible := func() bool { - inTypes := getExplicitFromTypes(t) - if len(inTypes) == 0 { - return false - } - for i := range inTypes { - pair := conversionPair{ - inType: &types.Type{Name: inTypes[i]}, - outType: t, - } - g.explicitConversions = append(g.explicitConversions, pair) - } - return true - }() - - return convertibleWithPeer || explicitlyConvertible -} - -func (g *genConversion) isOtherPackage(pkg string) bool { - if pkg == g.outputPackage { - return false - } - if strings.HasSuffix(pkg, `"`+g.outputPackage+`"`) { - return false - } - return true -} - -func (g *genConversion) Imports(c *generator.Context) (imports []string) { - var importLines []string - for _, singleImport := range g.imports.ImportLines() { - if g.isOtherPackage(singleImport) { - importLines = append(importLines, singleImport) - } - } - return importLines -} - -func argsFromType(inType, outType *types.Type) generator.Args { - return generator.Args{ - "inType": inType, - "outType": outType, - } -} - -const nameTmpl = "Convert_$.inType|publicIT$_To_$.outType|publicIT$" - -func (g *genConversion) preexists(inType, outType *types.Type) (*types.Type, bool) { - function, ok := g.manualConversions[conversionPair{inType, outType}] - return function, ok -} - -func (g *genConversion) Init(c *generator.Context, w io.Writer) error { - klogV := klog.V(5) - if klogV.Enabled() { - if m, ok := g.useUnsafe.(equalMemoryTypes); ok { - var result []string - klogV.Info("All objects without identical memory layout:") - for k, v := range m { - if v { - continue - } - result = append(result, fmt.Sprintf(" %s -> %s = %t", k.inType, k.outType, v)) - } - sort.Strings(result) - for _, s := range result { - klogV.Info(s) - } - } - } - sw := generator.NewSnippetWriter(w, c, "$", "$") - sw.Do("func init() {\n", nil) - sw.Do("localSchemeBuilder.Register(RegisterConversions)\n", nil) - sw.Do("}\n", nil) - - scheme := c.Universe.Type(types.Name{Package: runtimePackagePath, Name: "Scheme"}) - schemePtr := &types.Type{ - Kind: types.Pointer, - Elem: scheme, - } - sw.Do("// RegisterConversions adds conversion functions to the given scheme.\n", nil) - sw.Do("// Public to allow building arbitrary schemes.\n", nil) - sw.Do("func RegisterConversions(s $.|raw$) error {\n", schemePtr) - for _, t := range g.types { - peerType := getPeerTypeFor(c, t, g.peerPackages) - if _, found := g.preexists(t, peerType); !found { - args := argsFromType(t, peerType).With("Scope", types.Ref(conversionPackagePath, "Scope")) - sw.Do("if err := s.AddGeneratedConversionFunc((*$.inType|raw$)(nil), (*$.outType|raw$)(nil), func(a, b interface{}, scope $.Scope|raw$) error { return "+nameTmpl+"(a.(*$.inType|raw$), b.(*$.outType|raw$), scope) }); err != nil { return err }\n", args) - } - if _, found := g.preexists(peerType, t); !found { - args := argsFromType(peerType, t).With("Scope", types.Ref(conversionPackagePath, "Scope")) - sw.Do("if err := s.AddGeneratedConversionFunc((*$.inType|raw$)(nil), (*$.outType|raw$)(nil), func(a, b interface{}, scope $.Scope|raw$) error { return "+nameTmpl+"(a.(*$.inType|raw$), b.(*$.outType|raw$), scope) }); err != nil { return err }\n", args) - } - } - - for i := range g.explicitConversions { - args := argsFromType(g.explicitConversions[i].inType, g.explicitConversions[i].outType).With("Scope", types.Ref(conversionPackagePath, "Scope")) - sw.Do("if err := s.AddGeneratedConversionFunc((*$.inType|raw$)(nil), (*$.outType|raw$)(nil), func(a, b interface{}, scope $.Scope|raw$) error { return "+nameTmpl+"(a.(*$.inType|raw$), b.(*$.outType|raw$), scope) }); err != nil { return err }\n", args) - } - - var pairs []conversionPair - for pair, t := range g.manualConversions { - if t.Name.Package != g.outputPackage { - continue - } - pairs = append(pairs, pair) - } - // sort by name of the conversion function - sort.Slice(pairs, func(i, j int) bool { - if g.manualConversions[pairs[i]].Name.Name < g.manualConversions[pairs[j]].Name.Name { - return true - } - return false - }) - for _, pair := range pairs { - args := argsFromType(pair.inType, pair.outType).With("Scope", types.Ref(conversionPackagePath, "Scope")).With("fn", g.manualConversions[pair]) - sw.Do("if err := s.AddConversionFunc((*$.inType|raw$)(nil), (*$.outType|raw$)(nil), func(a, b interface{}, scope $.Scope|raw$) error { return $.fn|raw$(a.(*$.inType|raw$), b.(*$.outType|raw$), scope) }); err != nil { return err }\n", args) - } - - sw.Do("return nil\n", nil) - sw.Do("}\n\n", nil) - return sw.Error() -} - -func (g *genConversion) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - klog.V(5).Infof("generating for type %v", t) - sw := generator.NewSnippetWriter(w, c, "$", "$") - - if peerType := getPeerTypeFor(c, t, g.peerPackages); peerType != nil { - g.generateConversion(t, peerType, sw) - g.generateConversion(peerType, t, sw) - } - - for _, inTypeName := range getExplicitFromTypes(t) { - inPkg, ok := c.Universe[inTypeName.Package] - if !ok { - klog.Errorf("Unrecognized package: %s", inTypeName.Package) - continue - } - inType, ok := inPkg.Types[inTypeName.Name] - if !ok { - klog.Errorf("Unrecognized type in package %s: %s", inTypeName.Package, inTypeName.Name) - continue - } - switch { - case inType.Name.Package == "net/url" && inType.Name.Name == "Values": - g.generateFromUrlValues(inType, t, sw) - default: - klog.Errorf("Not supported input type: %#v", inType.Name) - } - } - - return sw.Error() -} - -func (g *genConversion) generateConversion(inType, outType *types.Type, sw *generator.SnippetWriter) { - args := argsFromType(inType, outType). - With("Scope", types.Ref(conversionPackagePath, "Scope")) - - sw.Do("func auto"+nameTmpl+"(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n", args) - g.generateFor(inType, outType, sw) - sw.Do("return nil\n", nil) - sw.Do("}\n\n", nil) - - if _, found := g.preexists(inType, outType); found { - // There is a public manual Conversion method: use it. - } else if skipped := g.skippedFields[inType]; len(skipped) != 0 { - // The inType had some fields we could not generate. - klog.Errorf("Warning: could not find nor generate a final Conversion function for %v -> %v", inType, outType) - klog.Errorf(" the following fields need manual conversion:") - for _, f := range skipped { - klog.Errorf(" - %v", f) - } - } else { - // Emit a public conversion function. - sw.Do("// "+nameTmpl+" is an autogenerated conversion function.\n", args) - sw.Do("func "+nameTmpl+"(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n", args) - sw.Do("return auto"+nameTmpl+"(in, out, s)\n", args) - sw.Do("}\n\n", nil) - } -} - -// we use the system of shadowing 'in' and 'out' so that the same code is valid -// at any nesting level. This makes the autogenerator easy to understand, and -// the compiler shouldn't care. -func (g *genConversion) generateFor(inType, outType *types.Type, sw *generator.SnippetWriter) { - klog.V(5).Infof("generating %v -> %v", inType, outType) - var f func(*types.Type, *types.Type, *generator.SnippetWriter) - - switch inType.Kind { - case types.Builtin: - f = g.doBuiltin - case types.Map: - f = g.doMap - case types.Slice: - f = g.doSlice - case types.Struct: - f = g.doStruct - case types.Pointer: - f = g.doPointer - case types.Alias: - f = g.doAlias - default: - f = g.doUnknown - } - - f(inType, outType, sw) -} - -func (g *genConversion) doBuiltin(inType, outType *types.Type, sw *generator.SnippetWriter) { - if inType == outType { - sw.Do("*out = *in\n", nil) - } else { - sw.Do("*out = $.|raw$(*in)\n", outType) - } -} - -func (g *genConversion) doMap(inType, outType *types.Type, sw *generator.SnippetWriter) { - sw.Do("*out = make($.|raw$, len(*in))\n", outType) - if isDirectlyAssignable(inType.Key, outType.Key) { - sw.Do("for key, val := range *in {\n", nil) - if isDirectlyAssignable(inType.Elem, outType.Elem) { - if inType.Key == outType.Key { - sw.Do("(*out)[key] = ", nil) - } else { - sw.Do("(*out)[$.|raw$(key)] = ", outType.Key) - } - if inType.Elem == outType.Elem { - sw.Do("val\n", nil) - } else { - sw.Do("$.|raw$(val)\n", outType.Elem) - } - } else { - conversionExists := true - if function, ok := g.preexists(inType.Elem, outType.Elem); ok { - sw.Do("newVal := new($.|raw$)\n", outType.Elem) - sw.Do("if err := $.|raw$(&val, newVal, s); err != nil {\n", function) - } else if g.convertibleOnlyWithinPackage(inType.Elem, outType.Elem) { - sw.Do("newVal := new($.|raw$)\n", outType.Elem) - sw.Do("if err := "+nameTmpl+"(&val, newVal, s); err != nil {\n", argsFromType(inType.Elem, outType.Elem)) - } else { - args := argsFromType(inType.Elem, outType.Elem) - sw.Do("// FIXME: Provide conversion function to convert $.inType|raw$ to $.outType|raw$\n", args) - sw.Do("compileErrorOnMissingConversion()\n", nil) - conversionExists = false - } - if conversionExists { - sw.Do("return err\n", nil) - sw.Do("}\n", nil) - if inType.Key == outType.Key { - sw.Do("(*out)[key] = *newVal\n", nil) - } else { - sw.Do("(*out)[$.|raw$(key)] = *newVal\n", outType.Key) - } - } - } - } else { - // TODO: Implement it when necessary. - sw.Do("for range *in {\n", nil) - sw.Do("// FIXME: Converting unassignable keys unsupported $.|raw$\n", inType.Key) - } - sw.Do("}\n", nil) -} - -func (g *genConversion) doSlice(inType, outType *types.Type, sw *generator.SnippetWriter) { - sw.Do("*out = make($.|raw$, len(*in))\n", outType) - if inType.Elem == outType.Elem && inType.Elem.Kind == types.Builtin { - sw.Do("copy(*out, *in)\n", nil) - } else { - sw.Do("for i := range *in {\n", nil) - if isDirectlyAssignable(inType.Elem, outType.Elem) { - if inType.Elem == outType.Elem { - sw.Do("(*out)[i] = (*in)[i]\n", nil) - } else { - sw.Do("(*out)[i] = $.|raw$((*in)[i])\n", outType.Elem) - } - } else { - conversionExists := true - if function, ok := g.preexists(inType.Elem, outType.Elem); ok { - sw.Do("if err := $.|raw$(&(*in)[i], &(*out)[i], s); err != nil {\n", function) - } else if g.convertibleOnlyWithinPackage(inType.Elem, outType.Elem) { - sw.Do("if err := "+nameTmpl+"(&(*in)[i], &(*out)[i], s); err != nil {\n", argsFromType(inType.Elem, outType.Elem)) - } else { - args := argsFromType(inType.Elem, outType.Elem) - sw.Do("// FIXME: Provide conversion function to convert $.inType|raw$ to $.outType|raw$\n", args) - sw.Do("compileErrorOnMissingConversion()\n", nil) - conversionExists = false - } - if conversionExists { - sw.Do("return err\n", nil) - sw.Do("}\n", nil) - } - } - sw.Do("}\n", nil) - } -} - -func (g *genConversion) doStruct(inType, outType *types.Type, sw *generator.SnippetWriter) { - for _, inMember := range inType.Members { - if tagvals := extractTag(inMember.CommentLines); tagvals != nil && tagvals[0] == "false" { - // This field is excluded from conversion. - sw.Do("// INFO: in."+inMember.Name+" opted out of conversion generation\n", nil) - continue - } - outMember, found := findMember(outType, inMember.Name) - if !found { - // This field doesn't exist in the peer. - sw.Do("// WARNING: in."+inMember.Name+" requires manual conversion: does not exist in peer-type\n", nil) - g.skippedFields[inType] = append(g.skippedFields[inType], inMember.Name) - continue - } - - inMemberType, outMemberType := inMember.Type, outMember.Type - // create a copy of both underlying types but give them the top level alias name (since aliases - // are assignable) - if underlying := unwrapAlias(inMemberType); underlying != inMemberType { - copied := *underlying - copied.Name = inMemberType.Name - inMemberType = &copied - } - if underlying := unwrapAlias(outMemberType); underlying != outMemberType { - copied := *underlying - copied.Name = outMemberType.Name - outMemberType = &copied - } - - args := argsFromType(inMemberType, outMemberType).With("name", inMember.Name) - - // try a direct memory copy for any type that has exactly equivalent values - if g.useUnsafe.Equal(inMemberType, outMemberType) { - args = args. - With("Pointer", types.Ref("unsafe", "Pointer")). - With("SliceHeader", types.Ref("reflect", "SliceHeader")) - switch inMemberType.Kind { - case types.Pointer: - sw.Do("out.$.name$ = ($.outType|raw$)($.Pointer|raw$(in.$.name$))\n", args) - continue - case types.Map: - sw.Do("out.$.name$ = *(*$.outType|raw$)($.Pointer|raw$(&in.$.name$))\n", args) - continue - case types.Slice: - sw.Do("out.$.name$ = *(*$.outType|raw$)($.Pointer|raw$(&in.$.name$))\n", args) - continue - } - } - - // check based on the top level name, not the underlying names - if function, ok := g.preexists(inMember.Type, outMember.Type); ok { - if isDrop(function.CommentLines) { - continue - } - // copy-only functions that are directly assignable can be inlined instead of invoked. - // As an example, conversion functions exist that allow types with private fields to be - // correctly copied between types. These functions are equivalent to a memory assignment, - // and are necessary for the reflection path, but should not block memory conversion. - // Convert_unversioned_Time_to_unversioned_Time is an example of this logic. - if !isCopyOnly(function.CommentLines) || !g.isFastConversion(inMemberType, outMemberType) { - args["function"] = function - sw.Do("if err := $.function|raw$(&in.$.name$, &out.$.name$, s); err != nil {\n", args) - sw.Do("return err\n", nil) - sw.Do("}\n", nil) - continue - } - klog.V(5).Infof("Skipped function %s because it is copy-only and we can use direct assignment", function.Name) - } - - // If we can't auto-convert, punt before we emit any code. - if inMemberType.Kind != outMemberType.Kind { - sw.Do("// WARNING: in."+inMember.Name+" requires manual conversion: inconvertible types ("+ - inMemberType.String()+" vs "+outMemberType.String()+")\n", nil) - g.skippedFields[inType] = append(g.skippedFields[inType], inMember.Name) - continue - } - - switch inMemberType.Kind { - case types.Builtin: - if inMemberType == outMemberType { - sw.Do("out.$.name$ = in.$.name$\n", args) - } else { - sw.Do("out.$.name$ = $.outType|raw$(in.$.name$)\n", args) - } - case types.Map, types.Slice, types.Pointer: - if g.isDirectlyAssignable(inMemberType, outMemberType) { - sw.Do("out.$.name$ = in.$.name$\n", args) - continue - } - - sw.Do("if in.$.name$ != nil {\n", args) - sw.Do("in, out := &in.$.name$, &out.$.name$\n", args) - g.generateFor(inMemberType, outMemberType, sw) - sw.Do("} else {\n", nil) - sw.Do("out.$.name$ = nil\n", args) - sw.Do("}\n", nil) - case types.Struct: - if g.isDirectlyAssignable(inMemberType, outMemberType) { - sw.Do("out.$.name$ = in.$.name$\n", args) - continue - } - conversionExists := true - if g.convertibleOnlyWithinPackage(inMemberType, outMemberType) { - sw.Do("if err := "+nameTmpl+"(&in.$.name$, &out.$.name$, s); err != nil {\n", args) - } else { - args := argsFromType(inMemberType, outMemberType) - sw.Do("// FIXME: Provide conversion function to convert $.inType|raw$ to $.outType|raw$\n", args) - sw.Do("compileErrorOnMissingConversion()\n", nil) - conversionExists = false - } - if conversionExists { - sw.Do("return err\n", nil) - sw.Do("}\n", nil) - } - case types.Alias: - if isDirectlyAssignable(inMemberType, outMemberType) { - if inMemberType == outMemberType { - sw.Do("out.$.name$ = in.$.name$\n", args) - } else { - sw.Do("out.$.name$ = $.outType|raw$(in.$.name$)\n", args) - } - } else { - conversionExists := true - if g.convertibleOnlyWithinPackage(inMemberType, outMemberType) { - sw.Do("if err := "+nameTmpl+"(&in.$.name$, &out.$.name$, s); err != nil {\n", args) - } else { - args := argsFromType(inMemberType, outMemberType) - sw.Do("// FIXME: Provide conversion function to convert $.inType|raw$ to $.outType|raw$\n", args) - sw.Do("compileErrorOnMissingConversion()\n", nil) - conversionExists = false - } - if conversionExists { - sw.Do("return err\n", nil) - sw.Do("}\n", nil) - } - } - default: - conversionExists := true - if g.convertibleOnlyWithinPackage(inMemberType, outMemberType) { - sw.Do("if err := "+nameTmpl+"(&in.$.name$, &out.$.name$, s); err != nil {\n", args) - } else { - args := argsFromType(inMemberType, outMemberType) - sw.Do("// FIXME: Provide conversion function to convert $.inType|raw$ to $.outType|raw$\n", args) - sw.Do("compileErrorOnMissingConversion()\n", nil) - conversionExists = false - } - if conversionExists { - sw.Do("return err\n", nil) - sw.Do("}\n", nil) - } - } - } -} - -func (g *genConversion) isFastConversion(inType, outType *types.Type) bool { - switch inType.Kind { - case types.Builtin: - return true - case types.Map, types.Slice, types.Pointer, types.Struct, types.Alias: - return g.isDirectlyAssignable(inType, outType) - default: - return false - } -} - -func (g *genConversion) isDirectlyAssignable(inType, outType *types.Type) bool { - return unwrapAlias(inType) == unwrapAlias(outType) -} - -func (g *genConversion) doPointer(inType, outType *types.Type, sw *generator.SnippetWriter) { - sw.Do("*out = new($.Elem|raw$)\n", outType) - if isDirectlyAssignable(inType.Elem, outType.Elem) { - if inType.Elem == outType.Elem { - sw.Do("**out = **in\n", nil) - } else { - sw.Do("**out = $.|raw$(**in)\n", outType.Elem) - } - } else { - conversionExists := true - if function, ok := g.preexists(inType.Elem, outType.Elem); ok { - sw.Do("if err := $.|raw$(*in, *out, s); err != nil {\n", function) - } else if g.convertibleOnlyWithinPackage(inType.Elem, outType.Elem) { - sw.Do("if err := "+nameTmpl+"(*in, *out, s); err != nil {\n", argsFromType(inType.Elem, outType.Elem)) - } else { - args := argsFromType(inType.Elem, outType.Elem) - sw.Do("// FIXME: Provide conversion function to convert $.inType|raw$ to $.outType|raw$\n", args) - sw.Do("compileErrorOnMissingConversion()\n", nil) - conversionExists = false - } - if conversionExists { - sw.Do("return err\n", nil) - sw.Do("}\n", nil) - } - } -} - -func (g *genConversion) doAlias(inType, outType *types.Type, sw *generator.SnippetWriter) { - // TODO: Add support for aliases. - g.doUnknown(inType, outType, sw) -} - -func (g *genConversion) doUnknown(inType, outType *types.Type, sw *generator.SnippetWriter) { - sw.Do("// FIXME: Type $.|raw$ is unsupported.\n", inType) -} - -func (g *genConversion) generateFromUrlValues(inType, outType *types.Type, sw *generator.SnippetWriter) { - args := generator.Args{ - "inType": inType, - "outType": outType, - "Scope": types.Ref(conversionPackagePath, "Scope"), - } - sw.Do("func auto"+nameTmpl+"(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n", args) - for _, outMember := range outType.Members { - if tagvals := extractTag(outMember.CommentLines); tagvals != nil && tagvals[0] == "false" { - // This field is excluded from conversion. - sw.Do("// INFO: in."+outMember.Name+" opted out of conversion generation\n", nil) - continue - } - jsonTag := reflect.StructTag(outMember.Tags).Get("json") - index := strings.Index(jsonTag, ",") - if index == -1 { - index = len(jsonTag) - } - if index == 0 { - memberArgs := generator.Args{ - "name": outMember.Name, - } - sw.Do("// WARNING: Field $.name$ does not have json tag, skipping.\n\n", memberArgs) - continue - } - memberArgs := generator.Args{ - "name": outMember.Name, - "tag": jsonTag[:index], - } - sw.Do("if values, ok := map[string][]string(*in)[\"$.tag$\"]; ok && len(values) > 0 {\n", memberArgs) - g.fromValuesEntry(inType.Underlying.Elem, outMember, sw) - sw.Do("} else {\n", nil) - g.setZeroValue(outMember, sw) - sw.Do("}\n", nil) - } - sw.Do("return nil\n", nil) - sw.Do("}\n\n", nil) - - if _, found := g.preexists(inType, outType); found { - // There is a public manual Conversion method: use it. - } else { - // Emit a public conversion function. - sw.Do("// "+nameTmpl+" is an autogenerated conversion function.\n", args) - sw.Do("func "+nameTmpl+"(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n", args) - sw.Do("return auto"+nameTmpl+"(in, out, s)\n", args) - sw.Do("}\n\n", nil) - } -} - -func (g *genConversion) fromValuesEntry(inType *types.Type, outMember types.Member, sw *generator.SnippetWriter) { - memberArgs := generator.Args{ - "name": outMember.Name, - "type": outMember.Type, - } - if function, ok := g.preexists(inType, outMember.Type); ok { - args := memberArgs.With("function", function) - sw.Do("if err := $.function|raw$(&values, &out.$.name$, s); err != nil {\n", args) - sw.Do("return err\n", nil) - sw.Do("}\n", nil) - return - } - switch { - case outMember.Type == types.String: - sw.Do("out.$.name$ = values[0]\n", memberArgs) - case g.useUnsafe.Equal(inType, outMember.Type): - args := memberArgs.With("Pointer", types.Ref("unsafe", "Pointer")) - switch inType.Kind { - case types.Pointer: - sw.Do("out.$.name$ = ($.type|raw$)($.Pointer|raw$(&values))\n", args) - case types.Map, types.Slice: - sw.Do("out.$.name$ = *(*$.type|raw$)($.Pointer|raw$(&values))\n", args) - default: - // TODO: Support other types to allow more auto-conversions. - sw.Do("// FIXME: out.$.name$ is of not yet supported type and requires manual conversion\n", memberArgs) - } - default: - // TODO: Support other types to allow more auto-conversions. - sw.Do("// FIXME: out.$.name$ is of not yet supported type and requires manual conversion\n", memberArgs) - } -} - -func (g *genConversion) setZeroValue(outMember types.Member, sw *generator.SnippetWriter) { - outMemberType := unwrapAlias(outMember.Type) - memberArgs := generator.Args{ - "name": outMember.Name, - "alias": outMember.Type, - "type": outMemberType, - } - - switch outMemberType.Kind { - case types.Builtin: - switch outMemberType { - case types.String: - sw.Do("out.$.name$ = \"\"\n", memberArgs) - case types.Int64, types.Int32, types.Int16, types.Int, types.Uint64, types.Uint32, types.Uint16, types.Uint: - sw.Do("out.$.name$ = 0\n", memberArgs) - case types.Uintptr, types.Byte: - sw.Do("out.$.name$ = 0\n", memberArgs) - case types.Float64, types.Float32, types.Float: - sw.Do("out.$.name$ = 0\n", memberArgs) - case types.Bool: - sw.Do("out.$.name$ = false\n", memberArgs) - default: - sw.Do("// FIXME: out.$.name$ is of unsupported type and requires manual conversion\n", memberArgs) - } - case types.Struct: - if outMemberType == outMember.Type { - sw.Do("out.$.name$ = $.type|raw${}\n", memberArgs) - } else { - sw.Do("out.$.name$ = $.alias|raw$($.type|raw${})\n", memberArgs) - } - case types.Map, types.Slice, types.Pointer: - sw.Do("out.$.name$ = nil\n", memberArgs) - case types.Alias: - // outMemberType was already unwrapped from aliases - so that should never happen. - sw.Do("// FIXME: unexpected error for out.$.name$\n", memberArgs) - case types.Interface, types.Array: - sw.Do("out.$.name$ = nil\n", memberArgs) - default: - sw.Do("// FIXME: out.$.name$ is of unsupported type and requires manual conversion\n", memberArgs) - } -} - -func isDirectlyAssignable(inType, outType *types.Type) bool { - // TODO: This should maybe check for actual assignability between the two - // types, rather than superficial traits that happen to indicate it is - // assignable in the ways we currently use this code. - return inType.IsAssignable() && (inType.IsPrimitive() || isSamePackage(inType, outType)) -} - -func isSamePackage(inType, outType *types.Type) bool { - return inType.Name.Package == outType.Name.Package -} diff --git a/vendor/k8s.io/code-generator/cmd/conversion-gen/main.go b/vendor/k8s.io/code-generator/cmd/conversion-gen/main.go deleted file mode 100644 index 5a461d27..00000000 --- a/vendor/k8s.io/code-generator/cmd/conversion-gen/main.go +++ /dev/null @@ -1,139 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -// conversion-gen is a tool for auto-generating functions that convert -// between internal and external types. A general conversion code -// generation task involves three sets of packages: (1) a set of -// packages containing internal types, (2) a single package containing -// the external types, and (3) a single destination package (i.e., -// where the generated conversion functions go, and where the -// developer-authored conversion functions are). The packages -// containing the internal types play the role known as "peer -// packages" in the general code-generation framework of Kubernetes. -// -// For each conversion task, `conversion-gen` will generate functions -// that efficiently convert between same-name types in the two -// (internal, external) packages. The generated functions include -// ones named -// -// autoConvert___To__ -// -// for each such pair of types --- both with (pkg1,pkg2) = -// (internal,external) and (pkg1,pkg2) = (external,internal). The -// generated conversion functions recurse on the structure of the data -// types. For structs, source and destination fields are matched up -// according to name; if a source field has no corresponding -// destination or there is a fundamental mismatch in the type of the -// field then the generated autoConvert_... function has just a -// warning comment about that field. The generated conversion -// functions use standard value assignment wherever possible. For -// compound types, the generated conversion functions call the -// `Convert...` functions for the subsidiary types. -// -// For each pair of types `conversion-gen` will also generate a -// function named -// -// Convert___To__ -// -// if both of two conditions are met: (1) the destination package does -// not contain a function of that name in a non-generated file and (2) -// the generation of the corresponding autoConvert_... function did -// not run into trouble with a missing or fundamentally differently -// typed field. A generated Convert_... function simply calls the -// corresponding `autoConvert...` function. `conversion_gen` also -// generates a function that updates a given `runtime.Scheme` by -// registering all the Convert_... functions found and generated. -// Thus developers can override the generated behavior for selected -// type pairs by putting the desired Convert_... functions in -// non-generated files. Further, developers are practically required -// to override the generated behavior when there are missing or -// fundamentally differently typed fields. -// -// `conversion-gen` will scan its `--input-dirs`, looking at the -// package defined in each of those directories for comment tags that -// define a conversion code generation task. A package requests -// conversion code generation by including one or more comment in the -// package's `doc.go` file (currently anywhere in that file is -// acceptable, but the recommended location is above the `package` -// statement), of the form: -// -// // +k8s:conversion-gen= -// -// This introduces a conversion task, for which the destination -// package is the one containing the file with the tag and the tag -// identifies a package containing internal types. If there is also a -// tag of the form -// -// // +k8s:conversion-gen-external-types= -// -// then it identifies the package containing the external types; -// otherwise they are in the destination package. -// -// For each conversion code generation task, the full set of internal -// packages (AKA peer packages) consists of the ones specified in the -// `k8s:conversion-gen` tags PLUS any specified in the -// `--base-peer-dirs` and `--extra-peer-dirs` flags on the command -// line. -// -// When generating for a package, individual types or fields of structs may opt -// out of Conversion generation by specifying a comment on the of the form: -// -// // +k8s:conversion-gen=false -package main - -import ( - "flag" - - "github.com/spf13/pflag" - "k8s.io/klog/v2" - - generatorargs "k8s.io/code-generator/cmd/conversion-gen/args" - "k8s.io/code-generator/cmd/conversion-gen/generators" -) - -func main() { - klog.InitFlags(nil) - genericArgs, customArgs := generatorargs.NewDefaults() - - genericArgs.AddFlags(pflag.CommandLine) - customArgs.AddFlags(pflag.CommandLine) - flag.Set("logtostderr", "true") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - // k8s.io/apimachinery/pkg/runtime contains a number of manual conversions, - // that we need to generate conversions. - // Packages being dependencies of explicitly requested packages are only - // partially scanned - only types explicitly used are being traversed. - // Not used functions or types are omitted. - // Adding this explicitly to InputDirs ensures that the package is fully - // scanned and all functions are parsed and processed. - genericArgs.InputDirs = append(genericArgs.InputDirs, "k8s.io/apimachinery/pkg/runtime") - - if err := generatorargs.Validate(genericArgs); err != nil { - klog.Fatalf("Error: %v", err) - } - - // Run it. - if err := genericArgs.Execute( - generators.NameSystems(), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Fatalf("Error: %v", err) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go b/vendor/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go deleted file mode 100644 index 78971301..00000000 --- a/vendor/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "fmt" - - "github.com/spf13/pflag" - "k8s.io/gengo/args" - "k8s.io/gengo/examples/deepcopy-gen/generators" -) - -// CustomArgs is used by the gengo framework to pass args specific to this generator. -type CustomArgs generators.CustomArgs - -// NewDefaults returns default arguments for the generator. -func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { - genericArgs := args.Default().WithoutDefaultFlagParsing() - customArgs := &CustomArgs{} - genericArgs.CustomArgs = (*generators.CustomArgs)(customArgs) // convert to upstream type to make type-casts work there - genericArgs.OutputFileBaseName = "deepcopy_generated" - return genericArgs, customArgs -} - -// AddFlags add the generator flags to the flag set. -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { - pflag.CommandLine.StringSliceVar(&ca.BoundingDirs, "bounding-dirs", ca.BoundingDirs, - "Comma-separated list of import paths which bound the types for which deep-copies will be generated.") -} - -// Validate checks the given arguments. -func Validate(genericArgs *args.GeneratorArgs) error { - _ = genericArgs.CustomArgs.(*generators.CustomArgs) - - if len(genericArgs.OutputFileBaseName) == 0 { - return fmt.Errorf("output file base name cannot be empty") - } - - return nil -} diff --git a/vendor/k8s.io/code-generator/cmd/deepcopy-gen/main.go b/vendor/k8s.io/code-generator/cmd/deepcopy-gen/main.go deleted file mode 100644 index 5622c1a1..00000000 --- a/vendor/k8s.io/code-generator/cmd/deepcopy-gen/main.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// deepcopy-gen is a tool for auto-generating DeepCopy functions. -// -// Given a list of input directories, it will generate functions that -// efficiently perform a full deep-copy of each type. For any type that -// offers a `.DeepCopy()` method, it will simply call that. Otherwise it will -// use standard value assignment whenever possible. If that is not possible it -// will try to call its own generated copy function for the type, if the type is -// within the allowed root packages. Failing that, it will fall back on -// `conversion.Cloner.DeepCopy(val)` to make the copy. The resulting file will -// be stored in the same directory as the processed source package. -// -// Generation is governed by comment tags in the source. Any package may -// request DeepCopy generation by including a comment in the file-comments of -// one file, of the form: -// -// // +k8s:deepcopy-gen=package -// -// DeepCopy functions can be generated for individual types, rather than the -// entire package by specifying a comment on the type definion of the form: -// -// // +k8s:deepcopy-gen=true -// -// When generating for a whole package, individual types may opt out of -// DeepCopy generation by specifying a comment on the of the form: -// -// // +k8s:deepcopy-gen=false -// -// Note that registration is a whole-package option, and is not available for -// individual types. -package main - -import ( - "flag" - - "github.com/spf13/pflag" - "k8s.io/gengo/examples/deepcopy-gen/generators" - "k8s.io/klog/v2" - - generatorargs "k8s.io/code-generator/cmd/deepcopy-gen/args" -) - -func main() { - klog.InitFlags(nil) - genericArgs, customArgs := generatorargs.NewDefaults() - - genericArgs.AddFlags(pflag.CommandLine) - customArgs.AddFlags(pflag.CommandLine) - flag.Set("logtostderr", "true") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - if err := generatorargs.Validate(genericArgs); err != nil { - klog.Fatalf("Error: %v", err) - } - - // Run it. - if err := genericArgs.Execute( - generators.NameSystems(), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Fatalf("Error: %v", err) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/cmd/defaulter-gen/args/args.go b/vendor/k8s.io/code-generator/cmd/defaulter-gen/args/args.go deleted file mode 100644 index 3c5a042c..00000000 --- a/vendor/k8s.io/code-generator/cmd/defaulter-gen/args/args.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "fmt" - - "github.com/spf13/pflag" - "k8s.io/gengo/args" - "k8s.io/gengo/examples/defaulter-gen/generators" -) - -// CustomArgs is used by the gengo framework to pass args specific to this generator. -type CustomArgs generators.CustomArgs - -// NewDefaults returns default arguments for the generator. -func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { - genericArgs := args.Default().WithoutDefaultFlagParsing() - customArgs := &CustomArgs{} - genericArgs.CustomArgs = (*generators.CustomArgs)(customArgs) // convert to upstream type to make type-casts work there - genericArgs.OutputFileBaseName = "zz_generated.defaults" - return genericArgs, customArgs -} - -// AddFlags add the generator flags to the flag set. -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { - pflag.CommandLine.StringSliceVar(&ca.ExtraPeerDirs, "extra-peer-dirs", ca.ExtraPeerDirs, - "Comma-separated list of import paths which are considered, after tag-specified peers, for conversions.") -} - -// Validate checks the given arguments. -func Validate(genericArgs *args.GeneratorArgs) error { - _ = genericArgs.CustomArgs.(*generators.CustomArgs) - - if len(genericArgs.OutputFileBaseName) == 0 { - return fmt.Errorf("output file base name cannot be empty") - } - - return nil -} diff --git a/vendor/k8s.io/code-generator/cmd/defaulter-gen/main.go b/vendor/k8s.io/code-generator/cmd/defaulter-gen/main.go deleted file mode 100644 index 23d5d327..00000000 --- a/vendor/k8s.io/code-generator/cmd/defaulter-gen/main.go +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -// defaulter-gen is a tool for auto-generating Defaulter functions. -// -// Given a list of input directories, it will scan for top level types -// and generate efficient defaulters for an entire object from the sum -// of the SetDefault_* methods contained in the object tree. -// -// Generation is governed by comment tags in the source. Any package may -// request defaulter generation by including one or more comment tags at -// the package comment level: -// -// // +k8s:defaulter-gen= -// -// which will create defaulters for any type that contains the provided -// field name (if the type has defaulters). Any type may request explicit -// defaulting by providing the comment tag: -// -// // +k8s:defaulter-gen=true|false -// -// An existing defaulter method (`SetDefaults_TYPE`) can provide the -// comment tag: -// -// // +k8s:defaulter-gen=covers -// -// to indicate that the defaulter does not or should not call any nested -// defaulters. -package main - -import ( - "flag" - - "github.com/spf13/pflag" - "k8s.io/gengo/examples/defaulter-gen/generators" - "k8s.io/klog/v2" - - generatorargs "k8s.io/code-generator/cmd/defaulter-gen/args" -) - -func main() { - klog.InitFlags(nil) - genericArgs, customArgs := generatorargs.NewDefaults() - - genericArgs.AddFlags(pflag.CommandLine) - customArgs.AddFlags(pflag.CommandLine) - flag.Set("logtostderr", "true") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - if err := generatorargs.Validate(genericArgs); err != nil { - klog.Fatalf("Error: %v", err) - } - - // Run it. - if err := genericArgs.Execute( - generators.NameSystems(), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Fatalf("Error: %v", err) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/.gitignore b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/.gitignore deleted file mode 100644 index 0e9aa466..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/.gitignore +++ /dev/null @@ -1 +0,0 @@ -go-to-protobuf diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/OWNERS b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/OWNERS deleted file mode 100644 index af7e2ec4..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - smarterclayton -reviewers: - - smarterclayton diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/main.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/main.go deleted file mode 100644 index 00997338..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/main.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// go-to-protobuf generates a Protobuf IDL from a Go struct, respecting any -// existing IDL tags on the Go struct. -package main - -import ( - goflag "flag" - - flag "github.com/spf13/pflag" - "k8s.io/code-generator/cmd/go-to-protobuf/protobuf" - "k8s.io/klog/v2" -) - -var g = protobuf.New() - -func init() { - klog.InitFlags(nil) - g.BindFlags(flag.CommandLine) - goflag.Set("logtostderr", "true") - flag.CommandLine.AddGoFlagSet(goflag.CommandLine) -} - -func main() { - flag.Parse() - protobuf.Run(g) -} diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go deleted file mode 100644 index ff267e26..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/cmd.go +++ /dev/null @@ -1,480 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// go-to-protobuf generates a Protobuf IDL from a Go struct, respecting any -// existing IDL tags on the Go struct. -package protobuf - -import ( - "bytes" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "sort" - "strings" - - flag "github.com/spf13/pflag" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/parser" - "k8s.io/gengo/types" -) - -type Generator struct { - Common args.GeneratorArgs - APIMachineryPackages string - Packages string - OutputBase string - VendorOutputBase string - ProtoImport []string - Conditional string - Clean bool - OnlyIDL bool - KeepGogoproto bool - SkipGeneratedRewrite bool - DropEmbeddedFields string - TrimPathPrefix string -} - -func New() *Generator { - sourceTree := args.DefaultSourceTree() - common := args.GeneratorArgs{ - OutputBase: sourceTree, - } - defaultProtoImport := filepath.Join(sourceTree, "k8s.io", "kubernetes", "vendor", "github.com", "gogo", "protobuf", "protobuf") - cwd, err := os.Getwd() - if err != nil { - log.Fatalf("Cannot get current directory.") - } - return &Generator{ - Common: common, - OutputBase: sourceTree, - VendorOutputBase: filepath.Join(cwd, "vendor"), - ProtoImport: []string{defaultProtoImport}, - APIMachineryPackages: strings.Join([]string{ - `+k8s.io/apimachinery/pkg/util/intstr`, - `+k8s.io/apimachinery/pkg/api/resource`, - `+k8s.io/apimachinery/pkg/runtime/schema`, - `+k8s.io/apimachinery/pkg/runtime`, - `k8s.io/apimachinery/pkg/apis/meta/v1`, - `k8s.io/apimachinery/pkg/apis/meta/v1beta1`, - `k8s.io/apimachinery/pkg/apis/testapigroup/v1`, - }, ","), - Packages: "", - DropEmbeddedFields: "k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta", - } -} - -func (g *Generator) BindFlags(flag *flag.FlagSet) { - flag.StringVarP(&g.Common.GoHeaderFilePath, "go-header-file", "h", g.Common.GoHeaderFilePath, "File containing boilerplate header text. The string YEAR will be replaced with the current 4-digit year.") - flag.BoolVar(&g.Common.VerifyOnly, "verify-only", g.Common.VerifyOnly, "If true, only verify existing output, do not write anything.") - flag.StringVarP(&g.Packages, "packages", "p", g.Packages, "comma-separated list of directories to get input types from. Directories prefixed with '-' are not generated, directories prefixed with '+' only create types with explicit IDL instructions.") - flag.StringVar(&g.APIMachineryPackages, "apimachinery-packages", g.APIMachineryPackages, "comma-separated list of directories to get apimachinery input types from which are needed by any API. Directories prefixed with '-' are not generated, directories prefixed with '+' only create types with explicit IDL instructions.") - flag.StringVarP(&g.OutputBase, "output-base", "o", g.OutputBase, "Output base; defaults to $GOPATH/src/") - flag.StringVar(&g.VendorOutputBase, "vendor-output-base", g.VendorOutputBase, "The vendor/ directory to look for packages in; defaults to $PWD/vendor/.") - flag.StringSliceVar(&g.ProtoImport, "proto-import", g.ProtoImport, "The search path for the core protobuf .protos, required; defaults $GOPATH/src/k8s.io/kubernetes/vendor/github.com/gogo/protobuf/protobuf.") - flag.StringVar(&g.Conditional, "conditional", g.Conditional, "An optional Golang build tag condition to add to the generated Go code") - flag.BoolVar(&g.Clean, "clean", g.Clean, "If true, remove all generated files for the specified Packages.") - flag.BoolVar(&g.OnlyIDL, "only-idl", g.OnlyIDL, "If true, only generate the IDL for each package.") - flag.BoolVar(&g.KeepGogoproto, "keep-gogoproto", g.KeepGogoproto, "If true, the generated IDL will contain gogoprotobuf extensions which are normally removed") - flag.BoolVar(&g.SkipGeneratedRewrite, "skip-generated-rewrite", g.SkipGeneratedRewrite, "If true, skip fixing up the generated.pb.go file (debugging only).") - flag.StringVar(&g.DropEmbeddedFields, "drop-embedded-fields", g.DropEmbeddedFields, "Comma-delimited list of embedded Go types to omit from generated protobufs") - flag.StringVar(&g.TrimPathPrefix, "trim-path-prefix", g.TrimPathPrefix, "If set, trim the specified prefix from --output-package when generating files.") -} - -func Run(g *Generator) { - if g.Common.VerifyOnly { - g.OnlyIDL = true - g.Clean = false - } - - b := parser.New() - b.AddBuildTags("proto") - - omitTypes := map[types.Name]struct{}{} - for _, t := range strings.Split(g.DropEmbeddedFields, ",") { - name := types.Name{} - if i := strings.LastIndex(t, "."); i != -1 { - name.Package, name.Name = t[:i], t[i+1:] - } else { - name.Name = t - } - if len(name.Name) == 0 { - log.Fatalf("--drop-embedded-types requires names in the form of [GOPACKAGE.]TYPENAME: %v", t) - } - omitTypes[name] = struct{}{} - } - - boilerplate, err := g.Common.LoadGoBoilerplate() - if err != nil { - log.Fatalf("Failed loading boilerplate (consider using the go-header-file flag): %v", err) - } - - protobufNames := NewProtobufNamer() - outputPackages := generator.Packages{} - nonOutputPackages := map[string]struct{}{} - - var packages []string - if len(g.APIMachineryPackages) != 0 { - packages = append(packages, strings.Split(g.APIMachineryPackages, ",")...) - } - if len(g.Packages) != 0 { - packages = append(packages, strings.Split(g.Packages, ",")...) - } - if len(packages) == 0 { - log.Fatalf("Both apimachinery-packages and packages are empty. At least one package must be specified.") - } - - for _, d := range packages { - generateAllTypes, outputPackage := true, true - switch { - case strings.HasPrefix(d, "+"): - d = d[1:] - generateAllTypes = false - case strings.HasPrefix(d, "-"): - d = d[1:] - outputPackage = false - } - name := protoSafePackage(d) - parts := strings.SplitN(d, "=", 2) - if len(parts) > 1 { - d = parts[0] - name = parts[1] - } - p := newProtobufPackage(d, name, generateAllTypes, omitTypes) - header := append([]byte{}, boilerplate...) - header = append(header, p.HeaderText...) - p.HeaderText = header - protobufNames.Add(p) - if outputPackage { - outputPackages = append(outputPackages, p) - } else { - nonOutputPackages[name] = struct{}{} - } - } - - if !g.Common.VerifyOnly { - for _, p := range outputPackages { - if err := p.(*protobufPackage).Clean(g.OutputBase); err != nil { - log.Fatalf("Unable to clean package %s: %v", p.Name(), err) - } - } - } - - if g.Clean { - return - } - - for _, p := range protobufNames.List() { - if err := b.AddDir(p.Path()); err != nil { - log.Fatalf("Unable to add directory %q: %v", p.Path(), err) - } - } - - c, err := generator.NewContext( - b, - namer.NameSystems{ - "public": namer.NewPublicNamer(3), - "proto": protobufNames, - }, - "public", - ) - if err != nil { - log.Fatalf("Failed making a context: %v", err) - } - - c.Verify = g.Common.VerifyOnly - c.FileTypes["protoidl"] = NewProtoFile() - c.TrimPathPrefix = g.TrimPathPrefix - - // order package by imports, importees first - deps := deps(c, protobufNames.packages) - order, err := importOrder(deps) - if err != nil { - log.Fatalf("Failed to order packages by imports: %v", err) - } - topologicalPos := map[string]int{} - for i, p := range order { - topologicalPos[p] = i - } - sort.Sort(positionOrder{topologicalPos, protobufNames.packages}) - - var vendoredOutputPackages, localOutputPackages generator.Packages - for _, p := range protobufNames.packages { - if _, ok := nonOutputPackages[p.Name()]; ok { - // if we're not outputting the package, don't include it in either package list - continue - } - p.Vendored = strings.Contains(c.Universe[p.PackagePath].SourcePath, "/vendor/") - if p.Vendored { - vendoredOutputPackages = append(vendoredOutputPackages, p) - } else { - localOutputPackages = append(localOutputPackages, p) - } - } - - if err := protobufNames.AssignTypesToPackages(c); err != nil { - log.Fatalf("Failed to identify Common types: %v", err) - } - - if err := c.ExecutePackages(g.VendorOutputBase, vendoredOutputPackages); err != nil { - log.Fatalf("Failed executing vendor generator: %v", err) - } - if err := c.ExecutePackages(g.OutputBase, localOutputPackages); err != nil { - log.Fatalf("Failed executing local generator: %v", err) - } - - if g.OnlyIDL { - return - } - - if _, err := exec.LookPath("protoc"); err != nil { - log.Fatalf("Unable to find 'protoc': %v", err) - } - - searchArgs := []string{"-I", ".", "-I", g.OutputBase} - if len(g.ProtoImport) != 0 { - for _, s := range g.ProtoImport { - searchArgs = append(searchArgs, "-I", s) - } - } - args := append(searchArgs, fmt.Sprintf("--gogo_out=%s", g.OutputBase)) - - buf := &bytes.Buffer{} - if len(g.Conditional) > 0 { - fmt.Fprintf(buf, "// +build %s\n\n", g.Conditional) - } - buf.Write(boilerplate) - - for _, outputPackage := range outputPackages { - p := outputPackage.(*protobufPackage) - - path := filepath.Join(g.OutputBase, p.ImportPath()) - outputPath := filepath.Join(g.OutputBase, p.OutputPath()) - if p.Vendored { - path = filepath.Join(g.VendorOutputBase, p.ImportPath()) - outputPath = filepath.Join(g.VendorOutputBase, p.OutputPath()) - } - - // When working outside of GOPATH, we typically won't want to generate the - // full path for a package. For example, if our current project's root/base - // package is github.com/foo/bar, outDir=., p.Path()=github.com/foo/bar/generated, - // then we really want to be writing files to ./generated, not ./github.com/foo/bar/generated. - // The following will trim a path prefix (github.com/foo/bar) from p.Path() to arrive at - // a relative path that works with projects not in GOPATH. - if g.TrimPathPrefix != "" { - separator := string(filepath.Separator) - if !strings.HasSuffix(g.TrimPathPrefix, separator) { - g.TrimPathPrefix += separator - } - - path = strings.TrimPrefix(path, g.TrimPathPrefix) - outputPath = strings.TrimPrefix(outputPath, g.TrimPathPrefix) - } - - // generate the gogoprotobuf protoc - cmd := exec.Command("protoc", append(args, path)...) - out, err := cmd.CombinedOutput() - if err != nil { - log.Println(strings.Join(cmd.Args, " ")) - log.Println(string(out)) - log.Fatalf("Unable to generate protoc on %s: %v", p.PackageName, err) - } - - if g.SkipGeneratedRewrite { - continue - } - - // alter the generated protobuf file to remove the generated types (but leave the serializers) and rewrite the - // package statement to match the desired package name - if err := RewriteGeneratedGogoProtobufFile(outputPath, p.ExtractGeneratedType, p.OptionalTypeName, buf.Bytes()); err != nil { - log.Fatalf("Unable to rewrite generated %s: %v", outputPath, err) - } - - // sort imports - cmd = exec.Command("goimports", "-w", outputPath) - out, err = cmd.CombinedOutput() - if len(out) > 0 { - log.Print(string(out)) - } - if err != nil { - log.Println(strings.Join(cmd.Args, " ")) - log.Fatalf("Unable to rewrite imports for %s: %v", p.PackageName, err) - } - - // format and simplify the generated file - cmd = exec.Command("gofmt", "-s", "-w", outputPath) - out, err = cmd.CombinedOutput() - if len(out) > 0 { - log.Print(string(out)) - } - if err != nil { - log.Println(strings.Join(cmd.Args, " ")) - log.Fatalf("Unable to apply gofmt for %s: %v", p.PackageName, err) - } - } - - if g.SkipGeneratedRewrite { - return - } - - if !g.KeepGogoproto { - // generate, but do so without gogoprotobuf extensions - for _, outputPackage := range outputPackages { - p := outputPackage.(*protobufPackage) - p.OmitGogo = true - } - if err := c.ExecutePackages(g.VendorOutputBase, vendoredOutputPackages); err != nil { - log.Fatalf("Failed executing vendor generator: %v", err) - } - if err := c.ExecutePackages(g.OutputBase, localOutputPackages); err != nil { - log.Fatalf("Failed executing local generator: %v", err) - } - } - - for _, outputPackage := range outputPackages { - p := outputPackage.(*protobufPackage) - - if len(p.StructTags) == 0 { - continue - } - - pattern := filepath.Join(g.OutputBase, p.PackagePath, "*.go") - if p.Vendored { - pattern = filepath.Join(g.VendorOutputBase, p.PackagePath, "*.go") - } - files, err := filepath.Glob(pattern) - if err != nil { - log.Fatalf("Can't glob pattern %q: %v", pattern, err) - } - - for _, s := range files { - if strings.HasSuffix(s, "_test.go") { - continue - } - if err := RewriteTypesWithProtobufStructTags(s, p.StructTags); err != nil { - log.Fatalf("Unable to rewrite with struct tags %s: %v", s, err) - } - } - } -} - -func deps(c *generator.Context, pkgs []*protobufPackage) map[string][]string { - ret := map[string][]string{} - for _, p := range pkgs { - pkg, ok := c.Universe[p.PackagePath] - if !ok { - log.Fatalf("Unrecognized package: %s", p.PackagePath) - } - - for _, d := range pkg.Imports { - ret[p.PackagePath] = append(ret[p.PackagePath], d.Path) - } - } - return ret -} - -// given a set of pkg->[]deps, return the order that ensures all deps are processed before the things that depend on them -func importOrder(deps map[string][]string) ([]string, error) { - // add all nodes and edges - var remainingNodes = map[string]struct{}{} - var graph = map[edge]struct{}{} - for to, froms := range deps { - remainingNodes[to] = struct{}{} - for _, from := range froms { - remainingNodes[from] = struct{}{} - graph[edge{from: from, to: to}] = struct{}{} - } - } - - // find initial nodes without any dependencies - sorted := findAndRemoveNodesWithoutDependencies(remainingNodes, graph) - for i := 0; i < len(sorted); i++ { - node := sorted[i] - removeEdgesFrom(node, graph) - sorted = append(sorted, findAndRemoveNodesWithoutDependencies(remainingNodes, graph)...) - } - if len(remainingNodes) > 0 { - return nil, fmt.Errorf("cycle: remaining nodes: %#v, remaining edges: %#v", remainingNodes, graph) - } - //for _, n := range sorted { - // fmt.Println("topological order", n) - //} - return sorted, nil -} - -// edge describes a from->to relationship in a graph -type edge struct { - from string - to string -} - -// findAndRemoveNodesWithoutDependencies finds nodes in the given set which are not pointed to by any edges in the graph, -// removes them from the set of nodes, and returns them in sorted order -func findAndRemoveNodesWithoutDependencies(nodes map[string]struct{}, graph map[edge]struct{}) []string { - roots := []string{} - // iterate over all nodes as potential "to" nodes - for node := range nodes { - incoming := false - // iterate over all remaining edges - for edge := range graph { - // if there's any edge to the node we care about, it's not a root - if edge.to == node { - incoming = true - break - } - } - // if there are no incoming edges, remove from the set of remaining nodes and add to our results - if !incoming { - delete(nodes, node) - roots = append(roots, node) - } - } - sort.Strings(roots) - return roots -} - -// removeEdgesFrom removes any edges from the graph where edge.from == node -func removeEdgesFrom(node string, graph map[edge]struct{}) { - for edge := range graph { - if edge.from == node { - delete(graph, edge) - } - } -} - -type positionOrder struct { - pos map[string]int - elements []*protobufPackage -} - -func (o positionOrder) Len() int { - return len(o.elements) -} - -func (o positionOrder) Less(i, j int) bool { - return o.pos[o.elements[i].PackagePath] < o.pos[o.elements[j].PackagePath] -} - -func (o positionOrder) Swap(i, j int) { - x := o.elements[i] - o.elements[i] = o.elements[j] - o.elements[j] = x -} diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go deleted file mode 100644 index c480a8a6..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go +++ /dev/null @@ -1,773 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package protobuf - -import ( - "fmt" - "io" - "log" - "reflect" - "sort" - "strconv" - "strings" - - "k8s.io/klog/v2" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// genProtoIDL produces a .proto IDL. -type genProtoIDL struct { - generator.DefaultGen - localPackage types.Name - localGoPackage types.Name - imports namer.ImportTracker - - generateAll bool - omitGogo bool - omitFieldTypes map[types.Name]struct{} -} - -func (g *genProtoIDL) PackageVars(c *generator.Context) []string { - if g.omitGogo { - return []string{ - fmt.Sprintf("option go_package = %q;", g.localGoPackage.Package), - } - } - return []string{ - "option (gogoproto.marshaler_all) = true;", - "option (gogoproto.stable_marshaler_all) = true;", - "option (gogoproto.sizer_all) = true;", - "option (gogoproto.goproto_stringer_all) = false;", - "option (gogoproto.stringer_all) = true;", - "option (gogoproto.unmarshaler_all) = true;", - "option (gogoproto.goproto_unrecognized_all) = false;", - "option (gogoproto.goproto_enum_prefix_all) = false;", - "option (gogoproto.goproto_getters_all) = false;", - fmt.Sprintf("option go_package = %q;", g.localGoPackage.Package), - } -} -func (g *genProtoIDL) Filename() string { return g.OptionalName + ".proto" } -func (g *genProtoIDL) FileType() string { return "protoidl" } -func (g *genProtoIDL) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - // The local namer returns the correct protobuf name for a proto type - // in the context of a package - "local": localNamer{g.localPackage}, - } -} - -// Filter ignores types that are identified as not exportable. -func (g *genProtoIDL) Filter(c *generator.Context, t *types.Type) bool { - tagVals := types.ExtractCommentTags("+", t.CommentLines)["protobuf"] - if tagVals != nil { - if tagVals[0] == "false" { - // Type specified "false". - return false - } - if tagVals[0] == "true" { - // Type specified "true". - return true - } - klog.Fatalf(`Comment tag "protobuf" must be true or false, found: %q`, tagVals[0]) - } - if !g.generateAll { - // We're not generating everything. - return false - } - seen := map[*types.Type]bool{} - ok := isProtoable(seen, t) - return ok -} - -func isProtoable(seen map[*types.Type]bool, t *types.Type) bool { - if seen[t] { - // be optimistic in the case of type cycles. - return true - } - seen[t] = true - switch t.Kind { - case types.Builtin: - return true - case types.Alias: - return isProtoable(seen, t.Underlying) - case types.Slice, types.Pointer: - return isProtoable(seen, t.Elem) - case types.Map: - return isProtoable(seen, t.Key) && isProtoable(seen, t.Elem) - case types.Struct: - if len(t.Members) == 0 { - return true - } - for _, m := range t.Members { - if isProtoable(seen, m.Type) { - return true - } - } - return false - case types.Func, types.Chan: - return false - case types.DeclarationOf, types.Unknown, types.Unsupported: - return false - case types.Interface: - return false - default: - log.Printf("WARNING: type %q is not portable: %s", t.Kind, t.Name) - return false - } -} - -// isOptionalAlias should return true if the specified type has an underlying type -// (is an alias) of a map or slice and has the comment tag protobuf.nullable=true, -// indicating that the type should be nullable in protobuf. -func isOptionalAlias(t *types.Type) bool { - if t.Underlying == nil || (t.Underlying.Kind != types.Map && t.Underlying.Kind != types.Slice) { - return false - } - if extractBoolTagOrDie("protobuf.nullable", t.CommentLines) == false { - return false - } - return true -} - -func (g *genProtoIDL) Imports(c *generator.Context) (imports []string) { - lines := []string{} - // TODO: this could be expressed more cleanly - for _, line := range g.imports.ImportLines() { - if g.omitGogo && line == "github.com/gogo/protobuf/gogoproto/gogo.proto" { - continue - } - lines = append(lines, line) - } - return lines -} - -// GenerateType makes the body of a file implementing a set for type t. -func (g *genProtoIDL) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - b := bodyGen{ - locator: &protobufLocator{ - namer: c.Namers["proto"].(ProtobufFromGoNamer), - tracker: g.imports, - universe: c.Universe, - - localGoPackage: g.localGoPackage.Package, - }, - localPackage: g.localPackage, - - omitGogo: g.omitGogo, - omitFieldTypes: g.omitFieldTypes, - - t: t, - } - switch t.Kind { - case types.Alias: - return b.doAlias(sw) - case types.Struct: - return b.doStruct(sw) - default: - return b.unknown(sw) - } -} - -// ProtobufFromGoNamer finds the protobuf name of a type (and its package, and -// the package path) from its Go name. -type ProtobufFromGoNamer interface { - GoNameToProtoName(name types.Name) types.Name -} - -type ProtobufLocator interface { - ProtoTypeFor(t *types.Type) (*types.Type, error) - GoTypeForName(name types.Name) *types.Type - CastTypeName(name types.Name) string -} - -type protobufLocator struct { - namer ProtobufFromGoNamer - tracker namer.ImportTracker - universe types.Universe - - localGoPackage string -} - -// CastTypeName returns the cast type name of a Go type -// TODO: delegate to a new localgo namer? -func (p protobufLocator) CastTypeName(name types.Name) string { - if name.Package == p.localGoPackage { - return name.Name - } - return name.String() -} - -func (p protobufLocator) GoTypeForName(name types.Name) *types.Type { - if len(name.Package) == 0 { - name.Package = p.localGoPackage - } - return p.universe.Type(name) -} - -// ProtoTypeFor locates a Protobuf type for the provided Go type (if possible). -func (p protobufLocator) ProtoTypeFor(t *types.Type) (*types.Type, error) { - switch { - // we've already converted the type, or it's a map - case t.Kind == types.Protobuf || t.Kind == types.Map: - p.tracker.AddType(t) - return t, nil - } - // it's a fundamental type - if t, ok := isFundamentalProtoType(t); ok { - p.tracker.AddType(t) - return t, nil - } - // it's a message - if t.Kind == types.Struct || isOptionalAlias(t) { - t := &types.Type{ - Name: p.namer.GoNameToProtoName(t.Name), - Kind: types.Protobuf, - - CommentLines: t.CommentLines, - } - p.tracker.AddType(t) - return t, nil - } - return nil, errUnrecognizedType -} - -type bodyGen struct { - locator ProtobufLocator - localPackage types.Name - omitGogo bool - omitFieldTypes map[types.Name]struct{} - - t *types.Type -} - -func (b bodyGen) unknown(sw *generator.SnippetWriter) error { - return fmt.Errorf("not sure how to generate: %#v", b.t) -} - -func (b bodyGen) doAlias(sw *generator.SnippetWriter) error { - if !isOptionalAlias(b.t) { - return nil - } - - var kind string - switch b.t.Underlying.Kind { - case types.Map: - kind = "map" - default: - kind = "slice" - } - optional := &types.Type{ - Name: b.t.Name, - Kind: types.Struct, - - CommentLines: b.t.CommentLines, - SecondClosestCommentLines: b.t.SecondClosestCommentLines, - Members: []types.Member{ - { - Name: "Items", - CommentLines: []string{fmt.Sprintf("items, if empty, will result in an empty %s\n", kind)}, - Type: b.t.Underlying, - }, - }, - } - nested := b - nested.t = optional - return nested.doStruct(sw) -} - -func (b bodyGen) doStruct(sw *generator.SnippetWriter) error { - if len(b.t.Name.Name) == 0 { - return nil - } - if namer.IsPrivateGoName(b.t.Name.Name) { - return nil - } - - var alias *types.Type - var fields []protoField - options := []string{} - allOptions := types.ExtractCommentTags("+", b.t.CommentLines) - for k, v := range allOptions { - switch { - case strings.HasPrefix(k, "protobuf.options."): - key := strings.TrimPrefix(k, "protobuf.options.") - switch key { - case "marshal": - if v[0] == "false" { - if !b.omitGogo { - options = append(options, - "(gogoproto.marshaler) = false", - "(gogoproto.unmarshaler) = false", - "(gogoproto.sizer) = false", - ) - } - } - default: - if !b.omitGogo || !strings.HasPrefix(key, "(gogoproto.") { - if key == "(gogoproto.goproto_stringer)" && v[0] == "false" { - options = append(options, "(gogoproto.stringer) = false") - } - options = append(options, fmt.Sprintf("%s = %s", key, v[0])) - } - } - // protobuf.as allows a type to have the same message contents as another Go type - case k == "protobuf.as": - fields = nil - if alias = b.locator.GoTypeForName(types.Name{Name: v[0]}); alias == nil { - return fmt.Errorf("type %v references alias %q which does not exist", b.t, v[0]) - } - // protobuf.embed instructs the generator to use the named type in this package - // as an embedded message. - case k == "protobuf.embed": - fields = []protoField{ - { - Tag: 1, - Name: v[0], - Type: &types.Type{ - Name: types.Name{ - Name: v[0], - Package: b.localPackage.Package, - Path: b.localPackage.Path, - }, - }, - }, - } - } - } - if alias == nil { - alias = b.t - } - - // If we don't explicitly embed anything, generate fields by traversing fields. - if fields == nil { - memberFields, err := membersToFields(b.locator, alias, b.localPackage, b.omitFieldTypes) - if err != nil { - return fmt.Errorf("type %v cannot be converted to protobuf: %v", b.t, err) - } - fields = memberFields - } - - out := sw.Out() - genComment(out, b.t.CommentLines, "") - sw.Do(`message $.Name.Name$ { -`, b.t) - - if len(options) > 0 { - sort.Strings(options) - for _, s := range options { - fmt.Fprintf(out, " option %s;\n", s) - } - fmt.Fprintln(out) - } - - for i, field := range fields { - genComment(out, field.CommentLines, " ") - fmt.Fprintf(out, " ") - switch { - case field.Map: - case field.Repeated: - fmt.Fprintf(out, "repeated ") - case field.Required: - fmt.Fprintf(out, "required ") - default: - fmt.Fprintf(out, "optional ") - } - sw.Do(`$.Type|local$ $.Name$ = $.Tag$`, field) - if len(field.Extras) > 0 { - extras := []string{} - for k, v := range field.Extras { - if b.omitGogo && strings.HasPrefix(k, "(gogoproto.") { - continue - } - extras = append(extras, fmt.Sprintf("%s = %s", k, v)) - } - sort.Strings(extras) - if len(extras) > 0 { - fmt.Fprintf(out, " [") - fmt.Fprint(out, strings.Join(extras, ", ")) - fmt.Fprintf(out, "]") - } - } - fmt.Fprintf(out, ";\n") - if i != len(fields)-1 { - fmt.Fprintf(out, "\n") - } - } - fmt.Fprintf(out, "}\n\n") - return nil -} - -type protoField struct { - LocalPackage types.Name - - Tag int - Name string - Type *types.Type - Map bool - Repeated bool - Optional bool - Required bool - Nullable bool - Extras map[string]string - - CommentLines []string -} - -var ( - errUnrecognizedType = fmt.Errorf("did not recognize the provided type") -) - -func isFundamentalProtoType(t *types.Type) (*types.Type, bool) { - // TODO: when we enable proto3, also include other fundamental types in the google.protobuf package - // switch { - // case t.Kind == types.Struct && t.Name == types.Name{Package: "time", Name: "Time"}: - // return &types.Type{ - // Kind: types.Protobuf, - // Name: types.Name{Path: "google/protobuf/timestamp.proto", Package: "google.protobuf", Name: "Timestamp"}, - // }, true - // } - switch t.Kind { - case types.Slice: - if t.Elem.Name.Name == "byte" && len(t.Elem.Name.Package) == 0 { - return &types.Type{Name: types.Name{Name: "bytes"}, Kind: types.Protobuf}, true - } - case types.Builtin: - switch t.Name.Name { - case "string", "uint32", "int32", "uint64", "int64", "bool": - return &types.Type{Name: types.Name{Name: t.Name.Name}, Kind: types.Protobuf}, true - case "int": - return &types.Type{Name: types.Name{Name: "int64"}, Kind: types.Protobuf}, true - case "uint": - return &types.Type{Name: types.Name{Name: "uint64"}, Kind: types.Protobuf}, true - case "float64", "float": - return &types.Type{Name: types.Name{Name: "double"}, Kind: types.Protobuf}, true - case "float32": - return &types.Type{Name: types.Name{Name: "float"}, Kind: types.Protobuf}, true - case "uintptr": - return &types.Type{Name: types.Name{Name: "uint64"}, Kind: types.Protobuf}, true - } - // TODO: complex? - } - return t, false -} - -func memberTypeToProtobufField(locator ProtobufLocator, field *protoField, t *types.Type) error { - var err error - switch t.Kind { - case types.Protobuf: - field.Type, err = locator.ProtoTypeFor(t) - case types.Builtin: - field.Type, err = locator.ProtoTypeFor(t) - case types.Map: - valueField := &protoField{} - if err := memberTypeToProtobufField(locator, valueField, t.Elem); err != nil { - return err - } - keyField := &protoField{} - if err := memberTypeToProtobufField(locator, keyField, t.Key); err != nil { - return err - } - // All other protobuf types have kind types.Protobuf, so setting types.Map - // here would be very misleading. - field.Type = &types.Type{ - Kind: types.Protobuf, - Key: keyField.Type, - Elem: valueField.Type, - } - if !strings.HasPrefix(t.Name.Name, "map[") { - field.Extras["(gogoproto.casttype)"] = strconv.Quote(locator.CastTypeName(t.Name)) - } - if k, ok := keyField.Extras["(gogoproto.casttype)"]; ok { - field.Extras["(gogoproto.castkey)"] = k - } - if v, ok := valueField.Extras["(gogoproto.casttype)"]; ok { - field.Extras["(gogoproto.castvalue)"] = v - } - field.Map = true - case types.Pointer: - if err := memberTypeToProtobufField(locator, field, t.Elem); err != nil { - return err - } - field.Nullable = true - case types.Alias: - if isOptionalAlias(t) { - field.Type, err = locator.ProtoTypeFor(t) - field.Nullable = true - } else { - if err := memberTypeToProtobufField(locator, field, t.Underlying); err != nil { - log.Printf("failed to alias: %s %s: err %v", t.Name, t.Underlying.Name, err) - return err - } - // If this is not an alias to a slice, cast to the alias - if !field.Repeated { - if field.Extras == nil { - field.Extras = make(map[string]string) - } - field.Extras["(gogoproto.casttype)"] = strconv.Quote(locator.CastTypeName(t.Name)) - } - } - case types.Slice: - if t.Elem.Name.Name == "byte" && len(t.Elem.Name.Package) == 0 { - field.Type = &types.Type{Name: types.Name{Name: "bytes"}, Kind: types.Protobuf} - return nil - } - if err := memberTypeToProtobufField(locator, field, t.Elem); err != nil { - return err - } - field.Repeated = true - case types.Struct: - if len(t.Name.Name) == 0 { - return errUnrecognizedType - } - field.Type, err = locator.ProtoTypeFor(t) - field.Nullable = false - default: - return errUnrecognizedType - } - return err -} - -// protobufTagToField extracts information from an existing protobuf tag -func protobufTagToField(tag string, field *protoField, m types.Member, t *types.Type, localPackage types.Name) error { - if len(tag) == 0 || tag == "-" { - return nil - } - - // protobuf:"bytes,3,opt,name=Id,customtype=github.com/gogo/protobuf/test.Uuid" - parts := strings.Split(tag, ",") - if len(parts) < 3 { - return fmt.Errorf("member %q of %q malformed 'protobuf' tag, not enough segments\n", m.Name, t.Name) - } - protoTag, err := strconv.Atoi(parts[1]) - if err != nil { - return fmt.Errorf("member %q of %q malformed 'protobuf' tag, field ID is %q which is not an integer: %v\n", m.Name, t.Name, parts[1], err) - } - field.Tag = protoTag - - // In general there is doesn't make sense to parse the protobuf tags to get the type, - // as all auto-generated once will have wire type "bytes", "varint" or "fixed64". - // However, sometimes we explicitly set them to have a custom serialization, e.g.: - // type Time struct { - // time.Time `protobuf:"Timestamp,1,req,name=time"` - // } - // to force the generator to use a given type (that we manually wrote serialization & - // deserialization methods for). - switch parts[0] { - case "varint", "fixed32", "fixed64", "bytes", "group": - default: - var name types.Name - if last := strings.LastIndex(parts[0], "."); last != -1 { - prefix := parts[0][:last] - name = types.Name{ - Name: parts[0][last+1:], - Package: prefix, - Path: strings.Replace(prefix, ".", "/", -1), - } - } else { - name = types.Name{ - Name: parts[0], - Package: localPackage.Package, - Path: localPackage.Path, - } - } - field.Type = &types.Type{ - Name: name, - Kind: types.Protobuf, - } - } - - protoExtra := make(map[string]string) - for i, extra := range parts[3:] { - parts := strings.SplitN(extra, "=", 2) - if len(parts) != 2 { - return fmt.Errorf("member %q of %q malformed 'protobuf' tag, tag %d should be key=value, got %q\n", m.Name, t.Name, i+4, extra) - } - switch parts[0] { - case "name": - protoExtra[parts[0]] = parts[1] - case "casttype", "castkey", "castvalue": - parts[0] = fmt.Sprintf("(gogoproto.%s)", parts[0]) - protoExtra[parts[0]] = strconv.Quote(parts[1]) - } - } - - field.Extras = protoExtra - if name, ok := protoExtra["name"]; ok { - field.Name = name - delete(protoExtra, "name") - } - - return nil -} - -func membersToFields(locator ProtobufLocator, t *types.Type, localPackage types.Name, omitFieldTypes map[types.Name]struct{}) ([]protoField, error) { - fields := []protoField{} - - for _, m := range t.Members { - if namer.IsPrivateGoName(m.Name) { - // skip private fields - continue - } - if _, ok := omitFieldTypes[types.Name{Name: m.Type.Name.Name, Package: m.Type.Name.Package}]; ok { - continue - } - tags := reflect.StructTag(m.Tags) - field := protoField{ - LocalPackage: localPackage, - - Tag: -1, - Extras: make(map[string]string), - } - - protobufTag := tags.Get("protobuf") - if protobufTag == "-" { - continue - } - - if err := protobufTagToField(protobufTag, &field, m, t, localPackage); err != nil { - return nil, err - } - - // extract information from JSON field tag - if tag := tags.Get("json"); len(tag) > 0 { - parts := strings.Split(tag, ",") - if len(field.Name) == 0 && len(parts[0]) != 0 { - field.Name = parts[0] - } - if field.Tag == -1 && field.Name == "-" { - continue - } - } - - if field.Type == nil { - if err := memberTypeToProtobufField(locator, &field, m.Type); err != nil { - return nil, fmt.Errorf("unable to embed type %q as field %q in %q: %v", m.Type, field.Name, t.Name, err) - } - } - if len(field.Name) == 0 { - field.Name = namer.IL(m.Name) - } - - if field.Map && field.Repeated { - // maps cannot be repeated - field.Repeated = false - field.Nullable = true - } - - if !field.Nullable { - field.Extras["(gogoproto.nullable)"] = "false" - } - if (field.Type.Name.Name == "bytes" && field.Type.Name.Package == "") || (field.Repeated && field.Type.Name.Package == "" && namer.IsPrivateGoName(field.Type.Name.Name)) { - delete(field.Extras, "(gogoproto.nullable)") - } - if field.Name != m.Name { - field.Extras["(gogoproto.customname)"] = strconv.Quote(m.Name) - } - field.CommentLines = m.CommentLines - fields = append(fields, field) - } - - // assign tags - highest := 0 - byTag := make(map[int]*protoField) - // fields are in Go struct order, which we preserve - for i := range fields { - field := &fields[i] - tag := field.Tag - if tag != -1 { - if existing, ok := byTag[tag]; ok { - return nil, fmt.Errorf("field %q and %q both have tag %d", field.Name, existing.Name, tag) - } - byTag[tag] = field - } - if tag > highest { - highest = tag - } - } - // starting from the highest observed tag, assign new field tags - for i := range fields { - field := &fields[i] - if field.Tag != -1 { - continue - } - highest++ - field.Tag = highest - byTag[field.Tag] = field - } - return fields, nil -} - -func genComment(out io.Writer, lines []string, indent string) { - for { - l := len(lines) - if l == 0 || len(lines[l-1]) != 0 { - break - } - lines = lines[:l-1] - } - for _, c := range lines { - if len(c) == 0 { - fmt.Fprintf(out, "%s//\n", indent) // avoid trailing whitespace - continue - } - fmt.Fprintf(out, "%s// %s\n", indent, c) - } -} - -func formatProtoFile(source []byte) ([]byte, error) { - // TODO; Is there any protobuf formatter? - return source, nil -} - -func assembleProtoFile(w io.Writer, f *generator.File) { - w.Write(f.Header) - - fmt.Fprint(w, "syntax = \"proto2\";\n\n") - - if len(f.PackageName) > 0 { - fmt.Fprintf(w, "package %s;\n\n", f.PackageName) - } - - if len(f.Imports) > 0 { - imports := []string{} - for i := range f.Imports { - imports = append(imports, i) - } - sort.Strings(imports) - for _, s := range imports { - fmt.Fprintf(w, "import %q;\n", s) - } - fmt.Fprint(w, "\n") - } - - if f.Vars.Len() > 0 { - fmt.Fprintf(w, "%s\n", f.Vars.String()) - } - - w.Write(f.Body.Bytes()) -} - -func NewProtoFile() *generator.DefaultFileType { - return &generator.DefaultFileType{ - Format: formatProtoFile, - Assemble: assembleProtoFile, - } -} diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/import_tracker.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/import_tracker.go deleted file mode 100644 index 08a991b1..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/import_tracker.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package protobuf - -import ( - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -type ImportTracker struct { - namer.DefaultImportTracker -} - -func NewImportTracker(local types.Name, typesToAdd ...*types.Type) *ImportTracker { - tracker := namer.NewDefaultImportTracker(local) - tracker.IsInvalidType = func(t *types.Type) bool { return t.Kind != types.Protobuf } - tracker.LocalName = func(name types.Name) string { return name.Package } - tracker.PrintImport = func(path, name string) string { return path } - - tracker.AddTypes(typesToAdd...) - return &ImportTracker{ - DefaultImportTracker: tracker, - } -} - -// AddNullable ensures that support for the nullable Gogo-protobuf extension is added. -func (tracker *ImportTracker) AddNullable() { - tracker.AddType(&types.Type{ - Kind: types.Protobuf, - Name: types.Name{ - Name: "nullable", - Package: "gogoproto", - Path: "github.com/gogo/protobuf/gogoproto/gogo.proto", - }, - }) -} diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/namer.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/namer.go deleted file mode 100644 index e3b21c67..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/namer.go +++ /dev/null @@ -1,208 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package protobuf - -import ( - "fmt" - "reflect" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -type localNamer struct { - localPackage types.Name -} - -func (n localNamer) Name(t *types.Type) string { - if t.Key != nil && t.Elem != nil { - return fmt.Sprintf("map<%s, %s>", n.Name(t.Key), n.Name(t.Elem)) - } - if len(n.localPackage.Package) != 0 && n.localPackage.Package == t.Name.Package { - return t.Name.Name - } - return t.Name.String() -} - -type protobufNamer struct { - packages []*protobufPackage - packagesByPath map[string]*protobufPackage -} - -func NewProtobufNamer() *protobufNamer { - return &protobufNamer{ - packagesByPath: make(map[string]*protobufPackage), - } -} - -func (n *protobufNamer) Name(t *types.Type) string { - if t.Kind == types.Map { - return fmt.Sprintf("map<%s, %s>", n.Name(t.Key), n.Name(t.Elem)) - } - return t.Name.String() -} - -func (n *protobufNamer) List() []generator.Package { - packages := make([]generator.Package, 0, len(n.packages)) - for i := range n.packages { - packages = append(packages, n.packages[i]) - } - return packages -} - -func (n *protobufNamer) Add(p *protobufPackage) { - if _, ok := n.packagesByPath[p.PackagePath]; !ok { - n.packagesByPath[p.PackagePath] = p - n.packages = append(n.packages, p) - } -} - -func (n *protobufNamer) GoNameToProtoName(name types.Name) types.Name { - if p, ok := n.packagesByPath[name.Package]; ok { - return types.Name{ - Name: name.Name, - Package: p.PackageName, - Path: p.ImportPath(), - } - } - for _, p := range n.packages { - if _, ok := p.FilterTypes[name]; ok { - return types.Name{ - Name: name.Name, - Package: p.PackageName, - Path: p.ImportPath(), - } - } - } - return types.Name{Name: name.Name} -} - -func protoSafePackage(name string) string { - pkg := strings.Replace(name, "/", ".", -1) - return strings.Replace(pkg, "-", "_", -1) -} - -type typeNameSet map[types.Name]*protobufPackage - -// assignGoTypeToProtoPackage looks for Go and Protobuf types that are referenced by a type in -// a package. It will not recurse into protobuf types. -func assignGoTypeToProtoPackage(p *protobufPackage, t *types.Type, local, global typeNameSet, optional map[types.Name]struct{}) { - newT, isProto := isFundamentalProtoType(t) - if isProto { - t = newT - } - if otherP, ok := global[t.Name]; ok { - if _, ok := local[t.Name]; !ok { - p.Imports.AddType(&types.Type{ - Kind: types.Protobuf, - Name: otherP.ProtoTypeName(), - }) - } - return - } - if t.Name.Package == p.PackagePath { - // Associate types only to their own package - global[t.Name] = p - } - if _, ok := local[t.Name]; ok { - return - } - // don't recurse into existing proto types - if isProto { - p.Imports.AddType(t) - return - } - - local[t.Name] = p - for _, m := range t.Members { - if namer.IsPrivateGoName(m.Name) { - continue - } - field := &protoField{} - tag := reflect.StructTag(m.Tags).Get("protobuf") - if tag == "-" { - continue - } - if err := protobufTagToField(tag, field, m, t, p.ProtoTypeName()); err == nil && field.Type != nil { - assignGoTypeToProtoPackage(p, field.Type, local, global, optional) - continue - } - assignGoTypeToProtoPackage(p, m.Type, local, global, optional) - } - // TODO: should methods be walked? - if t.Elem != nil { - assignGoTypeToProtoPackage(p, t.Elem, local, global, optional) - } - if t.Key != nil { - assignGoTypeToProtoPackage(p, t.Key, local, global, optional) - } - if t.Underlying != nil { - if t.Kind == types.Alias && isOptionalAlias(t) { - optional[t.Name] = struct{}{} - } - assignGoTypeToProtoPackage(p, t.Underlying, local, global, optional) - } -} - -// isTypeApplicableToProtobuf checks to see if a type is relevant for protobuf processing. -// Currently, it filters out functions and private types. -func isTypeApplicableToProtobuf(t *types.Type) bool { - // skip functions -- we don't care about them for protobuf - if t.Kind == types.Func || (t.Kind == types.DeclarationOf && t.Underlying.Kind == types.Func) { - return false - } - // skip private types - if namer.IsPrivateGoName(t.Name.Name) { - return false - } - - return true -} - -func (n *protobufNamer) AssignTypesToPackages(c *generator.Context) error { - global := make(typeNameSet) - for _, p := range n.packages { - local := make(typeNameSet) - optional := make(map[types.Name]struct{}) - p.Imports = NewImportTracker(p.ProtoTypeName()) - for _, t := range c.Order { - if t.Name.Package != p.PackagePath { - continue - } - if !isTypeApplicableToProtobuf(t) { - // skip types that we don't care about, like functions - continue - } - assignGoTypeToProtoPackage(p, t, local, global, optional) - } - p.FilterTypes = make(map[types.Name]struct{}) - p.LocalNames = make(map[string]struct{}) - p.OptionalTypeNames = make(map[string]struct{}) - for k, v := range local { - if v == p { - p.FilterTypes[k] = struct{}{} - p.LocalNames[k.Name] = struct{}{} - if _, ok := optional[k]; ok { - p.OptionalTypeNames[k.Name] = struct{}{} - } - } - } - } - return nil -} diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/package.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/package.go deleted file mode 100644 index bed4c3e3..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/package.go +++ /dev/null @@ -1,215 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package protobuf - -import ( - "fmt" - "go/ast" - "log" - "os" - "path/filepath" - "reflect" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/types" -) - -func newProtobufPackage(packagePath, packageName string, generateAll bool, omitFieldTypes map[types.Name]struct{}) *protobufPackage { - pkg := &protobufPackage{ - DefaultPackage: generator.DefaultPackage{ - // The protobuf package name (foo.bar.baz) - PackageName: packageName, - // A path segment relative to the GOPATH root (foo/bar/baz) - PackagePath: packagePath, - HeaderText: []byte( - ` -// This file was autogenerated by go-to-protobuf. Do not edit it manually! - -`), - PackageDocumentation: []byte(fmt.Sprintf( - `// Package %s is an autogenerated protobuf IDL. -`, packageName)), - }, - GenerateAll: generateAll, - OmitFieldTypes: omitFieldTypes, - } - pkg.FilterFunc = pkg.filterFunc - pkg.GeneratorFunc = pkg.generatorFunc - return pkg -} - -// protobufPackage contains the protobuf implementation of Package. -type protobufPackage struct { - generator.DefaultPackage - - // If true, this package has been vendored into our source tree and thus can - // only be generated by changing the vendor tree. - Vendored bool - - // If true, generate protobuf serializations for all public types. - // If false, only generate protobuf serializations for structs that - // request serialization. - GenerateAll bool - - // A list of types to filter to; if not specified all types will be included. - FilterTypes map[types.Name]struct{} - - // If true, omit any gogoprotobuf extensions not defined as types. - OmitGogo bool - - // A list of field types that will be excluded from the output struct - OmitFieldTypes map[types.Name]struct{} - - // A list of names that this package exports - LocalNames map[string]struct{} - - // A list of type names in this package that will need marshaller rewriting - // to remove synthetic protobuf fields. - OptionalTypeNames map[string]struct{} - - // A list of struct tags to generate onto named struct fields - StructTags map[string]map[string]string - - // An import tracker for this package - Imports *ImportTracker -} - -func (p *protobufPackage) Clean(outputBase string) error { - for _, s := range []string{p.ImportPath(), p.OutputPath()} { - if err := os.Remove(filepath.Join(outputBase, s)); err != nil && !os.IsNotExist(err) { - return err - } - } - return nil -} - -func (p *protobufPackage) ProtoTypeName() types.Name { - return types.Name{ - Name: p.Path(), // the go path "foo/bar/baz" - Package: p.Name(), // the protobuf package "foo.bar.baz" - Path: p.ImportPath(), // the path of the import to get the proto - } -} - -func (p *protobufPackage) filterFunc(c *generator.Context, t *types.Type) bool { - switch t.Kind { - case types.Func, types.Chan: - return false - case types.Struct: - if t.Name.Name == "struct{}" { - return false - } - case types.Builtin: - return false - case types.Alias: - if !isOptionalAlias(t) { - return false - } - case types.Slice, types.Array, types.Map: - return false - case types.Pointer: - return false - } - if _, ok := isFundamentalProtoType(t); ok { - return false - } - _, ok := p.FilterTypes[t.Name] - return ok -} - -func (p *protobufPackage) HasGoType(name string) bool { - _, ok := p.LocalNames[name] - return ok -} - -func (p *protobufPackage) OptionalTypeName(name string) bool { - _, ok := p.OptionalTypeNames[name] - return ok -} - -func (p *protobufPackage) ExtractGeneratedType(t *ast.TypeSpec) bool { - if !p.HasGoType(t.Name.Name) { - return false - } - - switch s := t.Type.(type) { - case *ast.StructType: - for i, f := range s.Fields.List { - if len(f.Tag.Value) == 0 { - continue - } - tag := strings.Trim(f.Tag.Value, "`") - protobufTag := reflect.StructTag(tag).Get("protobuf") - if len(protobufTag) == 0 { - continue - } - if len(f.Names) > 1 { - log.Printf("WARNING: struct %s field %d %s: defined multiple names but single protobuf tag", t.Name.Name, i, f.Names[0].Name) - // TODO hard error? - } - if p.StructTags == nil { - p.StructTags = make(map[string]map[string]string) - } - m := p.StructTags[t.Name.Name] - if m == nil { - m = make(map[string]string) - p.StructTags[t.Name.Name] = m - } - m[f.Names[0].Name] = tag - } - default: - log.Printf("WARNING: unexpected Go AST type definition: %#v", t) - } - - return true -} - -func (p *protobufPackage) generatorFunc(c *generator.Context) []generator.Generator { - generators := []generator.Generator{} - - p.Imports.AddNullable() - - generators = append(generators, &genProtoIDL{ - DefaultGen: generator.DefaultGen{ - OptionalName: "generated", - }, - localPackage: types.Name{Package: p.PackageName, Path: p.PackagePath}, - localGoPackage: types.Name{Package: p.PackagePath, Name: p.GoPackageName()}, - imports: p.Imports, - generateAll: p.GenerateAll, - omitGogo: p.OmitGogo, - omitFieldTypes: p.OmitFieldTypes, - }) - return generators -} - -func (p *protobufPackage) GoPackageName() string { - return filepath.Base(p.PackagePath) -} - -func (p *protobufPackage) ImportPath() string { - return filepath.Join(p.PackagePath, "generated.proto") -} - -func (p *protobufPackage) OutputPath() string { - return filepath.Join(p.PackagePath, "generated.pb.go") -} - -var ( - _ = generator.Package(&protobufPackage{}) -) diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/parser.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/parser.go deleted file mode 100644 index c4cf66e7..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/parser.go +++ /dev/null @@ -1,463 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package protobuf - -import ( - "bytes" - "errors" - "fmt" - "go/ast" - "go/format" - "go/parser" - "go/printer" - "go/token" - "os" - "reflect" - "strings" - - customreflect "k8s.io/code-generator/third_party/forked/golang/reflect" -) - -func rewriteFile(name string, header []byte, rewriteFn func(*token.FileSet, *ast.File) error) error { - fset := token.NewFileSet() - src, err := os.ReadFile(name) - if err != nil { - return err - } - file, err := parser.ParseFile(fset, name, src, parser.DeclarationErrors|parser.ParseComments) - if err != nil { - return err - } - - if err := rewriteFn(fset, file); err != nil { - return err - } - - b := &bytes.Buffer{} - b.Write(header) - if err := printer.Fprint(b, fset, file); err != nil { - return err - } - - body, err := format.Source(b.Bytes()) - if err != nil { - return err - } - - f, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC, 0644) - if err != nil { - return err - } - defer f.Close() - if _, err := f.Write(body); err != nil { - return err - } - return f.Close() -} - -// ExtractFunc extracts information from the provided TypeSpec and returns true if the type should be -// removed from the destination file. -type ExtractFunc func(*ast.TypeSpec) bool - -// OptionalFunc returns true if the provided local name is a type that has protobuf.nullable=true -// and should have its marshal functions adjusted to remove the 'Items' accessor. -type OptionalFunc func(name string) bool - -func RewriteGeneratedGogoProtobufFile(name string, extractFn ExtractFunc, optionalFn OptionalFunc, header []byte) error { - return rewriteFile(name, header, func(fset *token.FileSet, file *ast.File) error { - cmap := ast.NewCommentMap(fset, file, file.Comments) - - // transform methods that point to optional maps or slices - for _, d := range file.Decls { - rewriteOptionalMethods(d, optionalFn) - } - - // remove types that are already declared - decls := []ast.Decl{} - for _, d := range file.Decls { - if dropExistingTypeDeclarations(d, extractFn) { - continue - } - if dropEmptyImportDeclarations(d) { - continue - } - decls = append(decls, d) - } - file.Decls = decls - - // remove unmapped comments - file.Comments = cmap.Filter(file).Comments() - return nil - }) -} - -// rewriteOptionalMethods makes specific mutations to marshaller methods that belong to types identified -// as being "optional" (they may be nil on the wire). This allows protobuf to serialize a map or slice and -// properly discriminate between empty and nil (which is not possible in protobuf). -// TODO: move into upstream gogo-protobuf once https://github.com/gogo/protobuf/issues/181 -// has agreement -func rewriteOptionalMethods(decl ast.Decl, isOptional OptionalFunc) { - switch t := decl.(type) { - case *ast.FuncDecl: - ident, ptr, ok := receiver(t) - if !ok { - return - } - - // correct initialization of the form `m.Field = &OptionalType{}` to - // `m.Field = OptionalType{}` - if t.Name.Name == "Unmarshal" { - ast.Walk(optionalAssignmentVisitor{fn: isOptional}, t.Body) - } - - if !isOptional(ident.Name) { - return - } - - switch t.Name.Name { - case "Unmarshal": - ast.Walk(&optionalItemsVisitor{}, t.Body) - case "MarshalTo", "Size", "String", "MarshalToSizedBuffer": - ast.Walk(&optionalItemsVisitor{}, t.Body) - fallthrough - case "Marshal": - // if the method has a pointer receiver, set it back to a normal receiver - if ptr { - t.Recv.List[0].Type = ident - } - } - } -} - -type optionalAssignmentVisitor struct { - fn OptionalFunc -} - -// Visit walks the provided node, transforming field initializations of the form -// m.Field = &OptionalType{} -> m.Field = OptionalType{} -func (v optionalAssignmentVisitor) Visit(n ast.Node) ast.Visitor { - switch t := n.(type) { - case *ast.AssignStmt: - if len(t.Lhs) == 1 && len(t.Rhs) == 1 { - if !isFieldSelector(t.Lhs[0], "m", "") { - return nil - } - unary, ok := t.Rhs[0].(*ast.UnaryExpr) - if !ok || unary.Op != token.AND { - return nil - } - composite, ok := unary.X.(*ast.CompositeLit) - if !ok || composite.Type == nil || len(composite.Elts) != 0 { - return nil - } - if ident, ok := composite.Type.(*ast.Ident); ok && v.fn(ident.Name) { - t.Rhs[0] = composite - } - } - return nil - } - return v -} - -type optionalItemsVisitor struct{} - -// Visit walks the provided node, looking for specific patterns to transform that match -// the effective outcome of turning struct{ map[x]y || []x } into map[x]y or []x. -func (v *optionalItemsVisitor) Visit(n ast.Node) ast.Visitor { - switch t := n.(type) { - case *ast.RangeStmt: - if isFieldSelector(t.X, "m", "Items") { - t.X = &ast.Ident{Name: "m"} - } - case *ast.AssignStmt: - if len(t.Lhs) == 1 && len(t.Rhs) == 1 { - switch lhs := t.Lhs[0].(type) { - case *ast.IndexExpr: - if isFieldSelector(lhs.X, "m", "Items") { - lhs.X = &ast.StarExpr{X: &ast.Ident{Name: "m"}} - } - default: - if isFieldSelector(t.Lhs[0], "m", "Items") { - t.Lhs[0] = &ast.StarExpr{X: &ast.Ident{Name: "m"}} - } - } - switch rhs := t.Rhs[0].(type) { - case *ast.CallExpr: - if ident, ok := rhs.Fun.(*ast.Ident); ok && ident.Name == "append" { - ast.Walk(v, rhs) - if len(rhs.Args) > 0 { - switch arg := rhs.Args[0].(type) { - case *ast.Ident: - if arg.Name == "m" { - rhs.Args[0] = &ast.StarExpr{X: &ast.Ident{Name: "m"}} - } - } - } - return nil - } - } - } - case *ast.IfStmt: - switch cond := t.Cond.(type) { - case *ast.BinaryExpr: - if cond.Op == token.EQL { - if isFieldSelector(cond.X, "m", "Items") && isIdent(cond.Y, "nil") { - cond.X = &ast.StarExpr{X: &ast.Ident{Name: "m"}} - } - } - } - if t.Init != nil { - // Find form: - // if err := m[len(m.Items)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { - // return err - // } - switch s := t.Init.(type) { - case *ast.AssignStmt: - if call, ok := s.Rhs[0].(*ast.CallExpr); ok { - if sel, ok := call.Fun.(*ast.SelectorExpr); ok { - if x, ok := sel.X.(*ast.IndexExpr); ok { - // m[] -> (*m)[] - if sel2, ok := x.X.(*ast.SelectorExpr); ok { - if ident, ok := sel2.X.(*ast.Ident); ok && ident.Name == "m" { - x.X = &ast.StarExpr{X: &ast.Ident{Name: "m"}} - } - } - // len(m.Items) -> len(*m) - if bin, ok := x.Index.(*ast.BinaryExpr); ok { - if call2, ok := bin.X.(*ast.CallExpr); ok && len(call2.Args) == 1 { - if isFieldSelector(call2.Args[0], "m", "Items") { - call2.Args[0] = &ast.StarExpr{X: &ast.Ident{Name: "m"}} - } - } - } - } - } - } - } - } - case *ast.IndexExpr: - if isFieldSelector(t.X, "m", "Items") { - t.X = &ast.Ident{Name: "m"} - return nil - } - case *ast.CallExpr: - changed := false - for i := range t.Args { - if isFieldSelector(t.Args[i], "m", "Items") { - t.Args[i] = &ast.Ident{Name: "m"} - changed = true - } - } - if changed { - return nil - } - } - return v -} - -func isFieldSelector(n ast.Expr, name, field string) bool { - s, ok := n.(*ast.SelectorExpr) - if !ok || s.Sel == nil || (field != "" && s.Sel.Name != field) { - return false - } - return isIdent(s.X, name) -} - -func isIdent(n ast.Expr, value string) bool { - ident, ok := n.(*ast.Ident) - return ok && ident.Name == value -} - -func receiver(f *ast.FuncDecl) (ident *ast.Ident, pointer bool, ok bool) { - if f.Recv == nil || len(f.Recv.List) != 1 { - return nil, false, false - } - switch t := f.Recv.List[0].Type.(type) { - case *ast.StarExpr: - identity, ok := t.X.(*ast.Ident) - if !ok { - return nil, false, false - } - return identity, true, true - case *ast.Ident: - return t, false, true - } - return nil, false, false -} - -// dropExistingTypeDeclarations removes any type declaration for which extractFn returns true. The function -// returns true if the entire declaration should be dropped. -func dropExistingTypeDeclarations(decl ast.Decl, extractFn ExtractFunc) bool { - switch t := decl.(type) { - case *ast.GenDecl: - if t.Tok != token.TYPE { - return false - } - specs := []ast.Spec{} - for _, s := range t.Specs { - switch spec := s.(type) { - case *ast.TypeSpec: - if extractFn(spec) { - continue - } - specs = append(specs, spec) - } - } - if len(specs) == 0 { - return true - } - t.Specs = specs - } - return false -} - -// dropEmptyImportDeclarations strips any generated but no-op imports from the generated code -// to prevent generation from being able to define side-effects. The function returns true -// if the entire declaration should be dropped. -func dropEmptyImportDeclarations(decl ast.Decl) bool { - switch t := decl.(type) { - case *ast.GenDecl: - if t.Tok != token.IMPORT { - return false - } - specs := []ast.Spec{} - for _, s := range t.Specs { - switch spec := s.(type) { - case *ast.ImportSpec: - if spec.Name != nil && spec.Name.Name == "_" { - continue - } - specs = append(specs, spec) - } - } - if len(specs) == 0 { - return true - } - t.Specs = specs - } - return false -} - -func RewriteTypesWithProtobufStructTags(name string, structTags map[string]map[string]string) error { - return rewriteFile(name, []byte{}, func(fset *token.FileSet, file *ast.File) error { - allErrs := []error{} - - // set any new struct tags - for _, d := range file.Decls { - if errs := updateStructTags(d, structTags, []string{"protobuf"}); len(errs) > 0 { - allErrs = append(allErrs, errs...) - } - } - - if len(allErrs) > 0 { - var s string - for _, err := range allErrs { - s += err.Error() + "\n" - } - return errors.New(s) - } - return nil - }) -} - -func getFieldName(expr ast.Expr, structname string) (name string, err error) { - for { - switch t := expr.(type) { - case *ast.Ident: - return t.Name, nil - case *ast.SelectorExpr: - return t.Sel.Name, nil - case *ast.StarExpr: - expr = t.X - default: - return "", fmt.Errorf("unable to get name for tag from struct %q, field %#v", structname, t) - } - } -} - -func updateStructTags(decl ast.Decl, structTags map[string]map[string]string, toCopy []string) []error { - var errs []error - t, ok := decl.(*ast.GenDecl) - if !ok { - return nil - } - if t.Tok != token.TYPE { - return nil - } - - for _, s := range t.Specs { - spec, ok := s.(*ast.TypeSpec) - if !ok { - continue - } - typeName := spec.Name.Name - fieldTags, ok := structTags[typeName] - if !ok { - continue - } - st, ok := spec.Type.(*ast.StructType) - if !ok { - continue - } - - for i := range st.Fields.List { - f := st.Fields.List[i] - var name string - var err error - if len(f.Names) == 0 { - name, err = getFieldName(f.Type, spec.Name.Name) - if err != nil { - errs = append(errs, err) - continue - } - } else { - name = f.Names[0].Name - } - value, ok := fieldTags[name] - if !ok { - continue - } - var tags customreflect.StructTags - if f.Tag != nil { - oldTags, err := customreflect.ParseStructTags(strings.Trim(f.Tag.Value, "`")) - if err != nil { - errs = append(errs, fmt.Errorf("unable to read struct tag from struct %q, field %q: %v", spec.Name.Name, name, err)) - continue - } - tags = oldTags - } - for _, name := range toCopy { - // don't overwrite existing tags - if tags.Has(name) { - continue - } - // append new tags - if v := reflect.StructTag(value).Get(name); len(v) > 0 { - tags = append(tags, customreflect.StructTag{Name: name, Value: v}) - } - } - if len(tags) == 0 { - continue - } - if f.Tag == nil { - f.Tag = &ast.BasicLit{} - } - f.Tag.Value = tags.String() - } - } - return errs -} diff --git a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/tags.go b/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/tags.go deleted file mode 100644 index 6cfa3788..00000000 --- a/vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/tags.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package protobuf - -import ( - "k8s.io/gengo/types" - "k8s.io/klog/v2" -) - -// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if -// it exists, the value is boolean. If the tag did not exist, it returns -// false. -func extractBoolTagOrDie(key string, lines []string) bool { - val, err := types.ExtractSingleBoolCommentTag("+", key, false, lines) - if err != nil { - klog.Fatal(err) - } - return val -} diff --git a/vendor/k8s.io/code-generator/cmd/import-boss/.gitignore b/vendor/k8s.io/code-generator/cmd/import-boss/.gitignore deleted file mode 100644 index a5c47b66..00000000 --- a/vendor/k8s.io/code-generator/cmd/import-boss/.gitignore +++ /dev/null @@ -1 +0,0 @@ -import-boss diff --git a/vendor/k8s.io/code-generator/cmd/import-boss/README.md b/vendor/k8s.io/code-generator/cmd/import-boss/README.md deleted file mode 100644 index 88dc010e..00000000 --- a/vendor/k8s.io/code-generator/cmd/import-boss/README.md +++ /dev/null @@ -1,97 +0,0 @@ -## Purpose - -- `import-boss` enforces import restrictions against all pull requests submitted to the [k/k](https://github.com/kubernetes/kubernetes) repository. There are a number of `.import-restrictions` files that in the [k/k](https://github.com/kubernetes/kubernetes) repository, all of which are defined in `YAML` (or `JSON`) format. - -## How does it work? - -- When a directory is verified, `import-boss` looks for a file called `.import-restrictions`. If this file is not found, `import-boss` will go up to the parent directory until it finds this `.import-restrictions` file. - -- Adding `.import-restrictions` files does not add them to CI runs. They need to be explicitly added to `hack/verify-import-boss.sh`. Once an `.import-restrictions` file is added, all of the sub-packages of this file's directory are added as well. - -### What are Rules? - -- If an `.import-restrictions` file is found, then all imports of the package are checked against each `rule` in the file. A `rule` consists of three parts: - - A `SelectorRegexp`, to select the import paths that the rule applies to. - - A list of `AllowedPrefixes` - - A list of `ForbiddenPrefixes` - -- An import is allowed if it matches at least one allowed prefix and does not match any forbidden prefixes. An example `.import-restrictions` file looks like this: - -```json -{ - "Rules": [ - { - "SelectorRegexp": "k8s[.]io", - "AllowedPrefixes": [ - "k8s.io/gengo/examples", - "k8s.io/kubernetes/third_party" - ], - "ForbiddenPrefixes": [ - "k8s.io/kubernetes/pkg/third_party/deprecated" - ] - }, - { - "SelectorRegexp": "^unsafe$", - "AllowedPrefixes": [ - ], - "ForbiddenPrefixes": [ - "" - ] - } - ] -} -``` -- Take note of `"SelectorRegexp": "k8s[.]io"` in the first block. This specifies that we are applying these rules to the `"k8s.io"` import path. -- The second block explicitly matches the "unsafe" package, and forbids it ("" is a prefix of everything). - -### What are Inverse Rules? - -- In contrast to non-inverse rules, which are defined in importing packages, inverse rules are defined in imported packages. - -- Inverse rules allow for fine-grained import restrictions for "private packages" where we don't want to spread use inside of [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes). - -- If an `.import-restrictions` file is found, then all imports of the package are checked against each `inverse rule` in the file. This check will continue, climbing up the directory tree, until a match is found and accepted. - -- Inverse rules also have a boolean `transitive` option. When this option is true, the import rule is also applied to `transitive` imports. - - `transitive` imports are dependencies not directly depended on by the code, but are needed to run the application. Use this option if you want to apply restrictions to those indirect dependencies. - -```yaml -rules: - - selectorRegexp: k8s[.]io - allowedPrefixes: - - k8s.io/gengo/examples - - k8s.io/kubernetes/third_party - forbiddenPrefixes: - - k8s.io/kubernetes/pkg/third_party/deprecated - - selectorRegexp: ^unsafe$ - forbiddenPrefixes: - - "" -inverseRules: - - selectorRegexp: k8s[.]io - allowedPrefixes: - - k8s.io/same-repo - - k8s.io/kubernetes/pkg/legacy - forbiddenPrefixes: - - k8s.io/kubernetes/pkg/legacy/subpkg - - selectorRegexp: k8s[.]io - transitive: true - forbiddenPrefixes: - - k8s.io/kubernetes/cmd/kubelet - - k8s.io/kubernetes/cmd/kubectl -``` - -## How do I run import-boss within the k/k repo? - -- In order to include _test.go files, make sure to pass in the `include-test-files` flag: - ```sh - hack/verify-import-boss.sh --include-test-files=true - ``` - -- To include other directories, pass in a directory or directories using the `input-dirs` flag: - ```sh - hack/verify-import-boss.sh --input-dirs="k8s.io/kubernetes/test/e2e/framework/..." - ``` - -## Reference - -- [import-boss](https://github.com/kubernetes/gengo/tree/master/examples/import-boss) \ No newline at end of file diff --git a/vendor/k8s.io/code-generator/cmd/import-boss/main.go b/vendor/k8s.io/code-generator/cmd/import-boss/main.go deleted file mode 100644 index 34373c54..00000000 --- a/vendor/k8s.io/code-generator/cmd/import-boss/main.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -// import-boss enforces import restrictions in a given repository. -package main - -import ( - "os" - - "github.com/spf13/pflag" - "k8s.io/gengo/args" - "k8s.io/gengo/examples/import-boss/generators" - - "k8s.io/klog/v2" -) - -func main() { - klog.InitFlags(nil) - arguments := args.Default() - - pflag.CommandLine.BoolVar(&arguments.IncludeTestFiles, "include-test-files", false, "If true, include *_test.go files.") - - if err := arguments.Execute( - generators.NameSystems(), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Errorf("Error: %v", err) - os.Exit(1) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/args/args.go b/vendor/k8s.io/code-generator/cmd/informer-gen/args/args.go deleted file mode 100644 index ffd073a8..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/args/args.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "fmt" - "path" - - "github.com/spf13/pflag" - codegenutil "k8s.io/code-generator/pkg/util" - "k8s.io/gengo/args" -) - -// CustomArgs is used by the gengo framework to pass args specific to this generator. -type CustomArgs struct { - VersionedClientSetPackage string - InternalClientSetPackage string - ListersPackage string - SingleDirectory bool - - // PluralExceptions define a list of pluralizer exceptions in Type:PluralType format. - // The default list is "Endpoints:Endpoints" - PluralExceptions []string -} - -// NewDefaults returns default arguments for the generator. -func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { - genericArgs := args.Default().WithoutDefaultFlagParsing() - customArgs := &CustomArgs{ - SingleDirectory: false, - PluralExceptions: []string{"Endpoints:Endpoints"}, - } - genericArgs.CustomArgs = customArgs - - if pkg := codegenutil.CurrentPackage(); len(pkg) != 0 { - genericArgs.OutputPackagePath = path.Join(pkg, "pkg/client/informers") - customArgs.VersionedClientSetPackage = path.Join(pkg, "pkg/client/clientset/versioned") - customArgs.InternalClientSetPackage = path.Join(pkg, "pkg/client/clientset/internalversion") - customArgs.ListersPackage = path.Join(pkg, "pkg/client/listers") - } - - return genericArgs, customArgs -} - -// AddFlags add the generator flags to the flag set. -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { - fs.StringVar(&ca.InternalClientSetPackage, "internal-clientset-package", ca.InternalClientSetPackage, "the full package name for the internal clientset to use") - fs.StringVar(&ca.VersionedClientSetPackage, "versioned-clientset-package", ca.VersionedClientSetPackage, "the full package name for the versioned clientset to use") - fs.StringVar(&ca.ListersPackage, "listers-package", ca.ListersPackage, "the full package name for the listers to use") - fs.BoolVar(&ca.SingleDirectory, "single-directory", ca.SingleDirectory, "if true, omit the intermediate \"internalversion\" and \"externalversions\" subdirectories") - fs.StringSliceVar(&ca.PluralExceptions, "plural-exceptions", ca.PluralExceptions, "list of comma separated plural exception definitions in Type:PluralizedType format") -} - -// Validate checks the given arguments. -func Validate(genericArgs *args.GeneratorArgs) error { - customArgs := genericArgs.CustomArgs.(*CustomArgs) - - if len(genericArgs.OutputPackagePath) == 0 { - return fmt.Errorf("output package cannot be empty") - } - if len(customArgs.VersionedClientSetPackage) == 0 { - return fmt.Errorf("versioned clientset package cannot be empty") - } - if len(customArgs.ListersPackage) == 0 { - return fmt.Errorf("listers package cannot be empty") - } - - return nil -} diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go deleted file mode 100644 index 48753939..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go +++ /dev/null @@ -1,340 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "path" - - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/klog/v2" -) - -// factoryGenerator produces a file of listers for a given GroupVersion and -// type. -type factoryGenerator struct { - generator.DefaultGen - outputPackage string - imports namer.ImportTracker - groupVersions map[string]clientgentypes.GroupVersions - gvGoNames map[string]string - clientSetPackage string - internalInterfacesPackage string - filtered bool -} - -var _ generator.Generator = &factoryGenerator{} - -func (g *factoryGenerator) Filter(c *generator.Context, t *types.Type) bool { - if !g.filtered { - g.filtered = true - return true - } - return false -} - -func (g *factoryGenerator) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *factoryGenerator) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - return -} - -func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "{{", "}}") - - klog.V(5).Infof("processing type %v", t) - - gvInterfaces := make(map[string]*types.Type) - gvNewFuncs := make(map[string]*types.Type) - for groupPkgName := range g.groupVersions { - gvInterfaces[groupPkgName] = c.Universe.Type(types.Name{Package: path.Join(g.outputPackage, groupPkgName), Name: "Interface"}) - gvNewFuncs[groupPkgName] = c.Universe.Function(types.Name{Package: path.Join(g.outputPackage, groupPkgName), Name: "New"}) - } - m := map[string]interface{}{ - "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), - "cacheTransformFunc": c.Universe.Type(cacheTransformFunc), - "groupVersions": g.groupVersions, - "gvInterfaces": gvInterfaces, - "gvNewFuncs": gvNewFuncs, - "gvGoNames": g.gvGoNames, - "interfacesNewInformerFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "NewInformerFunc"}), - "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), - "informerFactoryInterface": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), - "clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), - "reflectType": c.Universe.Type(reflectType), - "runtimeObject": c.Universe.Type(runtimeObject), - "schemaGroupVersionResource": c.Universe.Type(schemaGroupVersionResource), - "syncMutex": c.Universe.Type(syncMutex), - "timeDuration": c.Universe.Type(timeDuration), - "namespaceAll": c.Universe.Type(metav1NamespaceAll), - "object": c.Universe.Type(metav1Object), - } - - sw.Do(sharedInformerFactoryStruct, m) - sw.Do(sharedInformerFactoryInterface, m) - - return sw.Error() -} - -var sharedInformerFactoryStruct = ` -// SharedInformerOption defines the functional option type for SharedInformerFactory. -type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory - -type sharedInformerFactory struct { - client {{.clientSetInterface|raw}} - namespace string - tweakListOptions {{.interfacesTweakListOptionsFunc|raw}} - lock {{.syncMutex|raw}} - defaultResync {{.timeDuration|raw}} - customResync map[{{.reflectType|raw}}]{{.timeDuration|raw}} - transform {{.cacheTransformFunc|raw}} - - informers map[{{.reflectType|raw}}]{{.cacheSharedIndexInformer|raw}} - // startedInformers is used for tracking which informers have been started. - // This allows Start() to be called multiple times safely. - startedInformers map[{{.reflectType|raw}}]bool - // wg tracks how many goroutines were started. - wg sync.WaitGroup - // shuttingDown is true when Shutdown has been called. It may still be running - // because it needs to wait for goroutines. - shuttingDown bool -} - -// WithCustomResyncConfig sets a custom resync period for the specified informer types. -func WithCustomResyncConfig(resyncConfig map[{{.object|raw}}]{{.timeDuration|raw}}) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - for k, v := range resyncConfig { - factory.customResync[reflect.TypeOf(k)] = v - } - return factory - } -} - -// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. -func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - factory.tweakListOptions = tweakListOptions - return factory - } -} - -// WithNamespace limits the SharedInformerFactory to the specified namespace. -func WithNamespace(namespace string) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - factory.namespace = namespace - return factory - } -} - -// WithTransform sets a transform on all informers. -func WithTransform(transform {{.cacheTransformFunc|raw}}) SharedInformerOption { - return func(factory *sharedInformerFactory) *sharedInformerFactory { - factory.transform = transform - return factory - } -} - -// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. -func NewSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}) SharedInformerFactory { - return NewSharedInformerFactoryWithOptions(client, defaultResync) -} - -// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. -// Listers obtained via this SharedInformerFactory will be subject to the same filters -// as specified here. -// Deprecated: Please use NewSharedInformerFactoryWithOptions instead -func NewFilteredSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}, namespace string, tweakListOptions {{.interfacesTweakListOptionsFunc|raw}}) SharedInformerFactory { - return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) -} - -// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. -func NewSharedInformerFactoryWithOptions(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}, options ...SharedInformerOption) SharedInformerFactory { - factory := &sharedInformerFactory{ - client: client, - namespace: v1.NamespaceAll, - defaultResync: defaultResync, - informers: make(map[{{.reflectType|raw}}]{{.cacheSharedIndexInformer|raw}}), - startedInformers: make(map[{{.reflectType|raw}}]bool), - customResync: make(map[{{.reflectType|raw}}]{{.timeDuration|raw}}), - } - - // Apply all options - for _, opt := range options { - factory = opt(factory) - } - - return factory -} - -func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { - f.lock.Lock() - defer f.lock.Unlock() - - if f.shuttingDown { - return - } - - for informerType, informer := range f.informers { - if !f.startedInformers[informerType] { - f.wg.Add(1) - // We need a new variable in each loop iteration, - // otherwise the goroutine would use the loop variable - // and that keeps changing. - informer := informer - go func() { - defer f.wg.Done() - informer.Run(stopCh) - }() - f.startedInformers[informerType] = true - } - } -} - -func (f *sharedInformerFactory) Shutdown() { - f.lock.Lock() - f.shuttingDown = true - f.lock.Unlock() - - - // Will return immediately if there is nothing to wait for. - f.wg.Wait() -} - -func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { - informers := func()map[reflect.Type]cache.SharedIndexInformer{ - f.lock.Lock() - defer f.lock.Unlock() - - informers := map[reflect.Type]cache.SharedIndexInformer{} - for informerType, informer := range f.informers { - if f.startedInformers[informerType] { - informers[informerType] = informer - } - } - return informers - }() - - res := map[reflect.Type]bool{} - for informType, informer := range informers { - res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) - } - return res -} - -// InformerFor returns the SharedIndexInformer for obj using an internal -// client. -func (f *sharedInformerFactory) InformerFor(obj {{.runtimeObject|raw}}, newFunc {{.interfacesNewInformerFunc|raw}}) {{.cacheSharedIndexInformer|raw}} { - f.lock.Lock() - defer f.lock.Unlock() - - informerType := reflect.TypeOf(obj) - informer, exists := f.informers[informerType] - if exists { - return informer - } - - resyncPeriod, exists := f.customResync[informerType] - if !exists { - resyncPeriod = f.defaultResync - } - - informer = newFunc(f.client, resyncPeriod) - informer.SetTransform(f.transform) - f.informers[informerType] = informer - - return informer -} -` - -var sharedInformerFactoryInterface = ` -// SharedInformerFactory provides shared informers for resources in all known -// API group versions. -// -// It is typically used like this: -// -// ctx, cancel := context.Background() -// defer cancel() -// factory := NewSharedInformerFactory(client, resyncPeriod) -// defer factory.WaitForStop() // Returns immediately if nothing was started. -// genericInformer := factory.ForResource(resource) -// typedInformer := factory.SomeAPIGroup().V1().SomeType() -// factory.Start(ctx.Done()) // Start processing these informers. -// synced := factory.WaitForCacheSync(ctx.Done()) -// for v, ok := range synced { -// if !ok { -// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) -// return -// } -// } -// -// // Creating informers can also be created after Start, but then -// // Start must be called again: -// anotherGenericInformer := factory.ForResource(resource) -// factory.Start(ctx.Done()) -type SharedInformerFactory interface { - {{.informerFactoryInterface|raw}} - - // Start initializes all requested informers. They are handled in goroutines - // which run until the stop channel gets closed. - Start(stopCh <-chan struct{}) - - // Shutdown marks a factory as shutting down. At that point no new - // informers can be started anymore and Start will return without - // doing anything. - // - // In addition, Shutdown blocks until all goroutines have terminated. For that - // to happen, the close channel(s) that they were started with must be closed, - // either before Shutdown gets called or while it is waiting. - // - // Shutdown may be called multiple times, even concurrently. All such calls will - // block until all goroutines have terminated. - Shutdown() - - // WaitForCacheSync blocks until all started informers' caches were synced - // or the stop channel gets closed. - WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool - - // ForResource gives generic access to a shared informer of the matching type. - ForResource(resource {{.schemaGroupVersionResource|raw}}) (GenericInformer, error) - - // InformerFor returns the SharedIndexInformer for obj using an internal - // client. - InformerFor(obj {{.runtimeObject|raw}}, newFunc {{.interfacesNewInformerFunc|raw}}) {{.cacheSharedIndexInformer|raw}} - - {{$gvInterfaces := .gvInterfaces}} - {{$gvGoNames := .gvGoNames}} - {{range $groupName, $group := .groupVersions}}{{index $gvGoNames $groupName}}() {{index $gvInterfaces $groupName|raw}} - {{end}} -} - -{{$gvNewFuncs := .gvNewFuncs}} -{{$gvGoNames := .gvGoNames}} -{{range $groupPkgName, $group := .groupVersions}} -func (f *sharedInformerFactory) {{index $gvGoNames $groupPkgName}}() {{index $gvInterfaces $groupPkgName|raw}} { - return {{index $gvNewFuncs $groupPkgName|raw}}(f, f.namespace, f.tweakListOptions) -} -{{end}} -` diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factoryinterface.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factoryinterface.go deleted file mode 100644 index 70826eba..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/factoryinterface.go +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/klog/v2" -) - -// factoryInterfaceGenerator produces a file of interfaces used to break a dependency cycle for -// informer registration -type factoryInterfaceGenerator struct { - generator.DefaultGen - outputPackage string - imports namer.ImportTracker - clientSetPackage string - filtered bool -} - -var _ generator.Generator = &factoryInterfaceGenerator{} - -func (g *factoryInterfaceGenerator) Filter(c *generator.Context, t *types.Type) bool { - if !g.filtered { - g.filtered = true - return true - } - return false -} - -func (g *factoryInterfaceGenerator) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *factoryInterfaceGenerator) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - return -} - -func (g *factoryInterfaceGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "{{", "}}") - - klog.V(5).Infof("processing type %v", t) - - m := map[string]interface{}{ - "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), - "clientSetPackage": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), - "runtimeObject": c.Universe.Type(runtimeObject), - "timeDuration": c.Universe.Type(timeDuration), - "v1ListOptions": c.Universe.Type(v1ListOptions), - } - - sw.Do(externalSharedInformerFactoryInterface, m) - - return sw.Error() -} - -var externalSharedInformerFactoryInterface = ` -// NewInformerFunc takes {{.clientSetPackage|raw}} and {{.timeDuration|raw}} to return a SharedIndexInformer. -type NewInformerFunc func({{.clientSetPackage|raw}}, {{.timeDuration|raw}}) cache.SharedIndexInformer - -// SharedInformerFactory a small interface to allow for adding an informer without an import cycle -type SharedInformerFactory interface { - Start(stopCh <-chan struct{}) - InformerFor(obj {{.runtimeObject|raw}}, newFunc NewInformerFunc) {{.cacheSharedIndexInformer|raw}} -} - -// TweakListOptionsFunc is a function that transforms a {{.v1ListOptions|raw}}. -type TweakListOptionsFunc func(*{{.v1ListOptions|raw}}) -` diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/generic.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/generic.go deleted file mode 100644 index a5a42953..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/generic.go +++ /dev/null @@ -1,184 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "sort" - "strings" - - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - codegennamer "k8s.io/code-generator/pkg/namer" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// genericGenerator generates the generic informer. -type genericGenerator struct { - generator.DefaultGen - outputPackage string - imports namer.ImportTracker - groupVersions map[string]clientgentypes.GroupVersions - groupGoNames map[string]string - pluralExceptions map[string]string - typesForGroupVersion map[clientgentypes.GroupVersion][]*types.Type - filtered bool -} - -var _ generator.Generator = &genericGenerator{} - -func (g *genericGenerator) Filter(c *generator.Context, t *types.Type) bool { - if !g.filtered { - g.filtered = true - return true - } - return false -} - -func (g *genericGenerator) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - "allLowercasePlural": namer.NewAllLowercasePluralNamer(g.pluralExceptions), - "publicPlural": namer.NewPublicPluralNamer(g.pluralExceptions), - "resource": codegennamer.NewTagOverrideNamer("resourceName", namer.NewAllLowercasePluralNamer(g.pluralExceptions)), - } -} - -func (g *genericGenerator) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - imports = append(imports, "fmt") - return -} - -type group struct { - GroupGoName string - Name string - Versions []*version -} - -type groupSort []group - -func (g groupSort) Len() int { return len(g) } -func (g groupSort) Less(i, j int) bool { - return strings.ToLower(g[i].Name) < strings.ToLower(g[j].Name) -} -func (g groupSort) Swap(i, j int) { g[i], g[j] = g[j], g[i] } - -type version struct { - Name string - GoName string - Resources []*types.Type -} - -type versionSort []*version - -func (v versionSort) Len() int { return len(v) } -func (v versionSort) Less(i, j int) bool { - return strings.ToLower(v[i].Name) < strings.ToLower(v[j].Name) -} -func (v versionSort) Swap(i, j int) { v[i], v[j] = v[j], v[i] } - -func (g *genericGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "{{", "}}") - - groups := []group{} - schemeGVs := make(map[*version]*types.Type) - - orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} - for groupPackageName, groupVersions := range g.groupVersions { - group := group{ - GroupGoName: g.groupGoNames[groupPackageName], - Name: groupVersions.Group.NonEmpty(), - Versions: []*version{}, - } - for _, v := range groupVersions.Versions { - gv := clientgentypes.GroupVersion{Group: groupVersions.Group, Version: v.Version} - version := &version{ - Name: v.Version.NonEmpty(), - GoName: namer.IC(v.Version.NonEmpty()), - Resources: orderer.OrderTypes(g.typesForGroupVersion[gv]), - } - func() { - schemeGVs[version] = c.Universe.Variable(types.Name{Package: g.typesForGroupVersion[gv][0].Name.Package, Name: "SchemeGroupVersion"}) - }() - group.Versions = append(group.Versions, version) - } - sort.Sort(versionSort(group.Versions)) - groups = append(groups, group) - } - sort.Sort(groupSort(groups)) - - m := map[string]interface{}{ - "cacheGenericLister": c.Universe.Type(cacheGenericLister), - "cacheNewGenericLister": c.Universe.Function(cacheNewGenericLister), - "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), - "groups": groups, - "schemeGVs": schemeGVs, - "schemaGroupResource": c.Universe.Type(schemaGroupResource), - "schemaGroupVersionResource": c.Universe.Type(schemaGroupVersionResource), - } - - sw.Do(genericInformer, m) - sw.Do(forResource, m) - - return sw.Error() -} - -var genericInformer = ` -// GenericInformer is type of SharedIndexInformer which will locate and delegate to other -// sharedInformers based on type -type GenericInformer interface { - Informer() {{.cacheSharedIndexInformer|raw}} - Lister() {{.cacheGenericLister|raw}} -} - -type genericInformer struct { - informer {{.cacheSharedIndexInformer|raw}} - resource {{.schemaGroupResource|raw}} -} - -// Informer returns the SharedIndexInformer. -func (f *genericInformer) Informer() {{.cacheSharedIndexInformer|raw}} { - return f.informer -} - -// Lister returns the GenericLister. -func (f *genericInformer) Lister() {{.cacheGenericLister|raw}} { - return {{.cacheNewGenericLister|raw}}(f.Informer().GetIndexer(), f.resource) -} -` - -var forResource = ` -// ForResource gives generic access to a shared informer of the matching type -// TODO extend this to unknown resources with a client pool -func (f *sharedInformerFactory) ForResource(resource {{.schemaGroupVersionResource|raw}}) (GenericInformer, error) { - switch resource { - {{range $group := .groups -}}{{$GroupGoName := .GroupGoName -}} - {{range $version := .Versions -}} - // Group={{$group.Name}}, Version={{.Name}} - {{range .Resources -}} - case {{index $.schemeGVs $version|raw}}.WithResource("{{.|resource}}"): - return &genericInformer{resource: resource.GroupResource(), informer: f.{{$GroupGoName}}().{{$version.GoName}}().{{.|publicPlural}}().Informer()}, nil - {{end}} - {{end}} - {{end -}} - } - - return nil, fmt.Errorf("no informer found for %v", resource) -} -` diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go deleted file mode 100644 index 0bba93c4..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go +++ /dev/null @@ -1,118 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "path/filepath" - "strings" - - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// groupInterfaceGenerator generates the per-group interface file. -type groupInterfaceGenerator struct { - generator.DefaultGen - outputPackage string - imports namer.ImportTracker - groupVersions clientgentypes.GroupVersions - filtered bool - internalInterfacesPackage string -} - -var _ generator.Generator = &groupInterfaceGenerator{} - -func (g *groupInterfaceGenerator) Filter(c *generator.Context, t *types.Type) bool { - if !g.filtered { - g.filtered = true - return true - } - return false -} - -func (g *groupInterfaceGenerator) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *groupInterfaceGenerator) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - return -} - -type versionData struct { - Name string - Interface *types.Type - New *types.Type -} - -func (g *groupInterfaceGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - versions := make([]versionData, 0, len(g.groupVersions.Versions)) - for _, version := range g.groupVersions.Versions { - gv := clientgentypes.GroupVersion{Group: g.groupVersions.Group, Version: version.Version} - versionPackage := filepath.Join(g.outputPackage, strings.ToLower(gv.Version.NonEmpty())) - iface := c.Universe.Type(types.Name{Package: versionPackage, Name: "Interface"}) - versions = append(versions, versionData{ - Name: namer.IC(version.Version.NonEmpty()), - Interface: iface, - New: c.Universe.Function(types.Name{Package: versionPackage, Name: "New"}), - }) - } - m := map[string]interface{}{ - "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), - "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), - "versions": versions, - } - - sw.Do(groupTemplate, m) - - return sw.Error() -} - -var groupTemplate = ` -// Interface provides access to each of this group's versions. -type Interface interface { - $range .versions -$ - // $.Name$ provides access to shared informers for resources in $.Name$. - $.Name$() $.Interface|raw$ - $end$ -} - -type group struct { - factory $.interfacesSharedInformerFactory|raw$ - namespace string - tweakListOptions $.interfacesTweakListOptionsFunc|raw$ -} - -// New returns a new Interface. -func New(f $.interfacesSharedInformerFactory|raw$, namespace string, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) Interface { - return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} - -$range .versions$ -// $.Name$ returns a new $.Interface|raw$. -func (g *group) $.Name$() $.Interface|raw$ { - return $.New|raw$(g.factory, g.namespace, g.tweakListOptions) -} -$end$ -` diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/informer.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/informer.go deleted file mode 100644 index da00e6e6..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/informer.go +++ /dev/null @@ -1,186 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "io" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - - "k8s.io/klog/v2" -) - -// informerGenerator produces a file of listers for a given GroupVersion and -// type. -type informerGenerator struct { - generator.DefaultGen - outputPackage string - groupPkgName string - groupVersion clientgentypes.GroupVersion - groupGoName string - typeToGenerate *types.Type - imports namer.ImportTracker - clientSetPackage string - listersPackage string - internalInterfacesPackage string -} - -var _ generator.Generator = &informerGenerator{} - -func (g *informerGenerator) Filter(c *generator.Context, t *types.Type) bool { - return t == g.typeToGenerate -} - -func (g *informerGenerator) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *informerGenerator) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - return -} - -func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - klog.V(5).Infof("processing type %v", t) - - listerPackage := fmt.Sprintf("%s/%s/%s", g.listersPackage, g.groupPkgName, strings.ToLower(g.groupVersion.Version.NonEmpty())) - clientSetInterface := c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}) - informerFor := "InformerFor" - - tags, err := util.ParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if err != nil { - return err - } - - m := map[string]interface{}{ - "apiScheme": c.Universe.Type(apiScheme), - "cacheIndexers": c.Universe.Type(cacheIndexers), - "cacheListWatch": c.Universe.Type(cacheListWatch), - "cacheMetaNamespaceIndexFunc": c.Universe.Function(cacheMetaNamespaceIndexFunc), - "cacheNamespaceIndex": c.Universe.Variable(cacheNamespaceIndex), - "cacheNewSharedIndexInformer": c.Universe.Function(cacheNewSharedIndexInformer), - "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), - "clientSetInterface": clientSetInterface, - "group": namer.IC(g.groupGoName), - "informerFor": informerFor, - "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), - "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), - "listOptions": c.Universe.Type(listOptions), - "lister": c.Universe.Type(types.Name{Package: listerPackage, Name: t.Name.Name + "Lister"}), - "namespaceAll": c.Universe.Type(metav1NamespaceAll), - "namespaced": !tags.NonNamespaced, - "newLister": c.Universe.Function(types.Name{Package: listerPackage, Name: "New" + t.Name.Name + "Lister"}), - "runtimeObject": c.Universe.Type(runtimeObject), - "timeDuration": c.Universe.Type(timeDuration), - "type": t, - "v1ListOptions": c.Universe.Type(v1ListOptions), - "version": namer.IC(g.groupVersion.Version.String()), - "watchInterface": c.Universe.Type(watchInterface), - } - - sw.Do(typeInformerInterface, m) - sw.Do(typeInformerStruct, m) - sw.Do(typeInformerPublicConstructor, m) - sw.Do(typeFilteredInformerPublicConstructor, m) - sw.Do(typeInformerConstructor, m) - sw.Do(typeInformerInformer, m) - sw.Do(typeInformerLister, m) - - return sw.Error() -} - -var typeInformerInterface = ` -// $.type|public$Informer provides access to a shared informer and lister for -// $.type|publicPlural$. -type $.type|public$Informer interface { - Informer() $.cacheSharedIndexInformer|raw$ - Lister() $.lister|raw$ -} -` - -var typeInformerStruct = ` -type $.type|private$Informer struct { - factory $.interfacesSharedInformerFactory|raw$ - tweakListOptions $.interfacesTweakListOptionsFunc|raw$ - $if .namespaced$namespace string$end$ -} -` - -var typeInformerPublicConstructor = ` -// New$.type|public$Informer constructs a new informer for $.type|public$ 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 New$.type|public$Informer(client $.clientSetInterface|raw$$if .namespaced$, namespace string$end$, resyncPeriod $.timeDuration|raw$, indexers $.cacheIndexers|raw$) $.cacheSharedIndexInformer|raw$ { - return NewFiltered$.type|public$Informer(client$if .namespaced$, namespace$end$, resyncPeriod, indexers, nil) -} -` - -var typeFilteredInformerPublicConstructor = ` -// NewFiltered$.type|public$Informer constructs a new informer for $.type|public$ 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 NewFiltered$.type|public$Informer(client $.clientSetInterface|raw$$if .namespaced$, namespace string$end$, resyncPeriod $.timeDuration|raw$, indexers $.cacheIndexers|raw$, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) $.cacheSharedIndexInformer|raw$ { - return $.cacheNewSharedIndexInformer|raw$( - &$.cacheListWatch|raw${ - ListFunc: func(options $.v1ListOptions|raw$) ($.runtimeObject|raw$, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).List(context.TODO(), options) - }, - WatchFunc: func(options $.v1ListOptions|raw$) ($.watchInterface|raw$, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).Watch(context.TODO(), options) - }, - }, - &$.type|raw${}, - resyncPeriod, - indexers, - ) -} -` - -var typeInformerConstructor = ` -func (f *$.type|private$Informer) defaultInformer(client $.clientSetInterface|raw$, resyncPeriod $.timeDuration|raw$) $.cacheSharedIndexInformer|raw$ { - return NewFiltered$.type|public$Informer(client$if .namespaced$, f.namespace$end$, resyncPeriod, $.cacheIndexers|raw${$.cacheNamespaceIndex|raw$: $.cacheMetaNamespaceIndexFunc|raw$}, f.tweakListOptions) -} -` - -var typeInformerInformer = ` -func (f *$.type|private$Informer) Informer() $.cacheSharedIndexInformer|raw$ { - return f.factory.$.informerFor$(&$.type|raw${}, f.defaultInformer) -} -` - -var typeInformerLister = ` -func (f *$.type|private$Informer) Lister() $.lister|raw$ { - return $.newLister|raw$(f.Informer().GetIndexer()) -} -` diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/packages.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/packages.go deleted file mode 100644 index dd2c9cce..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/packages.go +++ /dev/null @@ -1,347 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "path" - "path/filepath" - "strings" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - "k8s.io/klog/v2" - - "k8s.io/code-generator/cmd/client-gen/generators/util" - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - informergenargs "k8s.io/code-generator/cmd/informer-gen/args" - genutil "k8s.io/code-generator/pkg/util" -) - -// NameSystems returns the name system used by the generators in this package. -func NameSystems(pluralExceptions map[string]string) namer.NameSystems { - return namer.NameSystems{ - "public": namer.NewPublicNamer(0), - "private": namer.NewPrivateNamer(0), - "raw": namer.NewRawNamer("", nil), - "publicPlural": namer.NewPublicPluralNamer(pluralExceptions), - "allLowercasePlural": namer.NewAllLowercasePluralNamer(pluralExceptions), - "lowercaseSingular": &lowercaseSingularNamer{}, - } -} - -// lowercaseSingularNamer implements Namer -type lowercaseSingularNamer struct{} - -// Name returns t's name in all lowercase. -func (n *lowercaseSingularNamer) Name(t *types.Type) string { - return strings.ToLower(t.Name.Name) -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -// objectMetaForPackage returns the type of ObjectMeta used by package p. -func objectMetaForPackage(p *types.Package) (*types.Type, bool, error) { - generatingForPackage := false - for _, t := range p.Types { - if !util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)).GenerateClient { - continue - } - generatingForPackage = true - for _, member := range t.Members { - if member.Name == "ObjectMeta" { - return member.Type, isInternal(member), nil - } - } - } - if generatingForPackage { - return nil, false, fmt.Errorf("unable to find ObjectMeta for any types in package %s", p.Path) - } - return nil, false, nil -} - -// isInternal returns true if the tags for a member do not contain a json tag -func isInternal(m types.Member) bool { - return !strings.Contains(m.Tags, "json") -} - -func packageForInternalInterfaces(base string) string { - return filepath.Join(base, "internalinterfaces") -} - -// Packages makes the client package definition. -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - customArgs, ok := arguments.CustomArgs.(*informergenargs.CustomArgs) - if !ok { - klog.Fatalf("Wrong CustomArgs type: %T", arguments.CustomArgs) - } - - internalVersionPackagePath := filepath.Join(arguments.OutputPackagePath) - externalVersionPackagePath := filepath.Join(arguments.OutputPackagePath) - if !customArgs.SingleDirectory { - internalVersionPackagePath = filepath.Join(arguments.OutputPackagePath, "internalversion") - externalVersionPackagePath = filepath.Join(arguments.OutputPackagePath, "externalversions") - } - - var packageList generator.Packages - typesForGroupVersion := make(map[clientgentypes.GroupVersion][]*types.Type) - - externalGroupVersions := make(map[string]clientgentypes.GroupVersions) - internalGroupVersions := make(map[string]clientgentypes.GroupVersions) - groupGoNames := make(map[string]string) - for _, inputDir := range arguments.InputDirs { - p := context.Universe.Package(genutil.Vendorless(inputDir)) - - objectMeta, internal, err := objectMetaForPackage(p) - if err != nil { - klog.Fatal(err) - } - if objectMeta == nil { - // no types in this package had genclient - continue - } - - var gv clientgentypes.GroupVersion - var targetGroupVersions map[string]clientgentypes.GroupVersions - - if internal { - lastSlash := strings.LastIndex(p.Path, "/") - if lastSlash == -1 { - klog.Fatalf("error constructing internal group version for package %q", p.Path) - } - gv.Group = clientgentypes.Group(p.Path[lastSlash+1:]) - targetGroupVersions = internalGroupVersions - } else { - parts := strings.Split(p.Path, "/") - gv.Group = clientgentypes.Group(parts[len(parts)-2]) - gv.Version = clientgentypes.Version(parts[len(parts)-1]) - targetGroupVersions = externalGroupVersions - } - groupPackageName := gv.Group.NonEmpty() - gvPackage := path.Clean(p.Path) - - // If there's a comment of the form "// +groupName=somegroup" or - // "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the - // group when generating. - if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { - gv.Group = clientgentypes.Group(override[0]) - } - - // If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as - // the Go group identifier in CamelCase. It defaults - groupGoNames[groupPackageName] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0]) - if override := types.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil { - groupGoNames[groupPackageName] = namer.IC(override[0]) - } - - var typesToGenerate []*types.Type - for _, t := range p.Types { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if !tags.GenerateClient || tags.NoVerbs || !tags.HasVerb("list") || !tags.HasVerb("watch") { - continue - } - - typesToGenerate = append(typesToGenerate, t) - - if _, ok := typesForGroupVersion[gv]; !ok { - typesForGroupVersion[gv] = []*types.Type{} - } - typesForGroupVersion[gv] = append(typesForGroupVersion[gv], t) - } - if len(typesToGenerate) == 0 { - continue - } - - groupVersionsEntry, ok := targetGroupVersions[groupPackageName] - if !ok { - groupVersionsEntry = clientgentypes.GroupVersions{ - PackageName: groupPackageName, - Group: gv.Group, - } - } - groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, clientgentypes.PackageVersion{Version: gv.Version, Package: gvPackage}) - targetGroupVersions[groupPackageName] = groupVersionsEntry - - orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} - typesToGenerate = orderer.OrderTypes(typesToGenerate) - - if internal { - packageList = append(packageList, versionPackage(internalVersionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesToGenerate, customArgs.InternalClientSetPackage, customArgs.ListersPackage)) - } else { - packageList = append(packageList, versionPackage(externalVersionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesToGenerate, customArgs.VersionedClientSetPackage, customArgs.ListersPackage)) - } - } - - if len(externalGroupVersions) != 0 { - packageList = append(packageList, factoryInterfacePackage(externalVersionPackagePath, boilerplate, customArgs.VersionedClientSetPackage)) - packageList = append(packageList, factoryPackage(externalVersionPackagePath, boilerplate, groupGoNames, genutil.PluralExceptionListToMapOrDie(customArgs.PluralExceptions), externalGroupVersions, - customArgs.VersionedClientSetPackage, - typesForGroupVersion)) - for _, gvs := range externalGroupVersions { - packageList = append(packageList, groupPackage(externalVersionPackagePath, gvs, boilerplate)) - } - } - - if len(internalGroupVersions) != 0 { - packageList = append(packageList, factoryInterfacePackage(internalVersionPackagePath, boilerplate, customArgs.InternalClientSetPackage)) - packageList = append(packageList, factoryPackage(internalVersionPackagePath, boilerplate, groupGoNames, genutil.PluralExceptionListToMapOrDie(customArgs.PluralExceptions), internalGroupVersions, customArgs.InternalClientSetPackage, typesForGroupVersion)) - for _, gvs := range internalGroupVersions { - packageList = append(packageList, groupPackage(internalVersionPackagePath, gvs, boilerplate)) - } - } - - return packageList -} - -func factoryPackage(basePackage string, boilerplate []byte, groupGoNames, pluralExceptions map[string]string, groupVersions map[string]clientgentypes.GroupVersions, clientSetPackage string, - typesForGroupVersion map[clientgentypes.GroupVersion][]*types.Type) generator.Package { - return &generator.DefaultPackage{ - PackageName: filepath.Base(basePackage), - PackagePath: basePackage, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = append(generators, &factoryGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: "factory", - }, - outputPackage: basePackage, - imports: generator.NewImportTracker(), - groupVersions: groupVersions, - clientSetPackage: clientSetPackage, - internalInterfacesPackage: packageForInternalInterfaces(basePackage), - gvGoNames: groupGoNames, - }) - - generators = append(generators, &genericGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: "generic", - }, - outputPackage: basePackage, - imports: generator.NewImportTracker(), - groupVersions: groupVersions, - pluralExceptions: pluralExceptions, - typesForGroupVersion: typesForGroupVersion, - groupGoNames: groupGoNames, - }) - - return generators - }, - } -} - -func factoryInterfacePackage(basePackage string, boilerplate []byte, clientSetPackage string) generator.Package { - packagePath := packageForInternalInterfaces(basePackage) - - return &generator.DefaultPackage{ - PackageName: filepath.Base(packagePath), - PackagePath: packagePath, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = append(generators, &factoryInterfaceGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: "factory_interfaces", - }, - outputPackage: packagePath, - imports: generator.NewImportTracker(), - clientSetPackage: clientSetPackage, - }) - - return generators - }, - } -} - -func groupPackage(basePackage string, groupVersions clientgentypes.GroupVersions, boilerplate []byte) generator.Package { - packagePath := filepath.Join(basePackage, groupVersions.PackageName) - groupPkgName := strings.Split(string(groupVersions.PackageName), ".")[0] - - return &generator.DefaultPackage{ - PackageName: groupPkgName, - PackagePath: packagePath, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = append(generators, &groupInterfaceGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: "interface", - }, - outputPackage: packagePath, - groupVersions: groupVersions, - imports: generator.NewImportTracker(), - internalInterfacesPackage: packageForInternalInterfaces(basePackage), - }) - return generators - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("watch") - }, - } -} - -func versionPackage(basePackage string, groupPkgName string, gv clientgentypes.GroupVersion, groupGoName string, boilerplate []byte, typesToGenerate []*types.Type, clientSetPackage, listersPackage string) generator.Package { - packagePath := filepath.Join(basePackage, groupPkgName, strings.ToLower(gv.Version.NonEmpty())) - - return &generator.DefaultPackage{ - PackageName: strings.ToLower(gv.Version.NonEmpty()), - PackagePath: packagePath, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = append(generators, &versionInterfaceGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: "interface", - }, - outputPackage: packagePath, - imports: generator.NewImportTracker(), - types: typesToGenerate, - internalInterfacesPackage: packageForInternalInterfaces(basePackage), - }) - - for _, t := range typesToGenerate { - generators = append(generators, &informerGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: strings.ToLower(t.Name.Name), - }, - outputPackage: packagePath, - groupPkgName: groupPkgName, - groupVersion: gv, - groupGoName: groupGoName, - typeToGenerate: t, - imports: generator.NewImportTracker(), - clientSetPackage: clientSetPackage, - listersPackage: listersPackage, - internalInterfacesPackage: packageForInternalInterfaces(basePackage), - }) - } - return generators - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("watch") - }, - } -} diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/types.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/types.go deleted file mode 100644 index fc1f7786..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/types.go +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import "k8s.io/gengo/types" - -var ( - apiScheme = types.Name{Package: "k8s.io/kubernetes/pkg/api/legacyscheme", Name: "Scheme"} - cacheGenericLister = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "GenericLister"} - cacheIndexers = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "Indexers"} - cacheListWatch = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "ListWatch"} - cacheMetaNamespaceIndexFunc = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "MetaNamespaceIndexFunc"} - cacheNamespaceIndex = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "NamespaceIndex"} - cacheNewGenericLister = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "NewGenericLister"} - cacheNewSharedIndexInformer = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "NewSharedIndexInformer"} - cacheSharedIndexInformer = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "SharedIndexInformer"} - cacheTransformFunc = types.Name{Package: "k8s.io/client-go/tools/cache", Name: "TransformFunc"} - listOptions = types.Name{Package: "k8s.io/kubernetes/pkg/apis/core", Name: "ListOptions"} - reflectType = types.Name{Package: "reflect", Name: "Type"} - runtimeObject = types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "Object"} - schemaGroupResource = types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupResource"} - schemaGroupVersionResource = types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupVersionResource"} - syncMutex = types.Name{Package: "sync", Name: "Mutex"} - timeDuration = types.Name{Package: "time", Name: "Duration"} - v1ListOptions = types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ListOptions"} - metav1NamespaceAll = types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "NamespaceAll"} - metav1Object = types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "Object"} - watchInterface = types.Name{Package: "k8s.io/apimachinery/pkg/watch", Name: "Interface"} -) diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/versioninterface.go b/vendor/k8s.io/code-generator/cmd/informer-gen/generators/versioninterface.go deleted file mode 100644 index 3b51f8dc..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/generators/versioninterface.go +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" -) - -// versionInterfaceGenerator generates the per-version interface file. -type versionInterfaceGenerator struct { - generator.DefaultGen - outputPackage string - imports namer.ImportTracker - types []*types.Type - filtered bool - internalInterfacesPackage string -} - -var _ generator.Generator = &versionInterfaceGenerator{} - -func (g *versionInterfaceGenerator) Filter(c *generator.Context, t *types.Type) bool { - if !g.filtered { - g.filtered = true - return true - } - return false -} - -func (g *versionInterfaceGenerator) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *versionInterfaceGenerator) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - return -} - -func (g *versionInterfaceGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - m := map[string]interface{}{ - "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), - "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), - "types": g.types, - } - - sw.Do(versionTemplate, m) - for _, typeDef := range g.types { - tags, err := util.ParseClientGenTags(append(typeDef.SecondClosestCommentLines, typeDef.CommentLines...)) - if err != nil { - return err - } - m["namespaced"] = !tags.NonNamespaced - m["type"] = typeDef - sw.Do(versionFuncTemplate, m) - } - - return sw.Error() -} - -var versionTemplate = ` -// Interface provides access to all the informers in this group version. -type Interface interface { - $range .types -$ - // $.|publicPlural$ returns a $.|public$Informer. - $.|publicPlural$() $.|public$Informer - $end$ -} - -type version struct { - factory $.interfacesSharedInformerFactory|raw$ - namespace string - tweakListOptions $.interfacesTweakListOptionsFunc|raw$ -} - -// New returns a new Interface. -func New(f $.interfacesSharedInformerFactory|raw$, namespace string, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) Interface { - return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} -} -` - -var versionFuncTemplate = ` -// $.type|publicPlural$ returns a $.type|public$Informer. -func (v *version) $.type|publicPlural$() $.type|public$Informer { - return &$.type|private$Informer{factory: v.factory$if .namespaced$, namespace: v.namespace$end$, tweakListOptions: v.tweakListOptions} -} -` diff --git a/vendor/k8s.io/code-generator/cmd/informer-gen/main.go b/vendor/k8s.io/code-generator/cmd/informer-gen/main.go deleted file mode 100644 index 1247c35b..00000000 --- a/vendor/k8s.io/code-generator/cmd/informer-gen/main.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package main - -import ( - "flag" - - "github.com/spf13/pflag" - "k8s.io/code-generator/cmd/informer-gen/generators" - "k8s.io/code-generator/pkg/util" - "k8s.io/klog/v2" - - generatorargs "k8s.io/code-generator/cmd/informer-gen/args" -) - -func main() { - klog.InitFlags(nil) - genericArgs, customArgs := generatorargs.NewDefaults() - - // Override defaults. - // TODO: move out of informer-gen - genericArgs.OutputPackagePath = "k8s.io/kubernetes/pkg/client/informers/informers_generated" - customArgs.VersionedClientSetPackage = "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" - customArgs.InternalClientSetPackage = "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - customArgs.ListersPackage = "k8s.io/kubernetes/pkg/client/listers" - - genericArgs.AddFlags(pflag.CommandLine) - customArgs.AddFlags(pflag.CommandLine) - flag.Set("logtostderr", "true") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - if err := generatorargs.Validate(genericArgs); err != nil { - klog.Fatalf("Error: %v", err) - } - - // Run it. - if err := genericArgs.Execute( - generators.NameSystems(util.PluralExceptionListToMapOrDie(customArgs.PluralExceptions)), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Fatalf("Error: %v", err) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/cmd/lister-gen/args/args.go b/vendor/k8s.io/code-generator/cmd/lister-gen/args/args.go deleted file mode 100644 index 17033450..00000000 --- a/vendor/k8s.io/code-generator/cmd/lister-gen/args/args.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "fmt" - "path" - - "github.com/spf13/pflag" - codegenutil "k8s.io/code-generator/pkg/util" - "k8s.io/gengo/args" -) - -// CustomArgs is used by the gengo framework to pass args specific to this generator. -type CustomArgs struct { - // PluralExceptions specify list of exceptions used when pluralizing certain types. - // For example 'Endpoints:Endpoints', otherwise the pluralizer will generate 'Endpointes'. - PluralExceptions []string -} - -// NewDefaults returns default arguments for the generator. -func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { - genericArgs := args.Default().WithoutDefaultFlagParsing() - customArgs := &CustomArgs{ - PluralExceptions: []string{"Endpoints:Endpoints"}, - } - genericArgs.CustomArgs = customArgs - - if pkg := codegenutil.CurrentPackage(); len(pkg) != 0 { - genericArgs.OutputPackagePath = path.Join(pkg, "pkg/client/listers") - } - - return genericArgs, customArgs -} - -// AddFlags add the generator flags to the flag set. -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { - fs.StringSliceVar(&ca.PluralExceptions, "plural-exceptions", ca.PluralExceptions, "list of comma separated plural exception definitions in Type:PluralizedType format") -} - -// Validate checks the given arguments. -func Validate(genericArgs *args.GeneratorArgs) error { - _ = genericArgs.CustomArgs.(*CustomArgs) - - if len(genericArgs.OutputPackagePath) == 0 { - return fmt.Errorf("output package cannot be empty") - } - - return nil -} diff --git a/vendor/k8s.io/code-generator/cmd/lister-gen/generators/expansion.go b/vendor/k8s.io/code-generator/cmd/lister-gen/generators/expansion.go deleted file mode 100644 index dd45d774..00000000 --- a/vendor/k8s.io/code-generator/cmd/lister-gen/generators/expansion.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "os" - "path/filepath" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" -) - -// expansionGenerator produces a file for a expansion interfaces. -type expansionGenerator struct { - generator.DefaultGen - packagePath string - types []*types.Type -} - -// We only want to call GenerateType() once per group. -func (g *expansionGenerator) Filter(c *generator.Context, t *types.Type) bool { - return t == g.types[0] -} - -func (g *expansionGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - for _, t := range g.types { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if _, err := os.Stat(filepath.Join(g.packagePath, strings.ToLower(t.Name.Name+"_expansion.go"))); os.IsNotExist(err) { - sw.Do(expansionInterfaceTemplate, t) - if !tags.NonNamespaced { - sw.Do(namespacedExpansionInterfaceTemplate, t) - } - } - } - return sw.Error() -} - -var expansionInterfaceTemplate = ` -// $.|public$ListerExpansion allows custom methods to be added to -// $.|public$Lister. -type $.|public$ListerExpansion interface {} -` - -var namespacedExpansionInterfaceTemplate = ` -// $.|public$NamespaceListerExpansion allows custom methods to be added to -// $.|public$NamespaceLister. -type $.|public$NamespaceListerExpansion interface {} -` diff --git a/vendor/k8s.io/code-generator/cmd/lister-gen/generators/lister.go b/vendor/k8s.io/code-generator/cmd/lister-gen/generators/lister.go deleted file mode 100644 index 8ada4946..00000000 --- a/vendor/k8s.io/code-generator/cmd/lister-gen/generators/lister.go +++ /dev/null @@ -1,376 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "io" - "path/filepath" - "strings" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/code-generator/cmd/client-gen/generators/util" - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - - "k8s.io/klog/v2" -) - -// NameSystems returns the name system used by the generators in this package. -func NameSystems(pluralExceptions map[string]string) namer.NameSystems { - return namer.NameSystems{ - "public": namer.NewPublicNamer(0), - "private": namer.NewPrivateNamer(0), - "raw": namer.NewRawNamer("", nil), - "publicPlural": namer.NewPublicPluralNamer(pluralExceptions), - "allLowercasePlural": namer.NewAllLowercasePluralNamer(pluralExceptions), - "lowercaseSingular": &lowercaseSingularNamer{}, - } -} - -// lowercaseSingularNamer implements Namer -type lowercaseSingularNamer struct{} - -// Name returns t's name in all lowercase. -func (n *lowercaseSingularNamer) Name(t *types.Type) string { - return strings.ToLower(t.Name.Name) -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -// Packages makes the client package definition. -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - var packageList generator.Packages - for _, inputDir := range arguments.InputDirs { - p := context.Universe.Package(inputDir) - - objectMeta, internal, err := objectMetaForPackage(p) - if err != nil { - klog.Fatal(err) - } - if objectMeta == nil { - // no types in this package had genclient - continue - } - - var gv clientgentypes.GroupVersion - var internalGVPkg string - - if internal { - lastSlash := strings.LastIndex(p.Path, "/") - if lastSlash == -1 { - klog.Fatalf("error constructing internal group version for package %q", p.Path) - } - gv.Group = clientgentypes.Group(p.Path[lastSlash+1:]) - internalGVPkg = p.Path - } else { - parts := strings.Split(p.Path, "/") - gv.Group = clientgentypes.Group(parts[len(parts)-2]) - gv.Version = clientgentypes.Version(parts[len(parts)-1]) - - internalGVPkg = strings.Join(parts[0:len(parts)-1], "/") - } - groupPackageName := strings.ToLower(gv.Group.NonEmpty()) - - // If there's a comment of the form "// +groupName=somegroup" or - // "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the - // group when generating. - if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { - gv.Group = clientgentypes.Group(strings.SplitN(override[0], ".", 2)[0]) - } - - var typesToGenerate []*types.Type - for _, t := range p.Types { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if !tags.GenerateClient || !tags.HasVerb("list") || !tags.HasVerb("get") { - continue - } - typesToGenerate = append(typesToGenerate, t) - } - if len(typesToGenerate) == 0 { - continue - } - orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} - typesToGenerate = orderer.OrderTypes(typesToGenerate) - - packagePath := filepath.Join(arguments.OutputPackagePath, groupPackageName, strings.ToLower(gv.Version.NonEmpty())) - packageList = append(packageList, &generator.DefaultPackage{ - PackageName: strings.ToLower(gv.Version.NonEmpty()), - PackagePath: packagePath, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = append(generators, &expansionGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: "expansion_generated", - }, - packagePath: filepath.Join(arguments.OutputBase, packagePath), - types: typesToGenerate, - }) - - for _, t := range typesToGenerate { - generators = append(generators, &listerGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: strings.ToLower(t.Name.Name), - }, - outputPackage: arguments.OutputPackagePath, - groupVersion: gv, - internalGVPkg: internalGVPkg, - typeToGenerate: t, - imports: generator.NewImportTracker(), - objectMeta: objectMeta, - }) - } - return generators - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("get") - }, - }) - } - - return packageList -} - -// objectMetaForPackage returns the type of ObjectMeta used by package p. -func objectMetaForPackage(p *types.Package) (*types.Type, bool, error) { - generatingForPackage := false - for _, t := range p.Types { - // filter out types which don't have genclient. - if !util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)).GenerateClient { - continue - } - generatingForPackage = true - for _, member := range t.Members { - if member.Name == "ObjectMeta" { - return member.Type, isInternal(member), nil - } - } - } - if generatingForPackage { - return nil, false, fmt.Errorf("unable to find ObjectMeta for any types in package %s", p.Path) - } - return nil, false, nil -} - -// isInternal returns true if the tags for a member do not contain a json tag -func isInternal(m types.Member) bool { - return !strings.Contains(m.Tags, "json") -} - -// listerGenerator produces a file of listers for a given GroupVersion and -// type. -type listerGenerator struct { - generator.DefaultGen - outputPackage string - groupVersion clientgentypes.GroupVersion - internalGVPkg string - typeToGenerate *types.Type - imports namer.ImportTracker - objectMeta *types.Type -} - -var _ generator.Generator = &listerGenerator{} - -func (g *listerGenerator) Filter(c *generator.Context, t *types.Type) bool { - return t == g.typeToGenerate -} - -func (g *listerGenerator) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *listerGenerator) Imports(c *generator.Context) (imports []string) { - imports = append(imports, g.imports.ImportLines()...) - imports = append(imports, "k8s.io/apimachinery/pkg/api/errors") - imports = append(imports, "k8s.io/apimachinery/pkg/labels") - // for Indexer - imports = append(imports, "k8s.io/client-go/tools/cache") - return -} - -func (g *listerGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - klog.V(5).Infof("processing type %v", t) - m := map[string]interface{}{ - "Resource": c.Universe.Function(types.Name{Package: t.Name.Package, Name: "Resource"}), - "type": t, - "objectMeta": g.objectMeta, - } - - tags, err := util.ParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if err != nil { - return err - } - - if tags.NonNamespaced { - sw.Do(typeListerInterface_NonNamespaced, m) - } else { - sw.Do(typeListerInterface, m) - } - - sw.Do(typeListerStruct, m) - sw.Do(typeListerConstructor, m) - sw.Do(typeLister_List, m) - - if tags.NonNamespaced { - sw.Do(typeLister_NonNamespacedGet, m) - return sw.Error() - } - - sw.Do(typeLister_NamespaceLister, m) - sw.Do(namespaceListerInterface, m) - sw.Do(namespaceListerStruct, m) - sw.Do(namespaceLister_List, m) - sw.Do(namespaceLister_Get, m) - - return sw.Error() -} - -var typeListerInterface = ` -// $.type|public$Lister helps list $.type|publicPlural$. -// All objects returned here must be treated as read-only. -type $.type|public$Lister interface { - // List lists all $.type|publicPlural$ in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*$.type|raw$, err error) - // $.type|publicPlural$ returns an object that can list and get $.type|publicPlural$. - $.type|publicPlural$(namespace string) $.type|public$NamespaceLister - $.type|public$ListerExpansion -} -` - -var typeListerInterface_NonNamespaced = ` -// $.type|public$Lister helps list $.type|publicPlural$. -// All objects returned here must be treated as read-only. -type $.type|public$Lister interface { - // List lists all $.type|publicPlural$ in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*$.type|raw$, err error) - // Get retrieves the $.type|public$ from the index for a given name. - // Objects returned here must be treated as read-only. - Get(name string) (*$.type|raw$, error) - $.type|public$ListerExpansion -} -` - -var typeListerStruct = ` -// $.type|private$Lister implements the $.type|public$Lister interface. -type $.type|private$Lister struct { - indexer cache.Indexer -} -` - -var typeListerConstructor = ` -// New$.type|public$Lister returns a new $.type|public$Lister. -func New$.type|public$Lister(indexer cache.Indexer) $.type|public$Lister { - return &$.type|private$Lister{indexer: indexer} -} -` - -var typeLister_List = ` -// List lists all $.type|publicPlural$ in the indexer. -func (s *$.type|private$Lister) List(selector labels.Selector) (ret []*$.type|raw$, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*$.type|raw$)) - }) - return ret, err -} -` - -var typeLister_NamespaceLister = ` -// $.type|publicPlural$ returns an object that can list and get $.type|publicPlural$. -func (s *$.type|private$Lister) $.type|publicPlural$(namespace string) $.type|public$NamespaceLister { - return $.type|private$NamespaceLister{indexer: s.indexer, namespace: namespace} -} -` - -var typeLister_NonNamespacedGet = ` -// Get retrieves the $.type|public$ from the index for a given name. -func (s *$.type|private$Lister) Get(name string) (*$.type|raw$, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound($.Resource|raw$("$.type|lowercaseSingular$"), name) - } - return obj.(*$.type|raw$), nil -} -` - -var namespaceListerInterface = ` -// $.type|public$NamespaceLister helps list and get $.type|publicPlural$. -// All objects returned here must be treated as read-only. -type $.type|public$NamespaceLister interface { - // List lists all $.type|publicPlural$ in the indexer for a given namespace. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*$.type|raw$, err error) - // Get retrieves the $.type|public$ from the indexer for a given namespace and name. - // Objects returned here must be treated as read-only. - Get(name string) (*$.type|raw$, error) - $.type|public$NamespaceListerExpansion -} -` - -var namespaceListerStruct = ` -// $.type|private$NamespaceLister implements the $.type|public$NamespaceLister -// interface. -type $.type|private$NamespaceLister struct { - indexer cache.Indexer - namespace string -} -` - -var namespaceLister_List = ` -// List lists all $.type|publicPlural$ in the indexer for a given namespace. -func (s $.type|private$NamespaceLister) List(selector labels.Selector) (ret []*$.type|raw$, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*$.type|raw$)) - }) - return ret, err -} -` - -var namespaceLister_Get = ` -// Get retrieves the $.type|public$ from the indexer for a given namespace and name. -func (s $.type|private$NamespaceLister) Get(name string) (*$.type|raw$, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound($.Resource|raw$("$.type|lowercaseSingular$"), name) - } - return obj.(*$.type|raw$), nil -} -` diff --git a/vendor/k8s.io/code-generator/cmd/lister-gen/main.go b/vendor/k8s.io/code-generator/cmd/lister-gen/main.go deleted file mode 100644 index a7d7b610..00000000 --- a/vendor/k8s.io/code-generator/cmd/lister-gen/main.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package main - -import ( - "flag" - - "github.com/spf13/pflag" - "k8s.io/code-generator/cmd/lister-gen/generators" - "k8s.io/code-generator/pkg/util" - "k8s.io/klog/v2" - - generatorargs "k8s.io/code-generator/cmd/lister-gen/args" -) - -func main() { - klog.InitFlags(nil) - genericArgs, customArgs := generatorargs.NewDefaults() - - // Override defaults. - // TODO: move this out of lister-gen - genericArgs.OutputPackagePath = "k8s.io/kubernetes/pkg/client/listers" - - genericArgs.AddFlags(pflag.CommandLine) - customArgs.AddFlags(pflag.CommandLine) - flag.Set("logtostderr", "true") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - if err := generatorargs.Validate(genericArgs); err != nil { - klog.Fatalf("Error: %v", err) - } - - // Run it. - if err := genericArgs.Execute( - generators.NameSystems(util.PluralExceptionListToMapOrDie(customArgs.PluralExceptions)), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Fatalf("Error: %v", err) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/cmd/openapi-gen/main.go b/vendor/k8s.io/code-generator/cmd/openapi-gen/main.go deleted file mode 100644 index c446e80b..00000000 --- a/vendor/k8s.io/code-generator/cmd/openapi-gen/main.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -// This package generates openAPI definition file to be used in open API spec generation on API servers. To generate -// definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines. To -// exclude a type from a tagged package, add "+k8s:openapi-gen=false" tag to the type comment lines. - -package main - -import ( - "flag" - "log" - - generatorargs "k8s.io/kube-openapi/cmd/openapi-gen/args" - "k8s.io/kube-openapi/pkg/generators" - - "github.com/spf13/pflag" - - "k8s.io/klog/v2" -) - -func main() { - klog.InitFlags(nil) - genericArgs, customArgs := generatorargs.NewDefaults() - - genericArgs.AddFlags(pflag.CommandLine) - customArgs.AddFlags(pflag.CommandLine) - flag.Set("logtostderr", "true") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - if err := generatorargs.Validate(genericArgs); err != nil { - log.Fatalf("Arguments validation error: %v", err) - } - - // Generates the code for the OpenAPIDefinitions. - if err := genericArgs.Execute( - generators.NameSystems(), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - log.Fatalf("OpenAPI code generation error: %v", err) - } -} diff --git a/vendor/k8s.io/code-generator/cmd/register-gen/generators/packages.go b/vendor/k8s.io/code-generator/cmd/register-gen/generators/packages.go deleted file mode 100644 index fa8e3f1c..00000000 --- a/vendor/k8s.io/code-generator/cmd/register-gen/generators/packages.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "os" - "path" - "strings" - - "k8s.io/klog/v2" - - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// NameSystems returns the name system used by the generators in this package. -func NameSystems() namer.NameSystems { - return namer.NameSystems{} -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -// Packages makes packages to generate. -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - packages := generator.Packages{} - for _, inputDir := range arguments.InputDirs { - pkg := context.Universe.Package(inputDir) - internal, err := isInternal(pkg) - if err != nil { - klog.V(5).Infof("skipping the generation of %s file, due to err %v", arguments.OutputFileBaseName, err) - continue - } - if internal { - klog.V(5).Infof("skipping the generation of %s file because %s package contains internal types, note that internal types don't have \"json\" tags", arguments.OutputFileBaseName, pkg.Name) - continue - } - registerFileName := "register.go" - searchPath := path.Join(args.DefaultSourceTree(), inputDir, registerFileName) - if _, err := os.Stat(path.Join(searchPath)); err == nil { - klog.V(5).Infof("skipping the generation of %s file because %s already exists in the path %s", arguments.OutputFileBaseName, registerFileName, searchPath) - continue - } else if err != nil && !os.IsNotExist(err) { - klog.Fatalf("an error %v has occurred while checking if %s exists", err, registerFileName) - } - - gv := clientgentypes.GroupVersion{} - { - pathParts := strings.Split(pkg.Path, "/") - if len(pathParts) < 2 { - klog.Errorf("the path of the package must contain the group name and the version, path = %s", pkg.Path) - continue - } - gv.Group = clientgentypes.Group(pathParts[len(pathParts)-2]) - gv.Version = clientgentypes.Version(pathParts[len(pathParts)-1]) - - // if there is a comment of the form "// +groupName=somegroup" or "// +groupName=somegroup.foo.bar.io", - // extract the fully qualified API group name from it and overwrite the group inferred from the package path - if override := types.ExtractCommentTags("+", pkg.Comments)["groupName"]; override != nil { - groupName := override[0] - klog.V(5).Infof("overriding the group name with = %s", groupName) - gv.Group = clientgentypes.Group(groupName) - } - } - - typesToRegister := []*types.Type{} - for _, t := range pkg.Types { - klog.V(5).Infof("considering type = %s", t.Name.String()) - for _, typeMember := range t.Members { - if typeMember.Name == "TypeMeta" && typeMember.Embedded { - typesToRegister = append(typesToRegister, t) - } - } - } - - packages = append(packages, - &generator.DefaultPackage{ - PackageName: pkg.Name, - PackagePath: pkg.Path, - HeaderText: boilerplate, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - return []generator.Generator{ - ®isterExternalGenerator{ - DefaultGen: generator.DefaultGen{ - OptionalName: arguments.OutputFileBaseName, - }, - gv: gv, - typesToGenerate: typesToRegister, - outputPackage: pkg.Path, - imports: generator.NewImportTracker(), - }, - } - }, - }) - } - - return packages -} - -// isInternal determines whether the given package -// contains the internal types or not -func isInternal(p *types.Package) (bool, error) { - for _, t := range p.Types { - for _, member := range t.Members { - if member.Name == "TypeMeta" { - return !strings.Contains(member.Tags, "json"), nil - } - } - } - return false, fmt.Errorf("unable to find TypeMeta for any types in package %s", p.Path) -} diff --git a/vendor/k8s.io/code-generator/cmd/register-gen/generators/register_external.go b/vendor/k8s.io/code-generator/cmd/register-gen/generators/register_external.go deleted file mode 100644 index c831c575..00000000 --- a/vendor/k8s.io/code-generator/cmd/register-gen/generators/register_external.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "io" - "sort" - - clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -type registerExternalGenerator struct { - generator.DefaultGen - outputPackage string - gv clientgentypes.GroupVersion - typesToGenerate []*types.Type - imports namer.ImportTracker -} - -var _ generator.Generator = ®isterExternalGenerator{} - -func (g *registerExternalGenerator) Filter(_ *generator.Context, _ *types.Type) bool { - return false -} - -func (g *registerExternalGenerator) Imports(c *generator.Context) (imports []string) { - return g.imports.ImportLines() -} - -func (g *registerExternalGenerator) Namers(_ *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *registerExternalGenerator) Finalize(context *generator.Context, w io.Writer) error { - typesToGenerateOnlyNames := make([]string, len(g.typesToGenerate)) - for index, typeToGenerate := range g.typesToGenerate { - typesToGenerateOnlyNames[index] = typeToGenerate.Name.Name - } - - // sort the list of types to register, so that the generator produces stable output - sort.Strings(typesToGenerateOnlyNames) - - sw := generator.NewSnippetWriter(w, context, "$", "$") - m := map[string]interface{}{ - "groupName": g.gv.Group, - "version": g.gv.Version, - "types": typesToGenerateOnlyNames, - "addToGroupVersion": context.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "AddToGroupVersion"}), - "groupVersion": context.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "GroupVersion"}), - } - sw.Do(registerExternalTypesTemplate, m) - return sw.Error() -} - -var registerExternalTypesTemplate = ` -// GroupName specifies the group name used to register the objects. -const GroupName = "$.groupName$" - -// GroupVersion specifies the group and the version used to register the objects. -var GroupVersion = $.groupVersion|raw${Group: GroupName, Version: "$.version$"} - -// SchemeGroupVersion is group version used to register these objects -// Deprecated: use GroupVersion instead. -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "$.version$"} - -// Resource takes an unqualified resource and returns a Group qualified GroupResource -func Resource(resource string) schema.GroupResource { - return SchemeGroupVersion.WithResource(resource).GroupResource() -} - -var ( - // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. - SchemeBuilder runtime.SchemeBuilder - localSchemeBuilder = &SchemeBuilder - // Depreciated: use Install instead - AddToScheme = localSchemeBuilder.AddToScheme - Install = localSchemeBuilder.AddToScheme -) - -func init() { - // We only register manually written functions here. The registration of the - // generated functions takes place in the generated files. The separation - // makes the code compile even when the generated files are missing. - localSchemeBuilder.Register(addKnownTypes) -} - -// Adds the list of known types to Scheme. -func addKnownTypes(scheme *runtime.Scheme) error { - scheme.AddKnownTypes(SchemeGroupVersion, - $range .types -$ - &$.${}, - $end$ - ) - // AddToGroupVersion allows the serialization of client types like ListOptions. - $.addToGroupVersion|raw$(scheme, SchemeGroupVersion) - return nil -} -` diff --git a/vendor/k8s.io/code-generator/cmd/register-gen/main.go b/vendor/k8s.io/code-generator/cmd/register-gen/main.go deleted file mode 100644 index dc291444..00000000 --- a/vendor/k8s.io/code-generator/cmd/register-gen/main.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package main - -import ( - "flag" - - "github.com/spf13/pflag" - "k8s.io/klog/v2" - - generatorargs "k8s.io/code-generator/cmd/register-gen/args" - "k8s.io/code-generator/cmd/register-gen/generators" -) - -func main() { - klog.InitFlags(nil) - genericArgs := generatorargs.NewDefaults() - genericArgs.AddFlags(pflag.CommandLine) - flag.Set("logtostderr", "true") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - - pflag.Parse() - if err := generatorargs.Validate(genericArgs); err != nil { - klog.Fatalf("Error: %v", err) - } - - if err := genericArgs.Execute( - generators.NameSystems(), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Fatalf("Error: %v", err) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/cmd/set-gen/.gitignore b/vendor/k8s.io/code-generator/cmd/set-gen/.gitignore deleted file mode 100644 index ffe6458c..00000000 --- a/vendor/k8s.io/code-generator/cmd/set-gen/.gitignore +++ /dev/null @@ -1 +0,0 @@ -set-gen diff --git a/vendor/k8s.io/code-generator/cmd/set-gen/main.go b/vendor/k8s.io/code-generator/cmd/set-gen/main.go deleted file mode 100644 index 0968ce76..00000000 --- a/vendor/k8s.io/code-generator/cmd/set-gen/main.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// set-gen is an example usage of gengo. -// -// Structs in the input directories with the below line in their comments will -// have sets generated for them. -// // +genset -// -// Any builtin type referenced anywhere in the input directories will have a -// set generated for it. -package main - -import ( - "os" - - "k8s.io/gengo/args" - "k8s.io/gengo/examples/set-gen/generators" - - "k8s.io/klog/v2" -) - -func main() { - klog.InitFlags(nil) - arguments := args.Default() - - // Override defaults. - arguments.InputDirs = []string{"k8s.io/kubernetes/pkg/util/sets/types"} - arguments.OutputPackagePath = "k8s.io/apimachinery/pkg/util/sets" - - if err := arguments.Execute( - generators.NameSystems(), - generators.DefaultNameSystem(), - generators.Packages, - ); err != nil { - klog.Errorf("Error: %v", err) - os.Exit(1) - } - klog.V(2).Info("Completed successfully.") -} diff --git a/vendor/k8s.io/code-generator/generate-groups.sh b/vendor/k8s.io/code-generator/generate-groups.sh deleted file mode 100644 index a21d2184..00000000 --- a/vendor/k8s.io/code-generator/generate-groups.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2017 The Kubernetes Authors. -# -# 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. - -set -o errexit -set -o nounset -set -o pipefail - -# generate-groups generates everything for a project with external types only, e.g. a project based -# on CustomResourceDefinitions. - -if [ "$#" -lt 4 ] || [ "${1}" == "--help" ]; then - cat < ... - - the generators comma separated to run (deepcopy,defaulter,applyconfiguration,client,lister,informer). - the output package name (e.g. github.com/example/project/pkg/generated). - the external types dir (e.g. github.com/example/api or github.com/example/project/pkg/apis). - the groups and their versions in the format "groupA:v1,v2 groupB:v1 groupC:v2", relative - to . - ... arbitrary flags passed to all generator binaries. - - -Example: - $(basename "$0") \ - deepcopy,client \ - github.com/example/project/pkg/client \ - github.com/example/project/pkg/apis \ - "foo:v1 bar:v1alpha1,v1beta1" -EOF - exit 0 -fi - -GENS="$1" -OUTPUT_PKG="$2" -APIS_PKG="$3" -GROUPS_WITH_VERSIONS="$4" -shift 4 - -echo "WARNING: $(basename "$0") is deprecated." -echo "WARNING: Please use k8s.io/code-generator/kube_codegen.sh instead." -echo - -if [ "${GENS}" = "all" ] || grep -qw "all" <<<"${GENS}"; then - ALL="applyconfiguration,client,deepcopy,informer,lister" - echo "WARNING: Specifying \"all\" as a generator is deprecated." - echo "WARNING: Please list the specific generators needed." - echo "WARNING: \"all\" is now an alias for \"${ALL}\"; new code generators WILL NOT be added to this set" - echo - GENS="${ALL}" -fi - -INT_APIS_PKG="" -exec "$(dirname "${BASH_SOURCE[0]}")/generate-internal-groups.sh" "${GENS}" "${OUTPUT_PKG}" "${INT_APIS_PKG}" "${APIS_PKG}" "${GROUPS_WITH_VERSIONS}" "$@" diff --git a/vendor/k8s.io/code-generator/generate-internal-groups.sh b/vendor/k8s.io/code-generator/generate-internal-groups.sh deleted file mode 100644 index 9676fac3..00000000 --- a/vendor/k8s.io/code-generator/generate-internal-groups.sh +++ /dev/null @@ -1,272 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2017 The Kubernetes Authors. -# -# 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. - -set -o errexit -set -o nounset -set -o pipefail - -# generate-internal-groups generates everything for a project with internal types, e.g. an -# user-provided API server based on k8s.io/apiserver. - -if [ "$#" -lt 5 ] || [ "${1}" == "--help" ]; then - cat < ... - - the generators comma separated to run (applyconfiguration,client,conversion,deepcopy,defaulter,informer,lister,openapi). - the output package name (e.g. github.com/example/project/pkg/generated). - the internal types dir (e.g. github.com/example/project/pkg/apis) or "" if none. - the external types dir (e.g. github.com/example/project/pkg/apis or githubcom/example/apis). - the groups and their versions in the format "groupA:v1,v2 groupB:v1 groupC:v2", relative - to . - ... arbitrary flags passed to all generator binaries. - -Example: - $(basename "$0") \ - deepcopy,defaulter,conversion \ - github.com/example/project/pkg/client \ - github.com/example/project/pkg/apis \ - github.com/example/project/apis \ - "foo:v1 bar:v1alpha1,v1beta1" -EOF - exit 0 -fi - -GENS="$1" -OUTPUT_PKG="$2" -INT_APIS_PKG="$3" -EXT_APIS_PKG="$4" -GROUPS_WITH_VERSIONS="$5" -shift 5 - -echo "WARNING: $(basename "$0") is deprecated." -echo "WARNING: Please use k8s.io/code-generator/kube_codegen.sh instead." -echo - -if [ "${GENS}" = "all" ] || grep -qw "all" <<<"${GENS}"; then - ALL="client,conversion,deepcopy,defaulter,informer,lister,openapi" - echo "WARNING: Specifying \"all\" as a generator is deprecated." - echo "WARNING: Please list the specific generators needed." - echo "WARNING: \"all\" is now an alias for \"${ALL}\"; new code generators WILL NOT be added to this set" - echo - GENS="${ALL}" -fi - -( - # To support running this script from anywhere, first cd into this directory, - # and then install with forced module mode on and fully qualified name. - cd "$(dirname "${0}")" - BINS=( - applyconfiguration-gen - client-gen - conversion-gen - deepcopy-gen - defaulter-gen - informer-gen - lister-gen - openapi-gen - ) - # Compile all the tools at once - it's slightly faster but also just simpler. - # shellcheck disable=2046 # printf word-splitting is intentional - GO111MODULE=on go install $(printf "k8s.io/code-generator/cmd/%s " "${BINS[@]}") -) - -# Go installs the above commands to get installed in $GOBIN if defined, and $GOPATH/bin otherwise: -GOBIN="$(go env GOBIN)" -gobin="${GOBIN:-$(go env GOPATH)/bin}" - -function git_find() { - # Similar to find but faster and easier to understand. We want to include - # modified and untracked files because this might be running against code - # which is not tracked by git yet. - git ls-files -cmo --exclude-standard "$@" -} - -function git_grep() { - # We want to include modified and untracked files because this might be - # running against code which is not tracked by git yet. - git grep --untracked "$@" -} -function codegen::join() { local IFS="$1"; shift; echo "$*"; } - -# enumerate group versions -ALL_FQ_APIS=() # e.g. k8s.io/kubernetes/pkg/apis/apps k8s.io/api/apps/v1 -EXT_FQ_APIS=() # e.g. k8s.io/api/apps/v1 -GROUP_VERSIONS=() # e.g. apps/v1 -for GVs in ${GROUPS_WITH_VERSIONS}; do - IFS=: read -r G Vs <<<"${GVs}" - - if [ -n "${INT_APIS_PKG}" ]; then - ALL_FQ_APIS+=("${INT_APIS_PKG}/${G}") - fi - - # enumerate versions - for V in ${Vs//,/ }; do - ALL_FQ_APIS+=("${EXT_APIS_PKG}/${G}/${V}") - EXT_FQ_APIS+=("${EXT_APIS_PKG}/${G}/${V}") - GROUP_VERSIONS+=("${G}/${V}") - done -done - -CLIENTSET_PKG="${CLIENTSET_PKG_NAME:-clientset}" -CLIENTSET_NAME="${CLIENTSET_NAME_VERSIONED:-versioned}" - -if grep -qw "deepcopy" <<<"${GENS}"; then - # Nuke existing files - for dir in $(GO111MODULE=on go list -f '{{.Dir}}' "${ALL_FQ_APIS[@]}"); do - pushd "${dir}" >/dev/null - git_find -z ':(glob)**'/zz_generated.deepcopy.go | xargs -0 rm -f - popd >/dev/null - done - - echo "Generating deepcopy funcs" - "${gobin}/deepcopy-gen" \ - --input-dirs "$(codegen::join , "${ALL_FQ_APIS[@]}")" \ - -O zz_generated.deepcopy \ - "$@" -fi - -if grep -qw "defaulter" <<<"${GENS}"; then - # Nuke existing files - for dir in $(GO111MODULE=on go list -f '{{.Dir}}' "${ALL_FQ_APIS[@]}"); do - pushd "${dir}" >/dev/null - git_find -z ':(glob)**'/zz_generated.defaults.go | xargs -0 rm -f - popd >/dev/null - done - - echo "Generating defaulters" - "${gobin}/defaulter-gen" \ - --input-dirs "$(codegen::join , "${EXT_FQ_APIS[@]}")" \ - -O zz_generated.defaults \ - "$@" -fi - -if grep -qw "conversion" <<<"${GENS}"; then - # Nuke existing files - for dir in $(GO111MODULE=on go list -f '{{.Dir}}' "${ALL_FQ_APIS[@]}"); do - pushd "${dir}" >/dev/null - git_find -z ':(glob)**'/zz_generated.conversion.go | xargs -0 rm -f - popd >/dev/null - done - - echo "Generating conversions" - "${gobin}/conversion-gen" \ - --input-dirs "$(codegen::join , "${ALL_FQ_APIS[@]}")" \ - -O zz_generated.conversion \ - "$@" -fi - -if grep -qw "applyconfiguration" <<<"${GENS}"; then - APPLY_CONFIGURATION_PACKAGE="${OUTPUT_PKG}/${APPLYCONFIGURATION_PKG_NAME:-applyconfiguration}" - - # Nuke existing files - root="$(GO111MODULE=on go list -f '{{.Dir}}' "${APPLY_CONFIGURATION_PACKAGE}" 2>/dev/null || true)" - if [ -n "${root}" ]; then - pushd "${root}" >/dev/null - git_grep -l --null \ - -e '^// Code generated by applyconfiguration-gen. DO NOT EDIT.$' \ - ':(glob)**/*.go' \ - | xargs -0 rm -f - popd >/dev/null - fi - - echo "Generating apply configuration for ${GROUPS_WITH_VERSIONS} at ${APPLY_CONFIGURATION_PACKAGE}" - "${gobin}/applyconfiguration-gen" \ - --input-dirs "$(codegen::join , "${EXT_FQ_APIS[@]}")" \ - --output-package "${APPLY_CONFIGURATION_PACKAGE}" \ - "$@" -fi - -if grep -qw "client" <<<"${GENS}"; then - # Nuke existing files - root="$(GO111MODULE=on go list -f '{{.Dir}}' "${OUTPUT_PKG}/${CLIENTSET_PKG}/${CLIENTSET_NAME}" 2>/dev/null || true)" - if [ -n "${root}" ]; then - pushd "${root}" >/dev/null - git_grep -l --null \ - -e '^// Code generated by client-gen. DO NOT EDIT.$' \ - ':(glob)**/*.go' \ - | xargs -0 rm -f - popd >/dev/null - fi - - echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/${CLIENTSET_PKG}" - "${gobin}/client-gen" \ - --clientset-name "${CLIENTSET_NAME}" \ - --input-base "" \ - --input "$(codegen::join , "${EXT_FQ_APIS[@]}")" \ - --output-package "${OUTPUT_PKG}/${CLIENTSET_PKG}" \ - --apply-configuration-package "${APPLY_CONFIGURATION_PACKAGE:-}" \ - "$@" -fi - -if grep -qw "lister" <<<"${GENS}"; then - # Nuke existing files - for gv in "${GROUP_VERSIONS[@]}"; do - root="$(GO111MODULE=on go list -f '{{.Dir}}' "${OUTPUT_PKG}/listers/${gv}" 2>/dev/null || true)" - if [ -n "${root}" ]; then - pushd "${root}" >/dev/null - git_grep -l --null \ - -e '^// Code generated by lister-gen. DO NOT EDIT.$' \ - ':(glob)**/*.go' \ - | xargs -0 rm -f - popd >/dev/null - fi - done - - echo "Generating listers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/listers" - "${gobin}/lister-gen" \ - --input-dirs "$(codegen::join , "${EXT_FQ_APIS[@]}")" \ - --output-package "${OUTPUT_PKG}/listers" \ - "$@" -fi - -if grep -qw "informer" <<<"${GENS}"; then - # Nuke existing files - root="$(GO111MODULE=on go list -f '{{.Dir}}' "${OUTPUT_PKG}/informers/externalversions" 2>/dev/null || true)" - if [ -n "${root}" ]; then - pushd "${root}" >/dev/null - git_grep -l --null \ - -e '^// Code generated by informer-gen. DO NOT EDIT.$' \ - ':(glob)**/*.go' \ - | xargs -0 rm -f - popd >/dev/null - fi - - echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/informers" - "${gobin}/informer-gen" \ - --input-dirs "$(codegen::join , "${EXT_FQ_APIS[@]}")" \ - --versioned-clientset-package "${OUTPUT_PKG}/${CLIENTSET_PKG}/${CLIENTSET_NAME}" \ - --listers-package "${OUTPUT_PKG}/listers" \ - --output-package "${OUTPUT_PKG}/informers" \ - "$@" -fi - -if grep -qw "openapi" <<<"${GENS}"; then - # Nuke existing files - for dir in $(GO111MODULE=on go list -f '{{.Dir}}' "${FQ_APIS[@]}"); do - pushd "${dir}" >/dev/null - git_find -z ':(glob)**'/zz_generated.openapi.go | xargs -0 rm -f - popd >/dev/null - done - - echo "Generating OpenAPI definitions for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/openapi" - declare -a OPENAPI_EXTRA_PACKAGES - "${gobin}/openapi-gen" \ - --input-dirs "$(codegen::join , "${EXT_FQ_APIS[@]}" "${OPENAPI_EXTRA_PACKAGES[@]+"${OPENAPI_EXTRA_PACKAGES[@]}"}")" \ - --input-dirs "k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/runtime,k8s.io/apimachinery/pkg/version" \ - --output-package "${OUTPUT_PKG}/openapi" \ - -O zz_generated.openapi \ - "$@" -fi diff --git a/vendor/k8s.io/code-generator/kube_codegen.sh b/vendor/k8s.io/code-generator/kube_codegen.sh deleted file mode 100644 index 6ded2048..00000000 --- a/vendor/k8s.io/code-generator/kube_codegen.sh +++ /dev/null @@ -1,651 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2023 The Kubernetes Authors. -# -# 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. - -# This presents several functions for packages which want to use kubernetes -# code-generation tools. - -set -o errexit -set -o nounset -set -o pipefail - -KUBE_CODEGEN_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" - -function kube::codegen::internal::git_find() { - # Similar to find but faster and easier to understand. We want to include - # modified and untracked files because this might be running against code - # which is not tracked by git yet. - git ls-files -cmo --exclude-standard "$@" -} - -function kube::codegen::internal::git_grep() { - # We want to include modified and untracked files because this might be - # running against code which is not tracked by git yet. - git grep --untracked "$@" -} - -# Generate tagged helper code: conversions, deepcopy, and defaults -# -# Args: -# --input-pkg-root -# The root package under which to search for files which request code to be -# generated. This must be Go package syntax, e.g. "k8s.io/foo/bar". -# -# --output-base -# The root directory under which to emit code. The concatenation of -# + must be valid. -# -# --boilerplate -# An optional override for the header file to insert into generated files. -# -# --extra-peer-dir -# An optional list (this flag may be specified multiple times) of "extra" -# directories to consider during conversion generation. -# -function kube::codegen::gen_helpers() { - local in_pkg_root="" - local out_base="" # gengo needs the output dir must be $out_base/$out_pkg_root - local boilerplate="${KUBE_CODEGEN_ROOT}/hack/boilerplate.go.txt" - local v="${KUBE_VERBOSE:-0}" - local extra_peers=() - - while [ "$#" -gt 0 ]; do - case "$1" in - "--input-pkg-root") - in_pkg_root="$2" - shift 2 - ;; - "--output-base") - out_base="$2" - shift 2 - ;; - "--boilerplate") - boilerplate="$2" - shift 2 - ;; - "--extra-peer-dir") - extra_peers+=("$2") - shift 2 - ;; - *) - echo "unknown argument: $1" >&2 - return 1 - ;; - esac - done - - if [ -z "${in_pkg_root}" ]; then - echo "--input-pkg-root is required" >&2 - return 1 - fi - if [ -z "${out_base}" ]; then - echo "--output-base is required" >&2 - return 1 - fi - - ( - # To support running this from anywhere, first cd into this directory, - # and then install with forced module mode on and fully qualified name. - cd "${KUBE_CODEGEN_ROOT}" - BINS=( - conversion-gen - deepcopy-gen - defaulter-gen - ) - # shellcheck disable=2046 # printf word-splitting is intentional - GO111MODULE=on go install $(printf "k8s.io/code-generator/cmd/%s " "${BINS[@]}") - ) - # Go installs in $GOBIN if defined, and $GOPATH/bin otherwise - gobin="${GOBIN:-$(go env GOPATH)/bin}" - - # These tools all assume out-dir == in-dir. - root="${out_base}/${in_pkg_root}" - mkdir -p "${root}" - root="$(cd "${root}" && pwd -P)" - - # Deepcopy - # - local input_pkgs=() - while read -r file; do - dir="$(dirname "${file}")" - pkg="$(cd "${dir}" && GO111MODULE=on go list -find .)" - input_pkgs+=("${pkg}") - done < <( - ( kube::codegen::internal::git_grep -l \ - -e '+k8s:deepcopy-gen=' \ - ":(glob)${root}"/'**/*.go' \ - || true \ - ) | LC_ALL=C sort -u - ) - - if [ "${#input_pkgs[@]}" != 0 ]; then - echo "Generating deepcopy code for ${#input_pkgs[@]} targets" - - kube::codegen::internal::git_find -z \ - ":(glob)${root}"/'**/zz_generated.deepcopy.go' \ - | xargs -0 rm -f - - local input_args=() - for arg in "${input_pkgs[@]}"; do - input_args+=("--input-dirs" "$arg") - done - "${gobin}/deepcopy-gen" \ - -v "${v}" \ - -O zz_generated.deepcopy \ - --go-header-file "${boilerplate}" \ - --output-base "${out_base}" \ - "${input_args[@]}" - fi - - # Defaults - # - local input_pkgs=() - while read -r file; do - dir="$(dirname "${file}")" - pkg="$(cd "${dir}" && GO111MODULE=on go list -find .)" - input_pkgs+=("${pkg}") - done < <( - ( kube::codegen::internal::git_grep -l \ - -e '+k8s:defaulter-gen=' \ - ":(glob)${root}"/'**/*.go' \ - || true \ - ) | LC_ALL=C sort -u - ) - - if [ "${#input_pkgs[@]}" != 0 ]; then - echo "Generating defaulter code for ${#input_pkgs[@]} targets" - - kube::codegen::internal::git_find -z \ - ":(glob)${root}"/'**/zz_generated.defaults.go' \ - | xargs -0 rm -f - - local input_args=() - for arg in "${input_pkgs[@]}"; do - input_args+=("--input-dirs" "$arg") - done - "${gobin}/defaulter-gen" \ - -v "${v}" \ - -O zz_generated.defaults \ - --go-header-file "${boilerplate}" \ - --output-base "${out_base}" \ - "${input_args[@]}" - fi - - # Conversions - # - local input_pkgs=() - while read -r file; do - dir="$(dirname "${file}")" - pkg="$(cd "${dir}" && GO111MODULE=on go list -find .)" - input_pkgs+=("${pkg}") - done < <( - ( kube::codegen::internal::git_grep -l \ - -e '+k8s:conversion-gen=' \ - ":(glob)${root}"/'**/*.go' \ - || true \ - ) | LC_ALL=C sort -u - ) - - if [ "${#input_pkgs[@]}" != 0 ]; then - echo "Generating conversion code for ${#input_pkgs[@]} targets" - - kube::codegen::internal::git_find -z \ - ":(glob)${root}"/'**/zz_generated.conversion.go' \ - | xargs -0 rm -f - - local input_args=() - for arg in "${input_pkgs[@]}"; do - input_args+=("--input-dirs" "$arg") - done - local extra_peer_args=() - for arg in "${extra_peers[@]:+"${extra_peers[@]}"}"; do - extra_peer_args+=("--extra-peer-dirs" "$arg") - done - "${gobin}/conversion-gen" \ - -v "${v}" \ - -O zz_generated.conversion \ - --go-header-file "${boilerplate}" \ - --output-base "${out_base}" \ - "${extra_peer_args[@]:+"${extra_peer_args[@]}"}" \ - "${input_args[@]}" - fi -} - -# Generate openapi code -# -# Args: -# --input-pkg-root -# The root package under which to search for files which request openapi to -# be generated. This must be Go package syntax, e.g. "k8s.io/foo/bar". -# -# --output-pkg-root -# The root package under which generated directories and files -# will be placed. This must be go package syntax, e.g. "k8s.io/foo/bar". -# -# --output-base -# The root directory under which to emit code. The concatenation of -# + must be valid. -# -# --openapi-name -# An optional override for the leaf name of the generated directory. -# -# --extra-pkgs -# An optional list of additional packages to be imported during openapi -# generation. The argument must be Go package syntax, e.g. -# "k8s.io/foo/bar". It may be a single value or a comma-delimited list. -# This flag may be repeated. -# -# --report-filename -# An optional path at which to write an API violations report. "-" means -# stdout. -# -# --update-report -# If specified, update the report file in place, rather than diffing it. -# -# --boilerplate -# An optional override for the header file to insert into generated files. -# -function kube::codegen::gen_openapi() { - local in_pkg_root="" - local out_pkg_root="" - local out_base="" # gengo needs the output dir must be $out_base/$out_pkg_root - local openapi_subdir="openapi" - local extra_pkgs=() - local report="/dev/null" - local update_report="" - local boilerplate="${KUBE_CODEGEN_ROOT}/hack/boilerplate.go.txt" - local v="${KUBE_VERBOSE:-0}" - - while [ "$#" -gt 0 ]; do - case "$1" in - "--input-pkg-root") - in_pkg_root="$2" - shift 2 - ;; - "--output-pkg-root") - out_pkg_root="$2" - shift 2 - ;; - "--output-base") - out_base="$2" - shift 2 - ;; - "--openapi-name") - openapi_subdir="$2" - shift 2 - ;; - "--extra-pkgs") - extra_pkgs+=("$2") - shift 2 - ;; - "--report-filename") - report="$2" - shift 2 - ;; - "--update-report") - update_report="true" - shift - ;; - "--boilerplate") - boilerplate="$2" - shift 2 - ;; - *) - echo "unknown argument: $1" >&2 - return 1 - ;; - esac - done - - if [ -z "${in_pkg_root}" ]; then - echo "--input-pkg-root is required" >&2 - return 1 - fi - if [ -z "${out_pkg_root}" ]; then - echo "--output-pkg-root is required" >&2 - return 1 - fi - if [ -z "${out_base}" ]; then - echo "--output-base is required" >&2 - return 1 - fi - - local new_report - new_report="$(mktemp -t "$(basename "$0").api_violations.XXXXXX")" - if [ -n "${update_report}" ]; then - new_report="${report}" - fi - - ( - # To support running this from anywhere, first cd into this directory, - # and then install with forced module mode on and fully qualified name. - cd "${KUBE_CODEGEN_ROOT}" - BINS=( - openapi-gen - ) - # shellcheck disable=2046 # printf word-splitting is intentional - GO111MODULE=on go install $(printf "k8s.io/code-generator/cmd/%s " "${BINS[@]}") - ) - # Go installs in $GOBIN if defined, and $GOPATH/bin otherwise - gobin="${GOBIN:-$(go env GOPATH)/bin}" - - # These tools all assume out-dir == in-dir. - root="${out_base}/${in_pkg_root}" - mkdir -p "${root}" - root="$(cd "${root}" && pwd -P)" - - local input_pkgs=( "${extra_pkgs[@]:+"${extra_pkgs[@]}"}") - while read -r file; do - dir="$(dirname "${file}")" - pkg="$(cd "${dir}" && GO111MODULE=on go list -find .)" - input_pkgs+=("${pkg}") - done < <( - ( kube::codegen::internal::git_grep -l \ - -e '+k8s:openapi-gen=' \ - ":(glob)${root}"/'**/*.go' \ - || true \ - ) | LC_ALL=C sort -u - ) - - if [ "${#input_pkgs[@]}" != 0 ]; then - echo "Generating openapi code for ${#input_pkgs[@]} targets" - - kube::codegen::internal::git_find -z \ - ":(glob)${root}"/'**/zz_generated.openapi.go' \ - | xargs -0 rm -f - - local inputs=() - for arg in "${input_pkgs[@]}"; do - inputs+=("--input-dirs" "$arg") - done - "${gobin}/openapi-gen" \ - -v "${v}" \ - -O zz_generated.openapi \ - --go-header-file "${boilerplate}" \ - --output-base "${out_base}" \ - --output-package "${out_pkg_root}/${openapi_subdir}" \ - --report-filename "${new_report}" \ - --input-dirs "k8s.io/apimachinery/pkg/apis/meta/v1" \ - --input-dirs "k8s.io/apimachinery/pkg/runtime" \ - --input-dirs "k8s.io/apimachinery/pkg/version" \ - "${inputs[@]}" - fi - - touch "${report}" # in case it doesn't exist yet - if ! diff -u "${report}" "${new_report}"; then - echo -e "ERROR:" - echo -e "\tAPI rule check failed for ${report}: new reported violations" - echo -e "\tPlease read api/api-rules/README.md" - return 1 - fi -} - -# Generate client code -# -# Args: -# --input-pkg-root -# The root package under which to search for types.go files which request -# clients to be generated. This must be Go package syntax, e.g. -# "k8s.io/foo/bar". -# -# --output-pkg-root -# The root package into which generated directories and files will be -# placed. This must be Go package syntax, e.g. "k8s.io/foo/bar". -# -# --output-base -# The root directory under which to emit code. The concatenation of -# + must be valid. -# -# --boilerplate -# An optional override for the header file to insert into generated files. -# -# --clientset-name -# An optional override for the leaf name of the generated "clientset" directory. -# -# --versioned-name -# An optional override for the leaf name of the generated -# "/versioned" directory. -# -# --with-applyconfig -# Enables generation of applyconfiguration files. -# -# --applyconfig-name -# An optional override for the leaf name of the generated "applyconfiguration" directory. -# -# --with-watch -# Enables generation of listers and informers for APIs which support WATCH. -# -# --listers-name -# An optional override for the leaf name of the generated "listers" directory. -# -# --informers-name -# An optional override for the leaf name of the generated "informers" directory. -# -function kube::codegen::gen_client() { - local in_pkg_root="" - local out_pkg_root="" - local out_base="" # gengo needs the output dir must be $out_base/$out_pkg_root - local clientset_subdir="clientset" - local clientset_versioned_name="versioned" - local applyconfig="false" - local applyconfig_subdir="applyconfiguration" - local watchable="false" - local listers_subdir="listers" - local informers_subdir="informers" - local boilerplate="${KUBE_CODEGEN_ROOT}/hack/boilerplate.go.txt" - local v="${KUBE_VERBOSE:-0}" - - while [ "$#" -gt 0 ]; do - case "$1" in - "--input-pkg-root") - in_pkg_root="$2" - shift 2 - ;; - "--output-pkg-root") - out_pkg_root="$2" - shift 2 - ;; - "--output-base") - out_base="$2" - shift 2 - ;; - "--boilerplate") - boilerplate="$2" - shift 2 - ;; - "--clientset-name") - clientset_subdir="$2" - shift 2 - ;; - "--versioned-name") - clientset_versioned_name="$2" - shift 2 - ;; - "--with-applyconfig") - applyconfig="true" - shift - ;; - "--applyconfig-name") - applyconfig_subdir="$2" - shift 2 - ;; - "--with-watch") - watchable="true" - shift - ;; - "--listers-name") - listers_subdir="$2" - shift 2 - ;; - "--informers-name") - informers_subdir="$2" - shift 2 - ;; - *) - echo "unknown argument: $1" >&2 - return 1 - ;; - esac - done - - if [ -z "${in_pkg_root}" ]; then - echo "--input-pkg-root is required" >&2 - return 1 - fi - if [ -z "${out_pkg_root}" ]; then - echo "--output-pkg-root is required" >&2 - return 1 - fi - if [ -z "${out_base}" ]; then - echo "--output-base is required" >&2 - return 1 - fi - - ( - # To support running this from anywhere, first cd into this directory, - # and then install with forced module mode on and fully qualified name. - cd "${KUBE_CODEGEN_ROOT}" - BINS=( - applyconfiguration-gen - client-gen - informer-gen - lister-gen - ) - # shellcheck disable=2046 # printf word-splitting is intentional - GO111MODULE=on go install $(printf "k8s.io/code-generator/cmd/%s " "${BINS[@]}") - ) - # Go installs in $GOBIN if defined, and $GOPATH/bin otherwise - gobin="${GOBIN:-$(go env GOPATH)/bin}" - - in_root="${out_base}/${in_pkg_root}" - mkdir -p "${in_root}" - in_root="$(cd "${in_root}" && pwd -P)" - out_root="${out_base}/${out_pkg_root}" - mkdir -p "${out_root}" - out_root="$(cd "${out_root}" && pwd -P)" - - local group_versions=() - local input_pkgs=() - while read -r file; do - dir="$(dirname "${file}")" - pkg="$(cd "${dir}" && GO111MODULE=on go list -find .)" - leaf="$(basename "${dir}")" - if grep -E -q '^v[0-9]+((alpha|beta)[0-9]+)?$' <<< "${leaf}"; then - input_pkgs+=("${pkg}") - - dir2="$(dirname "${dir}")" - leaf2="$(basename "${dir2}")" - group_versions+=("${leaf2}/${leaf}") - fi - done < <( - ( kube::codegen::internal::git_grep -l \ - -e '+genclient' \ - ":(glob)${in_root}"/'**/types.go' \ - || true \ - ) | LC_ALL=C sort -u - ) - - if [ "${#group_versions[@]}" == 0 ]; then - return 0 - fi - - applyconfig_pkg="" # set this for later use, iff enabled - if [ "${applyconfig}" == "true" ]; then - applyconfig_pkg="${out_pkg_root}/${applyconfig_subdir}" - - echo "Generating applyconfig code for ${#input_pkgs[@]} targets" - - ( kube::codegen::internal::git_grep -l --null \ - -e '^// Code generated by applyconfiguration-gen. DO NOT EDIT.$' \ - ":(glob)${out_root}/${applyconfig_subdir}"/'**/*.go' \ - || true \ - ) | xargs -0 rm -f - - local inputs=() - for arg in "${input_pkgs[@]}"; do - inputs+=("--input-dirs" "$arg") - done - "${gobin}/applyconfiguration-gen" \ - -v "${v}" \ - --go-header-file "${boilerplate}" \ - --output-base "${out_base}" \ - --output-package "${out_pkg_root}/${applyconfig_subdir}" \ - "${inputs[@]}" - fi - - echo "Generating client code for ${#group_versions[@]} targets" - - ( kube::codegen::internal::git_grep -l --null \ - -e '^// Code generated by client-gen. DO NOT EDIT.$' \ - ":(glob)${out_root}/${clientset_subdir}"/'**/*.go' \ - || true \ - ) | xargs -0 rm -f - - local inputs=() - for arg in "${group_versions[@]}"; do - inputs+=("--input" "$arg") - done - "${gobin}/client-gen" \ - -v "${v}" \ - --go-header-file "${boilerplate}" \ - --clientset-name "${clientset_versioned_name}" \ - --input-base "${in_pkg_root}" \ - --output-base "${out_base}" \ - --output-package "${out_pkg_root}/${clientset_subdir}" \ - --apply-configuration-package "${applyconfig_pkg}" \ - "${inputs[@]}" - - if [ "${watchable}" == "true" ]; then - echo "Generating lister code for ${#input_pkgs[@]} targets" - - ( kube::codegen::internal::git_grep -l --null \ - -e '^// Code generated by lister-gen. DO NOT EDIT.$' \ - ":(glob)${out_root}/${listers_subdir}"/'**/*.go' \ - || true \ - ) | xargs -0 rm -f - - local inputs=() - for arg in "${input_pkgs[@]}"; do - inputs+=("--input-dirs" "$arg") - done - "${gobin}/lister-gen" \ - -v "${v}" \ - --go-header-file "${boilerplate}" \ - --output-base "${out_base}" \ - --output-package "${out_pkg_root}/${listers_subdir}" \ - "${inputs[@]}" - - echo "Generating informer code for ${#input_pkgs[@]} targets" - - ( kube::codegen::internal::git_grep -l --null \ - -e '^// Code generated by informer-gen. DO NOT EDIT.$' \ - ":(glob)${out_root}/${informers_subdir}"/'**/*.go' \ - || true \ - ) | xargs -0 rm -f - - local inputs=() - for arg in "${input_pkgs[@]}"; do - inputs+=("--input-dirs" "$arg") - done - "${gobin}/informer-gen" \ - -v "${v}" \ - --go-header-file "${boilerplate}" \ - --output-base "${out_base}" \ - --output-package "${out_pkg_root}/${informers_subdir}" \ - --versioned-clientset-package "${out_pkg_root}/${clientset_subdir}/${clientset_versioned_name}" \ - --listers-package "${out_pkg_root}/${listers_subdir}" \ - "${inputs[@]}" - fi -} diff --git a/vendor/k8s.io/code-generator/pkg/namer/tag-override.go b/vendor/k8s.io/code-generator/pkg/namer/tag-override.go deleted file mode 100644 index fd8c3a85..00000000 --- a/vendor/k8s.io/code-generator/pkg/namer/tag-override.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package namer - -import ( - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// TagOverrideNamer is a namer which pulls names from a given tag, if specified, -// and otherwise falls back to a different namer. -type TagOverrideNamer struct { - tagName string - fallback namer.Namer -} - -// Name returns the tag value if it exists. It no tag was found the fallback namer will be used -func (n *TagOverrideNamer) Name(t *types.Type) string { - if nameOverride := extractTag(n.tagName, append(t.SecondClosestCommentLines, t.CommentLines...)); nameOverride != "" { - return nameOverride - } - - return n.fallback.Name(t) -} - -// NewTagOverrideNamer creates a namer.Namer which uses the contents of the given tag as -// the name, or falls back to another Namer if the tag is not present. -func NewTagOverrideNamer(tagName string, fallback namer.Namer) namer.Namer { - return &TagOverrideNamer{ - tagName: tagName, - fallback: fallback, - } -} - -// extractTag gets the comment-tags for the key. If the tag did not exist, it -// returns the empty string. -func extractTag(key string, lines []string) string { - val, present := types.ExtractCommentTags("+", lines)[key] - if !present || len(val) < 1 { - return "" - } - - return val[0] -} diff --git a/vendor/k8s.io/code-generator/pkg/util/build.go b/vendor/k8s.io/code-generator/pkg/util/build.go deleted file mode 100644 index 53f93afe..00000000 --- a/vendor/k8s.io/code-generator/pkg/util/build.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package util - -import ( - gobuild "go/build" - "path/filepath" - "strings" -) - -// CurrentPackage returns the go package of the current directory, or "" if it cannot -// be derived from the GOPATH. -func CurrentPackage() string { - for _, root := range gobuild.Default.SrcDirs() { - if pkg, ok := hasSubdir(root, "."); ok { - return pkg - } - } - return "" -} - -func hasSubdir(root, dir string) (rel string, ok bool) { - // ensure a tailing separator to properly compare on word-boundaries - const sep = string(filepath.Separator) - root = filepath.Clean(root) - if !strings.HasSuffix(root, sep) { - root += sep - } - - // check whether root dir starts with root - dir = filepath.Clean(dir) - if !strings.HasPrefix(dir, root) { - return "", false - } - - // cut off root - return filepath.ToSlash(dir[len(root):]), true -} - -// Vendorless trims vendor prefix from a package path to make it canonical -func Vendorless(p string) string { - if pos := strings.LastIndex(p, "/vendor/"); pos != -1 { - return p[pos+len("/vendor/"):] - } - return p -} diff --git a/vendor/k8s.io/code-generator/pkg/util/plural_exceptions.go b/vendor/k8s.io/code-generator/pkg/util/plural_exceptions.go deleted file mode 100644 index 73c648d5..00000000 --- a/vendor/k8s.io/code-generator/pkg/util/plural_exceptions.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -package util - -import ( - "fmt" - "strings" -) - -// PluralExceptionListToMapOrDie converts the list in "Type:PluralType" to map[string]string. -// This is used for pluralizer. -// If the format is wrong, this function will panic. -func PluralExceptionListToMapOrDie(pluralExceptions []string) map[string]string { - pluralExceptionMap := make(map[string]string, len(pluralExceptions)) - for i := range pluralExceptions { - parts := strings.Split(pluralExceptions[i], ":") - if len(parts) != 2 { - panic(fmt.Sprintf("invalid plural exception definition: %s", pluralExceptions[i])) - } - pluralExceptionMap[parts[0]] = parts[1] - } - return pluralExceptionMap -} diff --git a/vendor/k8s.io/code-generator/third_party/forked/golang/LICENSE b/vendor/k8s.io/code-generator/third_party/forked/golang/LICENSE deleted file mode 100644 index 6a66aea5..00000000 --- a/vendor/k8s.io/code-generator/third_party/forked/golang/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/k8s.io/code-generator/third_party/forked/golang/PATENTS b/vendor/k8s.io/code-generator/third_party/forked/golang/PATENTS deleted file mode 100644 index 73309904..00000000 --- a/vendor/k8s.io/code-generator/third_party/forked/golang/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/k8s.io/code-generator/third_party/forked/golang/reflect/type.go b/vendor/k8s.io/code-generator/third_party/forked/golang/reflect/type.go deleted file mode 100644 index 67957ee3..00000000 --- a/vendor/k8s.io/code-generator/third_party/forked/golang/reflect/type.go +++ /dev/null @@ -1,91 +0,0 @@ -//This package is copied from Go library reflect/type.go. -//The struct tag library provides no way to extract the list of struct tags, only -//a specific tag -package reflect - -import ( - "fmt" - - "strconv" - "strings" -) - -type StructTag struct { - Name string - Value string -} - -func (t StructTag) String() string { - return fmt.Sprintf("%s:%q", t.Name, t.Value) -} - -type StructTags []StructTag - -func (tags StructTags) String() string { - s := make([]string, 0, len(tags)) - for _, tag := range tags { - s = append(s, tag.String()) - } - return "`" + strings.Join(s, " ") + "`" -} - -func (tags StructTags) Has(name string) bool { - for i := range tags { - if tags[i].Name == name { - return true - } - } - return false -} - -// ParseStructTags returns the full set of fields in a struct tag in the order they appear in -// the struct tag. -func ParseStructTags(tag string) (StructTags, error) { - tags := StructTags{} - for tag != "" { - // Skip leading space. - i := 0 - for i < len(tag) && tag[i] == ' ' { - i++ - } - tag = tag[i:] - if tag == "" { - break - } - - // Scan to colon. A space, a quote or a control character is a syntax error. - // Strictly speaking, control chars include the range [0x7f, 0x9f], not just - // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters - // as it is simpler to inspect the tag's bytes than the tag's runes. - i = 0 - for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f { - i++ - } - if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' { - break - } - name := string(tag[:i]) - tag = tag[i+1:] - - // Scan quoted string to find value. - i = 1 - for i < len(tag) && tag[i] != '"' { - if tag[i] == '\\' { - i++ - } - i++ - } - if i >= len(tag) { - break - } - qvalue := string(tag[:i+1]) - tag = tag[i+1:] - - value, err := strconv.Unquote(qvalue) - if err != nil { - return nil, err - } - tags = append(tags, StructTag{Name: name, Value: value}) - } - return tags, nil -} diff --git a/vendor/k8s.io/code-generator/tools.go b/vendor/k8s.io/code-generator/tools.go deleted file mode 100644 index 90b942b0..00000000 --- a/vendor/k8s.io/code-generator/tools.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build tools -// +build tools - -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// This package contains code generation utilities -// This package imports things required by build scripts, to force `go mod` to see them as dependencies -package codegenerator - -import ( - _ "k8s.io/code-generator/cmd/applyconfiguration-gen" - _ "k8s.io/code-generator/cmd/client-gen" - _ "k8s.io/code-generator/cmd/conversion-gen" - _ "k8s.io/code-generator/cmd/deepcopy-gen" - _ "k8s.io/code-generator/cmd/defaulter-gen" - _ "k8s.io/code-generator/cmd/go-to-protobuf" - _ "k8s.io/code-generator/cmd/import-boss" - _ "k8s.io/code-generator/cmd/informer-gen" - _ "k8s.io/code-generator/cmd/lister-gen" - _ "k8s.io/code-generator/cmd/openapi-gen" - _ "k8s.io/code-generator/cmd/register-gen" - _ "k8s.io/code-generator/cmd/set-gen" -) diff --git a/vendor/k8s.io/component-base/config/OWNERS b/vendor/k8s.io/component-base/config/OWNERS new file mode 100644 index 00000000..7243d3cc --- /dev/null +++ b/vendor/k8s.io/component-base/config/OWNERS @@ -0,0 +1,13 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: + - api-approvers +reviewers: + - api-reviewers +labels: + - kind/api-change + - sig/api-machinery + - sig/scheduling diff --git a/hack/boilerplate/boilerplate.generatego.txt b/vendor/k8s.io/component-base/config/doc.go similarity index 80% rename from hack/boilerplate/boilerplate.generatego.txt rename to vendor/k8s.io/component-base/config/doc.go index 4f8a6acb..dd0a5a53 100644 --- a/hack/boilerplate/boilerplate.generatego.txt +++ b/vendor/k8s.io/component-base/config/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kube Bind Authors. +Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,3 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ +// +k8s:deepcopy-gen=package + +package config // import "k8s.io/component-base/config" diff --git a/vendor/k8s.io/component-base/config/types.go b/vendor/k8s.io/component-base/config/types.go new file mode 100644 index 00000000..e1b9469d --- /dev/null +++ b/vendor/k8s.io/component-base/config/types.go @@ -0,0 +1,80 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package config + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ClientConnectionConfiguration contains details for constructing a client. +type ClientConnectionConfiguration struct { + // kubeconfig is the path to a KubeConfig file. + Kubeconfig string + // acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the + // default value of 'application/json'. This field will control all connections to the server used by a particular + // client. + AcceptContentTypes string + // contentType is the content type used when sending data to the server from this client. + ContentType string + // qps controls the number of queries per second allowed for this connection. + QPS float32 + // burst allows extra queries to accumulate when a client is exceeding its rate. + Burst int32 +} + +// LeaderElectionConfiguration defines the configuration of leader election +// clients for components that can run with leader election enabled. +type LeaderElectionConfiguration struct { + // leaderElect enables a leader election client to gain leadership + // before executing the main loop. Enable this when running replicated + // components for high availability. + LeaderElect bool + // leaseDuration is the duration that non-leader candidates will wait + // after observing a leadership renewal until attempting to acquire + // leadership of a led but unrenewed leader slot. This is effectively the + // maximum duration that a leader can be stopped before it is replaced + // by another candidate. This is only applicable if leader election is + // enabled. + LeaseDuration metav1.Duration + // renewDeadline is the interval between attempts by the acting master to + // renew a leadership slot before it stops leading. This must be less + // than or equal to the lease duration. This is only applicable if leader + // election is enabled. + RenewDeadline metav1.Duration + // retryPeriod is the duration the clients should wait between attempting + // acquisition and renewal of a leadership. This is only applicable if + // leader election is enabled. + RetryPeriod metav1.Duration + // resourceLock indicates the resource object type that will be used to lock + // during leader election cycles. + ResourceLock string + // resourceName indicates the name of resource object that will be used to lock + // during leader election cycles. + ResourceName string + // resourceNamespace indicates the namespace of resource object that will be used to lock + // during leader election cycles. + ResourceNamespace string +} + +// DebuggingConfiguration holds configuration for Debugging related features. +type DebuggingConfiguration struct { + // enableProfiling enables profiling via web interface host:port/debug/pprof/ + EnableProfiling bool + // enableContentionProfiling enables block profiling, if + // enableProfiling is true. + EnableContentionProfiling bool +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/conversion.go b/vendor/k8s.io/component-base/config/v1alpha1/conversion.go new file mode 100644 index 00000000..e2951e31 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/conversion.go @@ -0,0 +1,53 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/component-base/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +func Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(in *ClientConnectionConfiguration, out *config.ClientConnectionConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(in, out, s) +} + +func Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(in *config.ClientConnectionConfiguration, out *ClientConnectionConfiguration, s conversion.Scope) error { + return autoConvert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(in, out, s) +} + +func Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(in *DebuggingConfiguration, out *config.DebuggingConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(in, out, s) +} + +func Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(in *config.DebuggingConfiguration, out *DebuggingConfiguration, s conversion.Scope) error { + return autoConvert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(in, out, s) +} + +func Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(in *LeaderElectionConfiguration, out *config.LeaderElectionConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(in, out, s) +} + +func Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in *config.LeaderElectionConfiguration, out *LeaderElectionConfiguration, s conversion.Scope) error { + return autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/defaults.go b/vendor/k8s.io/component-base/config/v1alpha1/defaults.go new file mode 100644 index 00000000..cd7f820e --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/defaults.go @@ -0,0 +1,98 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilpointer "k8s.io/utils/pointer" +) + +// RecommendedDefaultLeaderElectionConfiguration defaults a pointer to a +// LeaderElectionConfiguration struct. This will set the recommended default +// values, but they may be subject to change between API versions. This function +// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` +// function to allow consumers of this type to set whatever defaults for their +// embedded configs. Forcing consumers to use these defaults would be problematic +// as defaulting in the scheme is done as part of the conversion, and there would +// be no easy way to opt-out. Instead, if you want to use this defaulting method +// run it in your wrapper struct of this type in its `SetDefaults_` method. +func RecommendedDefaultLeaderElectionConfiguration(obj *LeaderElectionConfiguration) { + zero := metav1.Duration{} + if obj.LeaseDuration == zero { + obj.LeaseDuration = metav1.Duration{Duration: 15 * time.Second} + } + if obj.RenewDeadline == zero { + obj.RenewDeadline = metav1.Duration{Duration: 10 * time.Second} + } + if obj.RetryPeriod == zero { + obj.RetryPeriod = metav1.Duration{Duration: 2 * time.Second} + } + if obj.ResourceLock == "" { + // TODO(#80289): Figure out how to migrate to LeaseLock at this point. + // This will most probably require going through EndpointsLease first. + obj.ResourceLock = EndpointsResourceLock + } + if obj.LeaderElect == nil { + obj.LeaderElect = utilpointer.BoolPtr(true) + } +} + +// RecommendedDefaultClientConnectionConfiguration defaults a pointer to a +// ClientConnectionConfiguration struct. This will set the recommended default +// values, but they may be subject to change between API versions. This function +// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` +// function to allow consumers of this type to set whatever defaults for their +// embedded configs. Forcing consumers to use these defaults would be problematic +// as defaulting in the scheme is done as part of the conversion, and there would +// be no easy way to opt-out. Instead, if you want to use this defaulting method +// run it in your wrapper struct of this type in its `SetDefaults_` method. +func RecommendedDefaultClientConnectionConfiguration(obj *ClientConnectionConfiguration) { + if len(obj.ContentType) == 0 { + obj.ContentType = "application/vnd.kubernetes.protobuf" + } + if obj.QPS == 0.0 { + obj.QPS = 50.0 + } + if obj.Burst == 0 { + obj.Burst = 100 + } +} + +// RecommendedDebuggingConfiguration defaults profiling and debugging configuration. +// This will set the recommended default +// values, but they may be subject to change between API versions. This function +// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` +// function to allow consumers of this type to set whatever defaults for their +// embedded configs. Forcing consumers to use these defaults would be problematic +// as defaulting in the scheme is done as part of the conversion, and there would +// be no easy way to opt-out. Instead, if you want to use this defaulting method +// run it in your wrapper struct of this type in its `SetDefaults_` method. +func RecommendedDebuggingConfiguration(obj *DebuggingConfiguration) { + if obj.EnableProfiling == nil { + obj.EnableProfiling = utilpointer.BoolPtr(true) // profile debugging is cheap to have exposed and standard on kube binaries + } +} + +// NewRecommendedDebuggingConfiguration returns the current recommended DebuggingConfiguration. +// This may change between releases as recommendations shift. +func NewRecommendedDebuggingConfiguration() *DebuggingConfiguration { + ret := &DebuggingConfiguration{} + RecommendedDebuggingConfiguration(ret) + return ret +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/doc.go b/vendor/k8s.io/component-base/config/v1alpha1/doc.go new file mode 100644 index 00000000..3cd4f429 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/component-base/config + +package v1alpha1 // import "k8s.io/component-base/config/v1alpha1" diff --git a/vendor/k8s.io/component-base/config/v1alpha1/register.go b/vendor/k8s.io/component-base/config/v1alpha1/register.go new file mode 100644 index 00000000..ddc186c9 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/register.go @@ -0,0 +1,31 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder runtime.SchemeBuilder + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) diff --git a/vendor/k8s.io/component-base/config/v1alpha1/types.go b/vendor/k8s.io/component-base/config/v1alpha1/types.go new file mode 100644 index 00000000..3c5f004f --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/types.go @@ -0,0 +1,82 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const EndpointsResourceLock = "endpoints" + +// LeaderElectionConfiguration defines the configuration of leader election +// clients for components that can run with leader election enabled. +type LeaderElectionConfiguration struct { + // leaderElect enables a leader election client to gain leadership + // before executing the main loop. Enable this when running replicated + // components for high availability. + LeaderElect *bool `json:"leaderElect"` + // leaseDuration is the duration that non-leader candidates will wait + // after observing a leadership renewal until attempting to acquire + // leadership of a led but unrenewed leader slot. This is effectively the + // maximum duration that a leader can be stopped before it is replaced + // by another candidate. This is only applicable if leader election is + // enabled. + LeaseDuration metav1.Duration `json:"leaseDuration"` + // renewDeadline is the interval between attempts by the acting master to + // renew a leadership slot before it stops leading. This must be less + // than or equal to the lease duration. This is only applicable if leader + // election is enabled. + RenewDeadline metav1.Duration `json:"renewDeadline"` + // retryPeriod is the duration the clients should wait between attempting + // acquisition and renewal of a leadership. This is only applicable if + // leader election is enabled. + RetryPeriod metav1.Duration `json:"retryPeriod"` + // resourceLock indicates the resource object type that will be used to lock + // during leader election cycles. + ResourceLock string `json:"resourceLock"` + // resourceName indicates the name of resource object that will be used to lock + // during leader election cycles. + ResourceName string `json:"resourceName"` + // resourceName indicates the namespace of resource object that will be used to lock + // during leader election cycles. + ResourceNamespace string `json:"resourceNamespace"` +} + +// DebuggingConfiguration holds configuration for Debugging related features. +type DebuggingConfiguration struct { + // enableProfiling enables profiling via web interface host:port/debug/pprof/ + EnableProfiling *bool `json:"enableProfiling,omitempty"` + // enableContentionProfiling enables block profiling, if + // enableProfiling is true. + EnableContentionProfiling *bool `json:"enableContentionProfiling,omitempty"` +} + +// ClientConnectionConfiguration contains details for constructing a client. +type ClientConnectionConfiguration struct { + // kubeconfig is the path to a KubeConfig file. + Kubeconfig string `json:"kubeconfig"` + // acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the + // default value of 'application/json'. This field will control all connections to the server used by a particular + // client. + AcceptContentTypes string `json:"acceptContentTypes"` + // contentType is the content type used when sending data to the server from this client. + ContentType string `json:"contentType"` + // qps controls the number of queries per second allowed for this connection. + QPS float32 `json:"qps"` + // burst allows extra queries to accumulate when a client is exceeding its rate. + Burst int32 `json:"burst"` +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 00000000..a911bb50 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,133 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/component-base/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddConversionFunc((*config.ClientConnectionConfiguration)(nil), (*ClientConnectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(a.(*config.ClientConnectionConfiguration), b.(*ClientConnectionConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.DebuggingConfiguration)(nil), (*DebuggingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(a.(*config.DebuggingConfiguration), b.(*DebuggingConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.LeaderElectionConfiguration)(nil), (*LeaderElectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(a.(*config.LeaderElectionConfiguration), b.(*LeaderElectionConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*ClientConnectionConfiguration)(nil), (*config.ClientConnectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(a.(*ClientConnectionConfiguration), b.(*config.ClientConnectionConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*DebuggingConfiguration)(nil), (*config.DebuggingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(a.(*DebuggingConfiguration), b.(*config.DebuggingConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*LeaderElectionConfiguration)(nil), (*config.LeaderElectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(a.(*LeaderElectionConfiguration), b.(*config.LeaderElectionConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(in *ClientConnectionConfiguration, out *config.ClientConnectionConfiguration, s conversion.Scope) error { + out.Kubeconfig = in.Kubeconfig + out.AcceptContentTypes = in.AcceptContentTypes + out.ContentType = in.ContentType + out.QPS = in.QPS + out.Burst = in.Burst + return nil +} + +func autoConvert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(in *config.ClientConnectionConfiguration, out *ClientConnectionConfiguration, s conversion.Scope) error { + out.Kubeconfig = in.Kubeconfig + out.AcceptContentTypes = in.AcceptContentTypes + out.ContentType = in.ContentType + out.QPS = in.QPS + out.Burst = in.Burst + return nil +} + +func autoConvert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(in *DebuggingConfiguration, out *config.DebuggingConfiguration, s conversion.Scope) error { + if err := v1.Convert_Pointer_bool_To_bool(&in.EnableProfiling, &out.EnableProfiling, s); err != nil { + return err + } + if err := v1.Convert_Pointer_bool_To_bool(&in.EnableContentionProfiling, &out.EnableContentionProfiling, s); err != nil { + return err + } + return nil +} + +func autoConvert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(in *config.DebuggingConfiguration, out *DebuggingConfiguration, s conversion.Scope) error { + if err := v1.Convert_bool_To_Pointer_bool(&in.EnableProfiling, &out.EnableProfiling, s); err != nil { + return err + } + if err := v1.Convert_bool_To_Pointer_bool(&in.EnableContentionProfiling, &out.EnableContentionProfiling, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(in *LeaderElectionConfiguration, out *config.LeaderElectionConfiguration, s conversion.Scope) error { + if err := v1.Convert_Pointer_bool_To_bool(&in.LeaderElect, &out.LeaderElect, s); err != nil { + return err + } + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod + out.ResourceLock = in.ResourceLock + out.ResourceName = in.ResourceName + out.ResourceNamespace = in.ResourceNamespace + return nil +} + +func autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in *config.LeaderElectionConfiguration, out *LeaderElectionConfiguration, s conversion.Scope) error { + if err := v1.Convert_bool_To_Pointer_bool(&in.LeaderElect, &out.LeaderElect, s); err != nil { + return err + } + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod + out.ResourceLock = in.ResourceLock + out.ResourceName = in.ResourceName + out.ResourceNamespace = in.ResourceNamespace + return nil +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000..92176d99 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,88 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientConnectionConfiguration) DeepCopyInto(out *ClientConnectionConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientConnectionConfiguration. +func (in *ClientConnectionConfiguration) DeepCopy() *ClientConnectionConfiguration { + if in == nil { + return nil + } + out := new(ClientConnectionConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DebuggingConfiguration) DeepCopyInto(out *DebuggingConfiguration) { + *out = *in + if in.EnableProfiling != nil { + in, out := &in.EnableProfiling, &out.EnableProfiling + *out = new(bool) + **out = **in + } + if in.EnableContentionProfiling != nil { + in, out := &in.EnableContentionProfiling, &out.EnableContentionProfiling + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DebuggingConfiguration. +func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration { + if in == nil { + return nil + } + out := new(DebuggingConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderElectionConfiguration) DeepCopyInto(out *LeaderElectionConfiguration) { + *out = *in + if in.LeaderElect != nil { + in, out := &in.LeaderElect, &out.LeaderElect + *out = new(bool) + **out = **in + } + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderElectionConfiguration. +func (in *LeaderElectionConfiguration) DeepCopy() *LeaderElectionConfiguration { + if in == nil { + return nil + } + out := new(LeaderElectionConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go b/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go new file mode 100644 index 00000000..fb0c1f1e --- /dev/null +++ b/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go @@ -0,0 +1,73 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package config + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientConnectionConfiguration) DeepCopyInto(out *ClientConnectionConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientConnectionConfiguration. +func (in *ClientConnectionConfiguration) DeepCopy() *ClientConnectionConfiguration { + if in == nil { + return nil + } + out := new(ClientConnectionConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DebuggingConfiguration) DeepCopyInto(out *DebuggingConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DebuggingConfiguration. +func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration { + if in == nil { + return nil + } + out := new(DebuggingConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderElectionConfiguration) DeepCopyInto(out *LeaderElectionConfiguration) { + *out = *in + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderElectionConfiguration. +func (in *LeaderElectionConfiguration) DeepCopy() *LeaderElectionConfiguration { + if in == nil { + return nil + } + out := new(LeaderElectionConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/gengo/LICENSE b/vendor/k8s.io/gengo/LICENSE deleted file mode 100644 index 00b24011..00000000 --- a/vendor/k8s.io/gengo/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014 The Kubernetes Authors. - - 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. diff --git a/vendor/k8s.io/gengo/args/args.go b/vendor/k8s.io/gengo/args/args.go deleted file mode 100644 index b81ceb93..00000000 --- a/vendor/k8s.io/gengo/args/args.go +++ /dev/null @@ -1,199 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// Package args has common command-line flags for generation programs. -package args - -import ( - "bytes" - goflag "flag" - "fmt" - "io/ioutil" - "os" - "path" - "path/filepath" - "strconv" - "strings" - "time" - - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/parser" - - "github.com/spf13/pflag" -) - -// Default returns a defaulted GeneratorArgs. You may change the defaults -// before calling AddFlags. -func Default() *GeneratorArgs { - return &GeneratorArgs{ - OutputBase: DefaultSourceTree(), - GoHeaderFilePath: filepath.Join(DefaultSourceTree(), "k8s.io/gengo/boilerplate/boilerplate.go.txt"), - GeneratedBuildTag: "ignore_autogenerated", - GeneratedByCommentTemplate: "// Code generated by GENERATOR_NAME. DO NOT EDIT.", - defaultCommandLineFlags: true, - } -} - -// GeneratorArgs has arguments that are passed to generators. -type GeneratorArgs struct { - // Which directories to parse. - InputDirs []string - - // Source tree to write results to. - OutputBase string - - // Package path within the source tree. - OutputPackagePath string - - // Output file name. - OutputFileBaseName string - - // Where to get copyright header text. - GoHeaderFilePath string - - // If GeneratedByCommentTemplate is set, generate a "Code generated by" comment - // below the bloilerplate, of the format defined by this string. - // Any instances of "GENERATOR_NAME" will be replaced with the name of the code generator. - GeneratedByCommentTemplate string - - // If true, only verify, don't write anything. - VerifyOnly bool - - // If true, include *_test.go files - IncludeTestFiles bool - - // GeneratedBuildTag is the tag used to identify code generated by execution - // of this type. Each generator should use a different tag, and different - // groups of generators (external API that depends on Kube generations) should - // keep tags distinct as well. - GeneratedBuildTag string - - // Any custom arguments go here - CustomArgs interface{} - - // If specified, trim the prefix from OutputPackagePath before writing files. - TrimPathPrefix string - - // Whether to use default command line flags - defaultCommandLineFlags bool -} - -// WithoutDefaultFlagParsing disables implicit addition of command line flags and parsing. -func (g *GeneratorArgs) WithoutDefaultFlagParsing() *GeneratorArgs { - g.defaultCommandLineFlags = false - return g -} - -func (g *GeneratorArgs) AddFlags(fs *pflag.FlagSet) { - fs.StringSliceVarP(&g.InputDirs, "input-dirs", "i", g.InputDirs, "Comma-separated list of import paths to get input types from.") - fs.StringVarP(&g.OutputBase, "output-base", "o", g.OutputBase, "Output base; defaults to $GOPATH/src/ or ./ if $GOPATH is not set.") - fs.StringVarP(&g.OutputPackagePath, "output-package", "p", g.OutputPackagePath, "Base package path.") - fs.StringVarP(&g.OutputFileBaseName, "output-file-base", "O", g.OutputFileBaseName, "Base name (without .go suffix) for output files.") - fs.StringVarP(&g.GoHeaderFilePath, "go-header-file", "h", g.GoHeaderFilePath, "File containing boilerplate header text. The string YEAR will be replaced with the current 4-digit year.") - fs.BoolVar(&g.VerifyOnly, "verify-only", g.VerifyOnly, "If true, only verify existing output, do not write anything.") - fs.StringVar(&g.GeneratedBuildTag, "build-tag", g.GeneratedBuildTag, "A Go build tag to use to identify files generated by this command. Should be unique.") - fs.StringVar(&g.TrimPathPrefix, "trim-path-prefix", g.TrimPathPrefix, "If set, trim the specified prefix from --output-package when generating files.") -} - -// LoadGoBoilerplate loads the boilerplate file passed to --go-header-file. -func (g *GeneratorArgs) LoadGoBoilerplate() ([]byte, error) { - b, err := ioutil.ReadFile(g.GoHeaderFilePath) - if err != nil { - return nil, err - } - b = bytes.Replace(b, []byte("YEAR"), []byte(strconv.Itoa(time.Now().UTC().Year())), -1) - - if g.GeneratedByCommentTemplate != "" { - if len(b) != 0 { - b = append(b, byte('\n')) - } - generatorName := path.Base(os.Args[0]) - generatedByComment := strings.Replace(g.GeneratedByCommentTemplate, "GENERATOR_NAME", generatorName, -1) - s := fmt.Sprintf("%s\n\n", generatedByComment) - b = append(b, []byte(s)...) - } - return b, nil -} - -// NewBuilder makes a new parser.Builder and populates it with the input -// directories. -func (g *GeneratorArgs) NewBuilder() (*parser.Builder, error) { - b := parser.New() - - // flag for including *_test.go - b.IncludeTestFiles = g.IncludeTestFiles - - // Ignore all auto-generated files. - b.AddBuildTags(g.GeneratedBuildTag) - - for _, d := range g.InputDirs { - var err error - if strings.HasSuffix(d, "/...") { - err = b.AddDirRecursive(strings.TrimSuffix(d, "/...")) - } else { - err = b.AddDir(d) - } - if err != nil { - return nil, fmt.Errorf("unable to add directory %q: %v", d, err) - } - } - return b, nil -} - -// DefaultSourceTree returns the /src directory of the first entry in $GOPATH. -// If $GOPATH is empty, it returns "./". Useful as a default output location. -func DefaultSourceTree() string { - paths := strings.Split(os.Getenv("GOPATH"), string(filepath.ListSeparator)) - if len(paths) > 0 && len(paths[0]) > 0 { - return filepath.Join(paths[0], "src") - } - return "./" -} - -// Execute implements main(). -// If you don't need any non-default behavior, use as: -// args.Default().Execute(...) -func (g *GeneratorArgs) Execute(nameSystems namer.NameSystems, defaultSystem string, pkgs func(*generator.Context, *GeneratorArgs) generator.Packages) error { - if g.defaultCommandLineFlags { - g.AddFlags(pflag.CommandLine) - pflag.CommandLine.AddGoFlagSet(goflag.CommandLine) - pflag.Parse() - } - - b, err := g.NewBuilder() - if err != nil { - return fmt.Errorf("Failed making a parser: %v", err) - } - - // pass through the flag on whether to include *_test.go files - b.IncludeTestFiles = g.IncludeTestFiles - - c, err := generator.NewContext(b, nameSystems, defaultSystem) - if err != nil { - return fmt.Errorf("Failed making a context: %v", err) - } - - c.TrimPathPrefix = g.TrimPathPrefix - - c.Verify = g.VerifyOnly - packages := pkgs(c, g) - if err := c.ExecutePackages(g.OutputBase, packages); err != nil { - return fmt.Errorf("Failed executing generator: %v", err) - } - - return nil -} diff --git a/vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go b/vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go deleted file mode 100644 index 170f6d7f..00000000 --- a/vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go +++ /dev/null @@ -1,935 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "io" - "path/filepath" - "sort" - "strings" - - "k8s.io/gengo/args" - "k8s.io/gengo/examples/set-gen/sets" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/klog/v2" -) - -// CustomArgs is used tby the go2idl framework to pass args specific to this -// generator. -type CustomArgs struct { - BoundingDirs []string // Only deal with types rooted under these dirs. -} - -// This is the comment tag that carries parameters for deep-copy generation. -const ( - tagEnabledName = "k8s:deepcopy-gen" - interfacesTagName = tagEnabledName + ":interfaces" - interfacesNonPointerTagName = tagEnabledName + ":nonpointer-interfaces" // attach the DeepCopy methods to the -) - -// Known values for the comment tag. -const tagValuePackage = "package" - -// enabledTagValue holds parameters from a tagName tag. -type enabledTagValue struct { - value string - register bool -} - -func extractEnabledTypeTag(t *types.Type) *enabledTagValue { - comments := append(append([]string{}, t.SecondClosestCommentLines...), t.CommentLines...) - return extractEnabledTag(comments) -} - -func extractEnabledTag(comments []string) *enabledTagValue { - tagVals := types.ExtractCommentTags("+", comments)[tagEnabledName] - if tagVals == nil { - // No match for the tag. - return nil - } - // If there are multiple values, abort. - if len(tagVals) > 1 { - klog.Fatalf("Found %d %s tags: %q", len(tagVals), tagEnabledName, tagVals) - } - - // If we got here we are returning something. - tag := &enabledTagValue{} - - // Get the primary value. - parts := strings.Split(tagVals[0], ",") - if len(parts) >= 1 { - tag.value = parts[0] - } - - // Parse extra arguments. - parts = parts[1:] - for i := range parts { - kv := strings.SplitN(parts[i], "=", 2) - k := kv[0] - v := "" - if len(kv) == 2 { - v = kv[1] - } - switch k { - case "register": - if v != "false" { - tag.register = true - } - default: - klog.Fatalf("Unsupported %s param: %q", tagEnabledName, parts[i]) - } - } - return tag -} - -// TODO: This is created only to reduce number of changes in a single PR. -// Remove it and use PublicNamer instead. -func deepCopyNamer() *namer.NameStrategy { - return &namer.NameStrategy{ - Join: func(pre string, in []string, post string) string { - return strings.Join(in, "_") - }, - PrependPackageNames: 1, - } -} - -// NameSystems returns the name system used by the generators in this package. -func NameSystems() namer.NameSystems { - return namer.NameSystems{ - "public": deepCopyNamer(), - "raw": namer.NewRawNamer("", nil), - } -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - inputs := sets.NewString(context.Inputs...) - packages := generator.Packages{} - header := append([]byte(fmt.Sprintf("//go:build !%s\n// +build !%s\n\n", arguments.GeneratedBuildTag, arguments.GeneratedBuildTag)), boilerplate...) - - boundingDirs := []string{} - if customArgs, ok := arguments.CustomArgs.(*CustomArgs); ok { - if customArgs.BoundingDirs == nil { - customArgs.BoundingDirs = context.Inputs - } - for i := range customArgs.BoundingDirs { - // Strip any trailing slashes - they are not exactly "correct" but - // this is friendlier. - boundingDirs = append(boundingDirs, strings.TrimRight(customArgs.BoundingDirs[i], "/")) - } - } - - for i := range inputs { - klog.V(5).Infof("Considering pkg %q", i) - pkg := context.Universe[i] - if pkg == nil { - // If the input had no Go files, for example. - continue - } - - ptag := extractEnabledTag(pkg.Comments) - ptagValue := "" - ptagRegister := false - if ptag != nil { - ptagValue = ptag.value - if ptagValue != tagValuePackage { - klog.Fatalf("Package %v: unsupported %s value: %q", i, tagEnabledName, ptagValue) - } - ptagRegister = ptag.register - klog.V(5).Infof(" tag.value: %q, tag.register: %t", ptagValue, ptagRegister) - } else { - klog.V(5).Infof(" no tag") - } - - // If the pkg-scoped tag says to generate, we can skip scanning types. - pkgNeedsGeneration := (ptagValue == tagValuePackage) - if !pkgNeedsGeneration { - // If the pkg-scoped tag did not exist, scan all types for one that - // explicitly wants generation. Ensure all types that want generation - // can be copied. - var uncopyable []string - for _, t := range pkg.Types { - klog.V(5).Infof(" considering type %q", t.Name.String()) - ttag := extractEnabledTypeTag(t) - if ttag != nil && ttag.value == "true" { - klog.V(5).Infof(" tag=true") - if !copyableType(t) { - uncopyable = append(uncopyable, fmt.Sprintf("%v", t)) - } else { - pkgNeedsGeneration = true - } - } - } - if len(uncopyable) > 0 { - klog.Fatalf("Types requested deepcopy generation but are not copyable: %s", - strings.Join(uncopyable, ", ")) - } - } - - if pkgNeedsGeneration { - klog.V(3).Infof("Package %q needs generation", i) - path := pkg.Path - // if the source path is within a /vendor/ directory (for example, - // k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1), allow - // generation to output to the proper relative path (under vendor). - // Otherwise, the generator will create the file in the wrong location - // in the output directory. - // TODO: build a more fundamental concept in gengo for dealing with modifications - // to vendored packages. - if strings.HasPrefix(pkg.SourcePath, arguments.OutputBase) { - expandedPath := strings.TrimPrefix(pkg.SourcePath, arguments.OutputBase) - if strings.Contains(expandedPath, "/vendor/") { - path = expandedPath - } - } - packages = append(packages, - &generator.DefaultPackage{ - PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0], - PackagePath: path, - HeaderText: header, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - return []generator.Generator{ - NewGenDeepCopy(arguments.OutputFileBaseName, pkg.Path, boundingDirs, (ptagValue == tagValuePackage), ptagRegister), - } - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - return t.Name.Package == pkg.Path - }, - }) - } - } - return packages -} - -// genDeepCopy produces a file with autogenerated deep-copy functions. -type genDeepCopy struct { - generator.DefaultGen - targetPackage string - boundingDirs []string - allTypes bool - registerTypes bool - imports namer.ImportTracker - typesForInit []*types.Type -} - -func NewGenDeepCopy(sanitizedName, targetPackage string, boundingDirs []string, allTypes, registerTypes bool) generator.Generator { - return &genDeepCopy{ - DefaultGen: generator.DefaultGen{ - OptionalName: sanitizedName, - }, - targetPackage: targetPackage, - boundingDirs: boundingDirs, - allTypes: allTypes, - registerTypes: registerTypes, - imports: generator.NewImportTracker(), - typesForInit: make([]*types.Type, 0), - } -} - -func (g *genDeepCopy) Namers(c *generator.Context) namer.NameSystems { - // Have the raw namer for this file track what it imports. - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.targetPackage, g.imports), - } -} - -func (g *genDeepCopy) Filter(c *generator.Context, t *types.Type) bool { - // Filter out types not being processed or not copyable within the package. - enabled := g.allTypes - if !enabled { - ttag := extractEnabledTypeTag(t) - if ttag != nil && ttag.value == "true" { - enabled = true - } - } - if !enabled { - return false - } - if !copyableType(t) { - klog.V(2).Infof("Type %v is not copyable", t) - return false - } - klog.V(4).Infof("Type %v is copyable", t) - g.typesForInit = append(g.typesForInit, t) - return true -} - -func (g *genDeepCopy) copyableAndInBounds(t *types.Type) bool { - if !copyableType(t) { - return false - } - // Only packages within the restricted range can be processed. - if !isRootedUnder(t.Name.Package, g.boundingDirs) { - return false - } - return true -} - -// deepCopyMethod returns the signature of a DeepCopy() method, nil or an error -// if the type does not match. This allows more efficient deep copy -// implementations to be defined by the type's author. The correct signature -// for a type T is: -// func (t T) DeepCopy() T -// or: -// func (t *T) DeepCopy() *T -func deepCopyMethod(t *types.Type) (*types.Signature, error) { - f, found := t.Methods["DeepCopy"] - if !found { - return nil, nil - } - if len(f.Signature.Parameters) != 0 { - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected no parameters", t) - } - if len(f.Signature.Results) != 1 { - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected exactly one result", t) - } - - ptrResult := f.Signature.Results[0].Kind == types.Pointer && f.Signature.Results[0].Elem.Name == t.Name - nonPtrResult := f.Signature.Results[0].Name == t.Name - - if !ptrResult && !nonPtrResult { - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected to return %s or *%s", t, t.Name.Name, t.Name.Name) - } - - ptrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Kind == types.Pointer && f.Signature.Receiver.Elem.Name == t.Name - nonPtrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Name == t.Name - - if ptrRcvr && !ptrResult { - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a *%s result for a *%s receiver", t, t.Name.Name, t.Name.Name) - } - if nonPtrRcvr && !nonPtrResult { - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a %s result for a %s receiver", t, t.Name.Name, t.Name.Name) - } - - return f.Signature, nil -} - -// deepCopyMethodOrDie returns the signatrue of a DeepCopy method, nil or calls klog.Fatalf -// if the type does not match. -func deepCopyMethodOrDie(t *types.Type) *types.Signature { - ret, err := deepCopyMethod(t) - if err != nil { - klog.Fatal(err) - } - return ret -} - -// deepCopyIntoMethod returns the signature of a DeepCopyInto() method, nil or an error -// if the type is wrong. DeepCopyInto allows more efficient deep copy -// implementations to be defined by the type's author. The correct signature -// for a type T is: -// func (t T) DeepCopyInto(t *T) -// or: -// func (t *T) DeepCopyInto(t *T) -func deepCopyIntoMethod(t *types.Type) (*types.Signature, error) { - f, found := t.Methods["DeepCopyInto"] - if !found { - return nil, nil - } - if len(f.Signature.Parameters) != 1 { - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected exactly one parameter", t) - } - if len(f.Signature.Results) != 0 { - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected no result type", t) - } - - ptrParam := f.Signature.Parameters[0].Kind == types.Pointer && f.Signature.Parameters[0].Elem.Name == t.Name - - if !ptrParam { - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected parameter of type *%s", t, t.Name.Name) - } - - ptrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Kind == types.Pointer && f.Signature.Receiver.Elem.Name == t.Name - nonPtrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Name == t.Name - - if !ptrRcvr && !nonPtrRcvr { - // this should never happen - return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a receiver of type %s or *%s", t, t.Name.Name, t.Name.Name) - } - - return f.Signature, nil -} - -// deepCopyIntoMethodOrDie returns the signature of a DeepCopyInto() method, nil or calls klog.Fatalf -// if the type is wrong. -func deepCopyIntoMethodOrDie(t *types.Type) *types.Signature { - ret, err := deepCopyIntoMethod(t) - if err != nil { - klog.Fatal(err) - } - return ret -} - -func isRootedUnder(pkg string, roots []string) bool { - // Add trailing / to avoid false matches, e.g. foo/bar vs foo/barn. This - // assumes that bounding dirs do not have trailing slashes. - pkg = pkg + "/" - for _, root := range roots { - if strings.HasPrefix(pkg, root+"/") { - return true - } - } - return false -} - -func copyableType(t *types.Type) bool { - // If the type opts out of copy-generation, stop. - ttag := extractEnabledTypeTag(t) - if ttag != nil && ttag.value == "false" { - return false - } - - // Filter out private types. - if namer.IsPrivateGoName(t.Name.Name) { - return false - } - - if t.Kind == types.Alias { - // if the underlying built-in is not deepcopy-able, deepcopy is opt-in through definition of custom methods. - // Note that aliases of builtins, maps, slices can have deepcopy methods. - if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil { - return true - } else { - return t.Underlying.Kind != types.Builtin || copyableType(t.Underlying) - } - } - - if t.Kind != types.Struct { - return false - } - - return true -} - -func underlyingType(t *types.Type) *types.Type { - for t.Kind == types.Alias { - t = t.Underlying - } - return t -} - -func (g *genDeepCopy) isOtherPackage(pkg string) bool { - if pkg == g.targetPackage { - return false - } - if strings.HasSuffix(pkg, "\""+g.targetPackage+"\"") { - return false - } - return true -} - -func (g *genDeepCopy) Imports(c *generator.Context) (imports []string) { - importLines := []string{} - for _, singleImport := range g.imports.ImportLines() { - if g.isOtherPackage(singleImport) { - importLines = append(importLines, singleImport) - } - } - return importLines -} - -func argsFromType(ts ...*types.Type) generator.Args { - a := generator.Args{ - "type": ts[0], - } - for i, t := range ts { - a[fmt.Sprintf("type%d", i+1)] = t - } - return a -} - -func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error { - return nil -} - -func (g *genDeepCopy) needsGeneration(t *types.Type) bool { - tag := extractEnabledTypeTag(t) - tv := "" - if tag != nil { - tv = tag.value - if tv != "true" && tv != "false" { - klog.Fatalf("Type %v: unsupported %s value: %q", t, tagEnabledName, tag.value) - } - } - if g.allTypes && tv == "false" { - // The whole package is being generated, but this type has opted out. - klog.V(5).Infof("Not generating for type %v because type opted out", t) - return false - } - if !g.allTypes && tv != "true" { - // The whole package is NOT being generated, and this type has NOT opted in. - klog.V(5).Infof("Not generating for type %v because type did not opt in", t) - return false - } - return true -} - -func extractInterfacesTag(t *types.Type) []string { - var result []string - comments := append(append([]string{}, t.SecondClosestCommentLines...), t.CommentLines...) - values := types.ExtractCommentTags("+", comments)[interfacesTagName] - for _, v := range values { - if len(v) == 0 { - continue - } - intfs := strings.Split(v, ",") - for _, intf := range intfs { - if intf == "" { - continue - } - result = append(result, intf) - } - } - return result -} - -func extractNonPointerInterfaces(t *types.Type) (bool, error) { - comments := append(append([]string{}, t.SecondClosestCommentLines...), t.CommentLines...) - values := types.ExtractCommentTags("+", comments)[interfacesNonPointerTagName] - if len(values) == 0 { - return false, nil - } - result := values[0] == "true" - for _, v := range values { - if v == "true" != result { - return false, fmt.Errorf("contradicting %v value %q found to previous value %v", interfacesNonPointerTagName, v, result) - } - } - return result, nil -} - -func (g *genDeepCopy) deepCopyableInterfacesInner(c *generator.Context, t *types.Type) ([]*types.Type, error) { - if t.Kind != types.Struct { - return nil, nil - } - - intfs := extractInterfacesTag(t) - - var ts []*types.Type - for _, intf := range intfs { - t := types.ParseFullyQualifiedName(intf) - err := c.AddDir(t.Package) - if err != nil { - return nil, err - } - intfT := c.Universe.Type(t) - if intfT == nil { - return nil, fmt.Errorf("unknown type %q in %s tag of type %s", intf, interfacesTagName, intfT) - } - if intfT.Kind != types.Interface { - return nil, fmt.Errorf("type %q in %s tag of type %s is not an interface, but: %q", intf, interfacesTagName, t, intfT.Kind) - } - g.imports.AddType(intfT) - ts = append(ts, intfT) - } - - return ts, nil -} - -// deepCopyableInterfaces returns the interface types to implement and whether they apply to a non-pointer receiver. -func (g *genDeepCopy) deepCopyableInterfaces(c *generator.Context, t *types.Type) ([]*types.Type, bool, error) { - ts, err := g.deepCopyableInterfacesInner(c, t) - if err != nil { - return nil, false, err - } - - set := map[string]*types.Type{} - for _, t := range ts { - set[t.String()] = t - } - - result := []*types.Type{} - for _, t := range set { - result = append(result, t) - } - - TypeSlice(result).Sort() // we need a stable sorting because it determines the order in generation - - nonPointerReceiver, err := extractNonPointerInterfaces(t) - if err != nil { - return nil, false, err - } - - return result, nonPointerReceiver, nil -} - -type TypeSlice []*types.Type - -func (s TypeSlice) Len() int { return len(s) } -func (s TypeSlice) Less(i, j int) bool { return s[i].String() < s[j].String() } -func (s TypeSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s TypeSlice) Sort() { sort.Sort(s) } - -func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - if !g.needsGeneration(t) { - return nil - } - klog.V(5).Infof("Generating deepcopy function for type %v", t) - - sw := generator.NewSnippetWriter(w, c, "$", "$") - args := argsFromType(t) - - if deepCopyIntoMethodOrDie(t) == nil { - sw.Do("// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\n", args) - if isReference(t) { - sw.Do("func (in $.type|raw$) DeepCopyInto(out *$.type|raw$) {\n", args) - sw.Do("{in:=&in\n", nil) - } else { - sw.Do("func (in *$.type|raw$) DeepCopyInto(out *$.type|raw$) {\n", args) - } - if deepCopyMethodOrDie(t) != nil { - if t.Methods["DeepCopy"].Signature.Receiver.Kind == types.Pointer { - sw.Do("clone := in.DeepCopy()\n", nil) - sw.Do("*out = *clone\n", nil) - } else { - sw.Do("*out = in.DeepCopy()\n", nil) - } - sw.Do("return\n", nil) - } else { - g.generateFor(t, sw) - sw.Do("return\n", nil) - } - if isReference(t) { - sw.Do("}\n", nil) - } - sw.Do("}\n\n", nil) - } - - if deepCopyMethodOrDie(t) == nil { - sw.Do("// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new $.type|raw$.\n", args) - if isReference(t) { - sw.Do("func (in $.type|raw$) DeepCopy() $.type|raw$ {\n", args) - } else { - sw.Do("func (in *$.type|raw$) DeepCopy() *$.type|raw$ {\n", args) - } - sw.Do("if in == nil { return nil }\n", nil) - sw.Do("out := new($.type|raw$)\n", args) - sw.Do("in.DeepCopyInto(out)\n", nil) - if isReference(t) { - sw.Do("return *out\n", nil) - } else { - sw.Do("return out\n", nil) - } - sw.Do("}\n\n", nil) - } - - intfs, nonPointerReceiver, err := g.deepCopyableInterfaces(c, t) - if err != nil { - return err - } - for _, intf := range intfs { - sw.Do(fmt.Sprintf("// DeepCopy%s is an autogenerated deepcopy function, copying the receiver, creating a new $.type2|raw$.\n", intf.Name.Name), argsFromType(t, intf)) - if nonPointerReceiver { - sw.Do(fmt.Sprintf("func (in $.type|raw$) DeepCopy%s() $.type2|raw$ {\n", intf.Name.Name), argsFromType(t, intf)) - sw.Do("return *in.DeepCopy()", nil) - sw.Do("}\n\n", nil) - } else { - sw.Do(fmt.Sprintf("func (in *$.type|raw$) DeepCopy%s() $.type2|raw$ {\n", intf.Name.Name), argsFromType(t, intf)) - sw.Do("if c := in.DeepCopy(); c != nil {\n", nil) - sw.Do("return c\n", nil) - sw.Do("}\n", nil) - sw.Do("return nil\n", nil) - sw.Do("}\n\n", nil) - } - } - - return sw.Error() -} - -// isReference return true for pointer, maps, slices and aliases of those. -func isReference(t *types.Type) bool { - if t.Kind == types.Pointer || t.Kind == types.Map || t.Kind == types.Slice { - return true - } - return t.Kind == types.Alias && isReference(underlyingType(t)) -} - -// we use the system of shadowing 'in' and 'out' so that the same code is valid -// at any nesting level. This makes the autogenerator easy to understand, and -// the compiler shouldn't care. -func (g *genDeepCopy) generateFor(t *types.Type, sw *generator.SnippetWriter) { - // derive inner types if t is an alias. We call the do* methods below with the alias type. - // basic rule: generate according to inner type, but construct objects with the alias type. - ut := underlyingType(t) - - var f func(*types.Type, *generator.SnippetWriter) - switch ut.Kind { - case types.Builtin: - f = g.doBuiltin - case types.Map: - f = g.doMap - case types.Slice: - f = g.doSlice - case types.Struct: - f = g.doStruct - case types.Pointer: - f = g.doPointer - case types.Interface: - // interfaces are handled in-line in the other cases - klog.Fatalf("Hit an interface type %v. This should never happen.", t) - case types.Alias: - // can never happen because we branch on the underlying type which is never an alias - klog.Fatalf("Hit an alias type %v. This should never happen.", t) - default: - klog.Fatalf("Hit an unsupported type %v.", t) - } - f(t, sw) -} - -// doBuiltin generates code for a builtin or an alias to a builtin. The generated code is -// is the same for both cases, i.e. it's the code for the underlying type. -func (g *genDeepCopy) doBuiltin(t *types.Type, sw *generator.SnippetWriter) { - if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil { - sw.Do("*out = in.DeepCopy()\n", nil) - return - } - - sw.Do("*out = *in\n", nil) -} - -// doMap generates code for a map or an alias to a map. The generated code is -// is the same for both cases, i.e. it's the code for the underlying type. -func (g *genDeepCopy) doMap(t *types.Type, sw *generator.SnippetWriter) { - ut := underlyingType(t) - uet := underlyingType(ut.Elem) - - if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil { - sw.Do("*out = in.DeepCopy()\n", nil) - return - } - - if !ut.Key.IsAssignable() { - klog.Fatalf("Hit an unsupported type %v for: %v", uet, t) - } - - sw.Do("*out = make($.|raw$, len(*in))\n", t) - sw.Do("for key, val := range *in {\n", nil) - dc, dci := deepCopyMethodOrDie(ut.Elem), deepCopyIntoMethodOrDie(ut.Elem) - switch { - case dc != nil || dci != nil: - // Note: a DeepCopy exists because it is added if DeepCopyInto is manually defined - leftPointer := ut.Elem.Kind == types.Pointer - rightPointer := !isReference(ut.Elem) - if dc != nil { - rightPointer = dc.Results[0].Kind == types.Pointer - } - if leftPointer == rightPointer { - sw.Do("(*out)[key] = val.DeepCopy()\n", nil) - } else if leftPointer { - sw.Do("x := val.DeepCopy()\n", nil) - sw.Do("(*out)[key] = &x\n", nil) - } else { - sw.Do("(*out)[key] = *val.DeepCopy()\n", nil) - } - case ut.Elem.IsAnonymousStruct(): // not uet here because it needs type cast - sw.Do("(*out)[key] = val\n", nil) - case uet.IsAssignable(): - sw.Do("(*out)[key] = val\n", nil) - case uet.Kind == types.Interface: - // Note: do not generate code that won't compile as `DeepCopyinterface{}()` is not a valid function - if uet.Name.Name == "interface{}" { - klog.Fatalf("DeepCopy of %q is unsupported. Instead, use named interfaces with DeepCopy as one of the methods.", uet.Name.Name) - } - sw.Do("if val == nil {(*out)[key]=nil} else {\n", nil) - // Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it - // as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang - // parser does not give us the underlying interface name. So we cannot do any better. - sw.Do(fmt.Sprintf("(*out)[key] = val.DeepCopy%s()\n", uet.Name.Name), nil) - sw.Do("}\n", nil) - case uet.Kind == types.Slice || uet.Kind == types.Map || uet.Kind == types.Pointer: - sw.Do("var outVal $.|raw$\n", uet) - sw.Do("if val == nil { (*out)[key] = nil } else {\n", nil) - sw.Do("in, out := &val, &outVal\n", uet) - g.generateFor(ut.Elem, sw) - sw.Do("}\n", nil) - sw.Do("(*out)[key] = outVal\n", nil) - case uet.Kind == types.Struct: - sw.Do("(*out)[key] = *val.DeepCopy()\n", uet) - default: - klog.Fatalf("Hit an unsupported type %v for %v", uet, t) - } - sw.Do("}\n", nil) -} - -// doSlice generates code for a slice or an alias to a slice. The generated code is -// is the same for both cases, i.e. it's the code for the underlying type. -func (g *genDeepCopy) doSlice(t *types.Type, sw *generator.SnippetWriter) { - ut := underlyingType(t) - uet := underlyingType(ut.Elem) - - if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil { - sw.Do("*out = in.DeepCopy()\n", nil) - return - } - - sw.Do("*out = make($.|raw$, len(*in))\n", t) - if deepCopyMethodOrDie(ut.Elem) != nil || deepCopyIntoMethodOrDie(ut.Elem) != nil { - sw.Do("for i := range *in {\n", nil) - // Note: a DeepCopyInto exists because it is added if DeepCopy is manually defined - sw.Do("(*in)[i].DeepCopyInto(&(*out)[i])\n", nil) - sw.Do("}\n", nil) - } else if uet.Kind == types.Builtin || uet.IsAssignable() { - sw.Do("copy(*out, *in)\n", nil) - } else { - sw.Do("for i := range *in {\n", nil) - if uet.Kind == types.Slice || uet.Kind == types.Map || uet.Kind == types.Pointer || deepCopyMethodOrDie(ut.Elem) != nil || deepCopyIntoMethodOrDie(ut.Elem) != nil { - sw.Do("if (*in)[i] != nil {\n", nil) - sw.Do("in, out := &(*in)[i], &(*out)[i]\n", nil) - g.generateFor(ut.Elem, sw) - sw.Do("}\n", nil) - } else if uet.Kind == types.Interface { - // Note: do not generate code that won't compile as `DeepCopyinterface{}()` is not a valid function - if uet.Name.Name == "interface{}" { - klog.Fatalf("DeepCopy of %q is unsupported. Instead, use named interfaces with DeepCopy as one of the methods.", uet.Name.Name) - } - sw.Do("if (*in)[i] != nil {\n", nil) - // Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it - // as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang - // parser does not give us the underlying interface name. So we cannot do any better. - sw.Do(fmt.Sprintf("(*out)[i] = (*in)[i].DeepCopy%s()\n", uet.Name.Name), nil) - sw.Do("}\n", nil) - } else if uet.Kind == types.Struct { - sw.Do("(*in)[i].DeepCopyInto(&(*out)[i])\n", nil) - } else { - klog.Fatalf("Hit an unsupported type %v for %v", uet, t) - } - sw.Do("}\n", nil) - } -} - -// doStruct generates code for a struct or an alias to a struct. The generated code is -// is the same for both cases, i.e. it's the code for the underlying type. -func (g *genDeepCopy) doStruct(t *types.Type, sw *generator.SnippetWriter) { - ut := underlyingType(t) - - if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil { - sw.Do("*out = in.DeepCopy()\n", nil) - return - } - - // Simple copy covers a lot of cases. - sw.Do("*out = *in\n", nil) - - // Now fix-up fields as needed. - for _, m := range ut.Members { - ft := m.Type - uft := underlyingType(ft) - - args := generator.Args{ - "type": ft, - "kind": ft.Kind, - "name": m.Name, - } - dc, dci := deepCopyMethodOrDie(ft), deepCopyIntoMethodOrDie(ft) - switch { - case dc != nil || dci != nil: - // Note: a DeepCopyInto exists because it is added if DeepCopy is manually defined - leftPointer := ft.Kind == types.Pointer - rightPointer := !isReference(ft) - if dc != nil { - rightPointer = dc.Results[0].Kind == types.Pointer - } - if leftPointer == rightPointer { - sw.Do("out.$.name$ = in.$.name$.DeepCopy()\n", args) - } else if leftPointer { - sw.Do("x := in.$.name$.DeepCopy()\n", args) - sw.Do("out.$.name$ = = &x\n", args) - } else { - sw.Do("in.$.name$.DeepCopyInto(&out.$.name$)\n", args) - } - case uft.Kind == types.Builtin: - // the initial *out = *in was enough - case uft.Kind == types.Map, uft.Kind == types.Slice, uft.Kind == types.Pointer: - // Fixup non-nil reference-semantic types. - sw.Do("if in.$.name$ != nil {\n", args) - sw.Do("in, out := &in.$.name$, &out.$.name$\n", args) - g.generateFor(ft, sw) - sw.Do("}\n", nil) - case uft.Kind == types.Array: - sw.Do("out.$.name$ = in.$.name$\n", args) - case uft.Kind == types.Struct: - if ft.IsAssignable() { - sw.Do("out.$.name$ = in.$.name$\n", args) - } else { - sw.Do("in.$.name$.DeepCopyInto(&out.$.name$)\n", args) - } - case uft.Kind == types.Interface: - // Note: do not generate code that won't compile as `DeepCopyinterface{}()` is not a valid function - if uft.Name.Name == "interface{}" { - klog.Fatalf("DeepCopy of %q is unsupported. Instead, use named interfaces with DeepCopy as one of the methods.", uft.Name.Name) - } - sw.Do("if in.$.name$ != nil {\n", args) - // Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it - // as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang - // parser does not give us the underlying interface name. So we cannot do any better. - sw.Do(fmt.Sprintf("out.$.name$ = in.$.name$.DeepCopy%s()\n", uft.Name.Name), args) - sw.Do("}\n", nil) - default: - klog.Fatalf("Hit an unsupported type %v for %v, from %v", uft, ft, t) - } - } -} - -// doPointer generates code for a pointer or an alias to a pointer. The generated code is -// is the same for both cases, i.e. it's the code for the underlying type. -func (g *genDeepCopy) doPointer(t *types.Type, sw *generator.SnippetWriter) { - ut := underlyingType(t) - uet := underlyingType(ut.Elem) - - dc, dci := deepCopyMethodOrDie(ut.Elem), deepCopyIntoMethodOrDie(ut.Elem) - switch { - case dc != nil || dci != nil: - rightPointer := !isReference(ut.Elem) - if dc != nil { - rightPointer = dc.Results[0].Kind == types.Pointer - } - if rightPointer { - sw.Do("*out = (*in).DeepCopy()\n", nil) - } else { - sw.Do("x := (*in).DeepCopy()\n", nil) - sw.Do("*out = &x\n", nil) - } - case uet.IsAssignable(): - sw.Do("*out = new($.Elem|raw$)\n", ut) - sw.Do("**out = **in", nil) - case uet.Kind == types.Map, uet.Kind == types.Slice, uet.Kind == types.Pointer: - sw.Do("*out = new($.Elem|raw$)\n", ut) - sw.Do("if **in != nil {\n", nil) - sw.Do("in, out := *in, *out\n", nil) - g.generateFor(uet, sw) - sw.Do("}\n", nil) - case uet.Kind == types.Struct: - sw.Do("*out = new($.Elem|raw$)\n", ut) - sw.Do("(*in).DeepCopyInto(*out)\n", nil) - default: - klog.Fatalf("Hit an unsupported type %v for %v", uet, t) - } -} diff --git a/vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go b/vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go deleted file mode 100644 index e9ed41de..00000000 --- a/vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go +++ /dev/null @@ -1,1260 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "path/filepath" - "reflect" - "regexp" - "strconv" - "strings" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/klog/v2" -) - -// CustomArgs is used tby the go2idl framework to pass args specific to this -// generator. -type CustomArgs struct { - ExtraPeerDirs []string // Always consider these as last-ditch possibilities for conversions. -} - -var typeZeroValue = map[string]interface{}{ - "uint": 0., - "uint8": 0., - "uint16": 0., - "uint32": 0., - "uint64": 0., - "int": 0., - "int8": 0., - "int16": 0., - "int32": 0., - "int64": 0., - "byte": 0., - "float64": 0., - "float32": 0., - "bool": false, - "time.Time": "", - "string": "", - "integer": 0., - "number": 0., - "boolean": false, - "[]byte": "", // base64 encoded characters - "interface{}": interface{}(nil), -} - -// These are the comment tags that carry parameters for defaulter generation. -const tagName = "k8s:defaulter-gen" -const inputTagName = "k8s:defaulter-gen-input" -const defaultTagName = "default" - -func extractDefaultTag(comments []string) []string { - return types.ExtractCommentTags("+", comments)[defaultTagName] -} - -func extractTag(comments []string) []string { - return types.ExtractCommentTags("+", comments)[tagName] -} - -func extractInputTag(comments []string) []string { - return types.ExtractCommentTags("+", comments)[inputTagName] -} - -func checkTag(comments []string, require ...string) bool { - values := types.ExtractCommentTags("+", comments)[tagName] - if len(require) == 0 { - return len(values) == 1 && values[0] == "" - } - return reflect.DeepEqual(values, require) -} - -func defaultFnNamer() *namer.NameStrategy { - return &namer.NameStrategy{ - Prefix: "SetDefaults_", - Join: func(pre string, in []string, post string) string { - return pre + strings.Join(in, "_") + post - }, - } -} - -func objectDefaultFnNamer() *namer.NameStrategy { - return &namer.NameStrategy{ - Prefix: "SetObjectDefaults_", - Join: func(pre string, in []string, post string) string { - return pre + strings.Join(in, "_") + post - }, - } -} - -// NameSystems returns the name system used by the generators in this package. -func NameSystems() namer.NameSystems { - return namer.NameSystems{ - "public": namer.NewPublicNamer(1), - "raw": namer.NewRawNamer("", nil), - "defaultfn": defaultFnNamer(), - "objectdefaultfn": objectDefaultFnNamer(), - } -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -// defaults holds the declared defaulting functions for a given type (all defaulting functions -// are expected to be func(1)) -type defaults struct { - // object is the defaulter function for a top level type (typically one with TypeMeta) that - // invokes all child defaulters. May be nil if the object defaulter has not yet been generated. - object *types.Type - // base is a defaulter function defined for a type SetDefaults_Pod which does not invoke all - // child defaults - the base defaulter alone is insufficient to default a type - base *types.Type - // additional is zero or more defaulter functions of the form SetDefaults_Pod_XXXX that can be - // included in the Object defaulter. - additional []*types.Type -} - -// All of the types in conversions map are of type "DeclarationOf" with -// the underlying type being "Func". -type defaulterFuncMap map[*types.Type]defaults - -// Returns all manually-defined defaulting functions in the package. -func getManualDefaultingFunctions(context *generator.Context, pkg *types.Package, manualMap defaulterFuncMap) { - buffer := &bytes.Buffer{} - sw := generator.NewSnippetWriter(buffer, context, "$", "$") - - for _, f := range pkg.Functions { - if f.Underlying == nil || f.Underlying.Kind != types.Func { - klog.Errorf("Malformed function: %#v", f) - continue - } - if f.Underlying.Signature == nil { - klog.Errorf("Function without signature: %#v", f) - continue - } - signature := f.Underlying.Signature - // Check whether the function is defaulting function. - // Note that all of them have signature: - // object: func SetObjectDefaults_inType(*inType) - // base: func SetDefaults_inType(*inType) - // additional: func SetDefaults_inType_Qualifier(*inType) - if signature.Receiver != nil { - continue - } - if len(signature.Parameters) != 1 { - continue - } - if len(signature.Results) != 0 { - continue - } - inType := signature.Parameters[0] - if inType.Kind != types.Pointer { - continue - } - // Check if this is the primary defaulter. - args := defaultingArgsFromType(inType.Elem) - sw.Do("$.inType|defaultfn$", args) - switch { - case f.Name.Name == buffer.String(): - key := inType.Elem - // We might scan the same package twice, and that's OK. - v, ok := manualMap[key] - if ok && v.base != nil && v.base.Name.Package != pkg.Path { - panic(fmt.Sprintf("duplicate static defaulter defined: %#v", key)) - } - v.base = f - manualMap[key] = v - klog.V(6).Infof("found base defaulter function for %s from %s", key.Name, f.Name) - // Is one of the additional defaulters - a top level defaulter on a type that is - // also invoked. - case strings.HasPrefix(f.Name.Name, buffer.String()+"_"): - key := inType.Elem - v, ok := manualMap[key] - if ok { - exists := false - for _, existing := range v.additional { - if existing.Name == f.Name { - exists = true - break - } - } - if exists { - continue - } - } - v.additional = append(v.additional, f) - manualMap[key] = v - klog.V(6).Infof("found additional defaulter function for %s from %s", key.Name, f.Name) - } - buffer.Reset() - sw.Do("$.inType|objectdefaultfn$", args) - if f.Name.Name == buffer.String() { - key := inType.Elem - // We might scan the same package twice, and that's OK. - v, ok := manualMap[key] - if ok && v.base != nil && v.base.Name.Package != pkg.Path { - panic(fmt.Sprintf("duplicate static defaulter defined: %#v", key)) - } - v.object = f - manualMap[key] = v - klog.V(6).Infof("found object defaulter function for %s from %s", key.Name, f.Name) - } - buffer.Reset() - } -} - -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - packages := generator.Packages{} - header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...) - - // Accumulate pre-existing default functions. - // TODO: This is too ad-hoc. We need a better way. - existingDefaulters := defaulterFuncMap{} - - buffer := &bytes.Buffer{} - sw := generator.NewSnippetWriter(buffer, context, "$", "$") - - // We are generating defaults only for packages that are explicitly - // passed as InputDir. - for _, i := range context.Inputs { - klog.V(5).Infof("considering pkg %q", i) - pkg := context.Universe[i] - if pkg == nil { - // If the input had no Go files, for example. - continue - } - // typesPkg is where the types that needs defaulter are defined. - // Sometimes it is different from pkg. For example, kubernetes core/v1 - // types are defined in vendor/k8s.io/api/core/v1, while pkg is at - // pkg/api/v1. - typesPkg := pkg - - // Add defaulting functions. - getManualDefaultingFunctions(context, pkg, existingDefaulters) - - var peerPkgs []string - if customArgs, ok := arguments.CustomArgs.(*CustomArgs); ok { - for _, pkg := range customArgs.ExtraPeerDirs { - if i := strings.Index(pkg, "/vendor/"); i != -1 { - pkg = pkg[i+len("/vendor/"):] - } - peerPkgs = append(peerPkgs, pkg) - } - } - // Make sure our peer-packages are added and fully parsed. - for _, pp := range peerPkgs { - context.AddDir(pp) - getManualDefaultingFunctions(context, context.Universe[pp], existingDefaulters) - } - - typesWith := extractTag(pkg.Comments) - shouldCreateObjectDefaulterFn := func(t *types.Type) bool { - if defaults, ok := existingDefaulters[t]; ok && defaults.object != nil { - // A default generator is defined - baseTypeName := "" - if defaults.base != nil { - baseTypeName = defaults.base.Name.String() - } - klog.V(5).Infof(" an object defaulter already exists as %s", baseTypeName) - return false - } - // opt-out - if checkTag(t.SecondClosestCommentLines, "false") { - return false - } - // opt-in - if checkTag(t.SecondClosestCommentLines, "true") { - return true - } - // For every k8s:defaulter-gen tag at the package level, interpret the value as a - // field name (like TypeMeta, ListMeta, ObjectMeta) and trigger defaulter generation - // for any type with any of the matching field names. Provides a more useful package - // level defaulting than global (because we only need defaulters on a subset of objects - - // usually those with TypeMeta). - if t.Kind == types.Struct && len(typesWith) > 0 { - for _, field := range t.Members { - for _, s := range typesWith { - if field.Name == s { - return true - } - } - } - } - return false - } - - // if the types are not in the same package where the defaulter functions to be generated - inputTags := extractInputTag(pkg.Comments) - if len(inputTags) > 1 { - panic(fmt.Sprintf("there could only be one input tag, got %#v", inputTags)) - } - if len(inputTags) == 1 { - var err error - - inputPath := inputTags[0] - if strings.HasPrefix(inputPath, "./") || strings.HasPrefix(inputPath, "../") { - // this is a relative dir, which will not work under gomodules. - // join with the local package path, but warn - klog.Warningf("relative path %s=%s will not work under gomodule mode; use full package path (as used by 'import') instead", inputTagName, inputPath) - inputPath = filepath.Join(pkg.Path, inputTags[0]) - } - - typesPkg, err = context.AddDirectory(inputPath) - if err != nil { - klog.Fatalf("cannot import package %s", inputPath) - } - // update context.Order to the latest context.Universe - orderer := namer.Orderer{Namer: namer.NewPublicNamer(1)} - context.Order = orderer.OrderUniverse(context.Universe) - } - - newDefaulters := defaulterFuncMap{} - for _, t := range typesPkg.Types { - if !shouldCreateObjectDefaulterFn(t) { - continue - } - if namer.IsPrivateGoName(t.Name.Name) { - // We won't be able to convert to a private type. - klog.V(5).Infof(" found a type %v, but it is a private name", t) - continue - } - - // create a synthetic type we can use during generation - newDefaulters[t] = defaults{} - } - - // only generate defaulters for objects that actually have defined defaulters - // prevents empty defaulters from being registered - for { - promoted := 0 - for t, d := range newDefaulters { - if d.object != nil { - continue - } - if newCallTreeForType(existingDefaulters, newDefaulters).build(t, true) != nil { - args := defaultingArgsFromType(t) - sw.Do("$.inType|objectdefaultfn$", args) - newDefaulters[t] = defaults{ - object: &types.Type{ - Name: types.Name{ - Package: pkg.Path, - Name: buffer.String(), - }, - Kind: types.Func, - }, - } - buffer.Reset() - promoted++ - } - } - if promoted != 0 { - continue - } - - // prune any types that were not used - for t, d := range newDefaulters { - if d.object == nil { - klog.V(6).Infof("did not generate defaulter for %s because no child defaulters were registered", t.Name) - delete(newDefaulters, t) - } - } - break - } - - if len(newDefaulters) == 0 { - klog.V(5).Infof("no defaulters in package %s", pkg.Name) - } - - path := pkg.Path - // if the source path is within a /vendor/ directory (for example, - // k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1), allow - // generation to output to the proper relative path (under vendor). - // Otherwise, the generator will create the file in the wrong location - // in the output directory. - // TODO: build a more fundamental concept in gengo for dealing with modifications - // to vendored packages. - if strings.HasPrefix(pkg.SourcePath, arguments.OutputBase) { - expandedPath := strings.TrimPrefix(pkg.SourcePath, arguments.OutputBase) - if strings.Contains(expandedPath, "/vendor/") { - path = expandedPath - } - } - - packages = append(packages, - &generator.DefaultPackage{ - PackageName: filepath.Base(pkg.Path), - PackagePath: path, - HeaderText: header, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - return []generator.Generator{ - NewGenDefaulter(arguments.OutputFileBaseName, typesPkg.Path, pkg.Path, existingDefaulters, newDefaulters, peerPkgs), - } - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - return t.Name.Package == typesPkg.Path - }, - }) - } - return packages -} - -// callTreeForType contains fields necessary to build a tree for types. -type callTreeForType struct { - existingDefaulters defaulterFuncMap - newDefaulters defaulterFuncMap - currentlyBuildingTypes map[*types.Type]bool -} - -func newCallTreeForType(existingDefaulters, newDefaulters defaulterFuncMap) *callTreeForType { - return &callTreeForType{ - existingDefaulters: existingDefaulters, - newDefaulters: newDefaulters, - currentlyBuildingTypes: make(map[*types.Type]bool), - } -} - -// resolveType follows pointers and aliases of `t` until reaching the first -// non-pointer type in `t's` herarchy -func resolveTypeAndDepth(t *types.Type) (*types.Type, int) { - var prev *types.Type - depth := 0 - for prev != t { - prev = t - if t.Kind == types.Alias { - t = t.Underlying - } else if t.Kind == types.Pointer { - t = t.Elem - depth += 1 - } - } - return t, depth -} - -// getPointerElementPath follows pointers and aliases to returns all -// pointer elements in the path from the given type, to its base value type. -// -// Example: -// -// type MyString string -// type MyStringPointer *MyString -// type MyStringPointerPointer *MyStringPointer -// type MyStringAlias MyStringPointer -// type MyStringAliasPointer *MyStringAlias -// type MyStringAliasDoublePointer **MyStringAlias -// -// t | defaultPointerElementPath(t) -// ---------------------------|---------------------------------------- -// MyString | [] -// MyStringPointer | [MyString] -// MyStringPointerPointer | [MyStringPointer, MyString] -// MyStringAlias | [MyStringPointer, MyString] -// MyStringAliasPointer | [MyStringAlias, MyStringPointer, MyString] -// MyStringAliasDoublePointer | [*MyStringAlias, MyStringAlias, MyStringPointer, MyString] -func getPointerElementPath(t *types.Type) []*types.Type { - var path []*types.Type - for t != nil { - switch t.Kind { - case types.Alias: - t = t.Underlying - case types.Pointer: - t = t.Elem - path = append(path, t) - default: - t = nil - } - } - return path -} - -// getNestedDefault returns the first default value when resolving alias types -func getNestedDefault(t *types.Type) string { - var prev *types.Type - for prev != t { - prev = t - defaultMap := extractDefaultTag(t.CommentLines) - if len(defaultMap) == 1 && defaultMap[0] != "" { - return defaultMap[0] - } - if t.Kind == types.Alias { - t = t.Underlying - } else if t.Kind == types.Pointer { - t = t.Elem - } - } - return "" -} - -func mustEnforceDefault(t *types.Type, depth int, omitEmpty bool) (interface{}, error) { - if depth > 0 { - return nil, nil - } - switch t.Kind { - case types.Pointer, types.Map, types.Slice, types.Array, types.Interface: - return nil, nil - case types.Struct: - return map[string]interface{}{}, nil - case types.Builtin: - if !omitEmpty { - if zero, ok := typeZeroValue[t.String()]; ok { - return zero, nil - } else { - return nil, fmt.Errorf("please add type %v to typeZeroValue struct", t) - } - } - return nil, nil - default: - return nil, fmt.Errorf("not sure how to enforce default for %v", t.Kind) - } -} - -var refRE = regexp.MustCompile(`^ref\((?P[^"]+)\)$`) -var refREIdentIndex = refRE.SubexpIndex("reference") - -// ParseSymbolReference looks for strings that match one of the following: -// - ref(Ident) -// - ref(pkgpath.Ident) -// If the input string matches either of these, it will return the (optional) -// pkgpath, the Ident, and true. Otherwise it will return empty strings and -// false. -func ParseSymbolReference(s, sourcePackage string) (types.Name, bool) { - matches := refRE.FindStringSubmatch(s) - if len(matches) < refREIdentIndex || matches[refREIdentIndex] == "" { - return types.Name{}, false - } - - contents := matches[refREIdentIndex] - name := types.ParseFullyQualifiedName(contents) - if len(name.Package) == 0 { - name.Package = sourcePackage - } - return name, true -} - -func populateDefaultValue(node *callNode, t *types.Type, tags string, commentLines []string, commentPackage string) *callNode { - defaultMap := extractDefaultTag(commentLines) - var defaultString string - if len(defaultMap) == 1 { - defaultString = defaultMap[0] - } else if len(defaultMap) > 1 { - klog.Fatalf("Found more than one default tag for %v", t.Kind) - } - - baseT, depth := resolveTypeAndDepth(t) - if depth > 0 && defaultString == "" { - defaultString = getNestedDefault(t) - } - - if len(defaultString) == 0 { - return node - } - var symbolReference types.Name - var defaultValue interface{} - if id, ok := ParseSymbolReference(defaultString, commentPackage); ok { - symbolReference = id - defaultString = "" - } else if err := json.Unmarshal([]byte(defaultString), &defaultValue); err != nil { - klog.Fatalf("Failed to unmarshal default: %v", err) - } - - omitEmpty := strings.Contains(reflect.StructTag(tags).Get("json"), "omitempty") - if enforced, err := mustEnforceDefault(baseT, depth, omitEmpty); err != nil { - klog.Fatal(err) - } else if enforced != nil { - if defaultValue != nil { - if reflect.DeepEqual(defaultValue, enforced) { - // If the default value annotation matches the default value for the type, - // do not generate any defaulting function - return node - } else { - enforcedJSON, _ := json.Marshal(enforced) - klog.Fatalf("Invalid default value (%#v) for non-pointer/non-omitempty. If specified, must be: %v", defaultValue, string(enforcedJSON)) - } - } - } - - // callNodes are not automatically generated for primitive types. Generate one if the callNode does not exist - if node == nil { - node = &callNode{} - node.markerOnly = true - } - - node.defaultIsPrimitive = baseT.IsPrimitive() - node.defaultType = baseT - node.defaultTopLevelType = t - node.defaultValue.InlineConstant = defaultString - node.defaultValue.SymbolReference = symbolReference - return node -} - -// build creates a tree of paths to fields (based on how they would be accessed in Go - pointer, elem, -// slice, or key) and the functions that should be invoked on each field. An in-order traversal of the resulting tree -// can be used to generate a Go function that invokes each nested function on the appropriate type. The return -// value may be nil if there are no functions to call on type or the type is a primitive (Defaulters can only be -// invoked on structs today). When root is true this function will not use a newDefaulter. existingDefaulters should -// contain all defaulting functions by type defined in code - newDefaulters should contain all object defaulters -// that could be or will be generated. If newDefaulters has an entry for a type, but the 'object' field is nil, -// this function skips adding that defaulter - this allows us to avoid generating object defaulter functions for -// list types that call empty defaulters. -func (c *callTreeForType) build(t *types.Type, root bool) *callNode { - parent := &callNode{} - - if root { - // the root node is always a pointer - parent.elem = true - } - - defaults, _ := c.existingDefaulters[t] - newDefaults, generated := c.newDefaulters[t] - switch { - case !root && generated && newDefaults.object != nil: - parent.call = append(parent.call, newDefaults.object) - // if we will be generating the defaulter, it by definition is a covering - // defaulter, so we halt recursion - klog.V(6).Infof("the defaulter %s will be generated as an object defaulter", t.Name) - return parent - - case defaults.object != nil: - // object defaulters are always covering - parent.call = append(parent.call, defaults.object) - return parent - - case defaults.base != nil: - parent.call = append(parent.call, defaults.base) - // if the base function indicates it "covers" (it already includes defaulters) - // we can halt recursion - if checkTag(defaults.base.CommentLines, "covers") { - klog.V(6).Infof("the defaulter %s indicates it covers all sub generators", t.Name) - return parent - } - } - - // base has been added already, now add any additional defaulters defined for this object - parent.call = append(parent.call, defaults.additional...) - - // if the type already exists, don't build the tree for it and don't generate anything. - // This is used to avoid recursion for nested recursive types. - if c.currentlyBuildingTypes[t] { - return nil - } - // if type doesn't exist, mark it as existing - c.currentlyBuildingTypes[t] = true - - defer func() { - // The type will now acts as a parent, not a nested recursive type. - // We can now build the tree for it safely. - c.currentlyBuildingTypes[t] = false - }() - - switch t.Kind { - case types.Pointer: - if child := c.build(t.Elem, false); child != nil { - child.elem = true - parent.children = append(parent.children, *child) - } - case types.Slice, types.Array: - if child := c.build(t.Elem, false); child != nil { - child.index = true - if t.Elem.Kind == types.Pointer { - child.elem = true - } - parent.children = append(parent.children, *child) - } else if member := populateDefaultValue(nil, t.Elem, "", t.Elem.CommentLines, t.Elem.Name.Package); member != nil { - member.index = true - parent.children = append(parent.children, *member) - } - case types.Map: - if child := c.build(t.Elem, false); child != nil { - child.key = true - parent.children = append(parent.children, *child) - } else if member := populateDefaultValue(nil, t.Elem, "", t.Elem.CommentLines, t.Elem.Name.Package); member != nil { - member.key = true - parent.children = append(parent.children, *member) - } - - case types.Struct: - for _, field := range t.Members { - name := field.Name - if len(name) == 0 { - if field.Type.Kind == types.Pointer { - name = field.Type.Elem.Name.Name - } else { - name = field.Type.Name.Name - } - } - if child := c.build(field.Type, false); child != nil { - child.field = name - populateDefaultValue(child, field.Type, field.Tags, field.CommentLines, field.Type.Name.Package) - parent.children = append(parent.children, *child) - } else if member := populateDefaultValue(nil, field.Type, field.Tags, field.CommentLines, t.Name.Package); member != nil { - member.field = name - parent.children = append(parent.children, *member) - } - } - case types.Alias: - if child := c.build(t.Underlying, false); child != nil { - parent.children = append(parent.children, *child) - } - } - if len(parent.children) == 0 && len(parent.call) == 0 { - //klog.V(6).Infof("decided type %s needs no generation", t.Name) - return nil - } - return parent -} - -const ( - runtimePackagePath = "k8s.io/apimachinery/pkg/runtime" - conversionPackagePath = "k8s.io/apimachinery/pkg/conversion" -) - -// genDefaulter produces a file with a autogenerated conversions. -type genDefaulter struct { - generator.DefaultGen - typesPackage string - outputPackage string - peerPackages []string - newDefaulters defaulterFuncMap - existingDefaulters defaulterFuncMap - imports namer.ImportTracker - typesForInit []*types.Type -} - -func NewGenDefaulter(sanitizedName, typesPackage, outputPackage string, existingDefaulters, newDefaulters defaulterFuncMap, peerPkgs []string) generator.Generator { - return &genDefaulter{ - DefaultGen: generator.DefaultGen{ - OptionalName: sanitizedName, - }, - typesPackage: typesPackage, - outputPackage: outputPackage, - peerPackages: peerPkgs, - newDefaulters: newDefaulters, - existingDefaulters: existingDefaulters, - imports: generator.NewImportTrackerForPackage(outputPackage), - typesForInit: make([]*types.Type, 0), - } -} - -func (g *genDefaulter) Namers(c *generator.Context) namer.NameSystems { - // Have the raw namer for this file track what it imports. - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *genDefaulter) isOtherPackage(pkg string) bool { - if pkg == g.outputPackage { - return false - } - if strings.HasSuffix(pkg, `"`+g.outputPackage+`"`) { - return false - } - return true -} - -func (g *genDefaulter) Filter(c *generator.Context, t *types.Type) bool { - defaults, ok := g.newDefaulters[t] - if !ok || defaults.object == nil { - return false - } - g.typesForInit = append(g.typesForInit, t) - return true -} - -func (g *genDefaulter) Imports(c *generator.Context) (imports []string) { - var importLines []string - for _, singleImport := range g.imports.ImportLines() { - if g.isOtherPackage(singleImport) { - importLines = append(importLines, singleImport) - } - } - return importLines -} - -func (g *genDefaulter) Init(c *generator.Context, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - - scheme := c.Universe.Type(types.Name{Package: runtimePackagePath, Name: "Scheme"}) - schemePtr := &types.Type{ - Kind: types.Pointer, - Elem: scheme, - } - sw.Do("// RegisterDefaults adds defaulters functions to the given scheme.\n", nil) - sw.Do("// Public to allow building arbitrary schemes.\n", nil) - sw.Do("// All generated defaulters are covering - they call all nested defaulters.\n", nil) - sw.Do("func RegisterDefaults(scheme $.|raw$) error {\n", schemePtr) - for _, t := range g.typesForInit { - args := defaultingArgsFromType(t) - sw.Do("scheme.AddTypeDefaultingFunc(&$.inType|raw${}, func(obj interface{}) { $.inType|objectdefaultfn$(obj.(*$.inType|raw$)) })\n", args) - } - sw.Do("return nil\n", nil) - sw.Do("}\n\n", nil) - return sw.Error() -} - -func (g *genDefaulter) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - if _, ok := g.newDefaulters[t]; !ok { - return nil - } - - klog.V(5).Infof("generating for type %v", t) - - callTree := newCallTreeForType(g.existingDefaulters, g.newDefaulters).build(t, true) - if callTree == nil { - klog.V(5).Infof(" no defaulters defined") - return nil - } - i := 0 - callTree.VisitInOrder(func(ancestors []*callNode, current *callNode) { - if ref := ¤t.defaultValue.SymbolReference; len(ref.Name) > 0 { - // Ensure package for symbol is imported in output generation - g.imports.AddSymbol(*ref) - - // Rewrite the fully qualified name using the local package name - // from the imports - ref.Package = g.imports.LocalNameOf(ref.Package) - } - - if len(current.call) == 0 { - return - } - path := callPath(append(ancestors, current)) - klog.V(5).Infof(" %d: %s", i, path) - i++ - }) - - sw := generator.NewSnippetWriter(w, c, "$", "$") - g.generateDefaulter(t, callTree, sw) - return sw.Error() -} - -func defaultingArgsFromType(inType *types.Type) generator.Args { - return generator.Args{ - "inType": inType, - } -} - -func (g *genDefaulter) generateDefaulter(inType *types.Type, callTree *callNode, sw *generator.SnippetWriter) { - sw.Do("func $.inType|objectdefaultfn$(in *$.inType|raw$) {\n", defaultingArgsFromType(inType)) - callTree.WriteMethod("in", 0, nil, sw) - sw.Do("}\n\n", nil) -} - -// callNode represents an entry in a tree of Go type accessors - the path from the root to a leaf represents -// how in Go code an access would be performed. For example, if a defaulting function exists on a container -// lifecycle hook, to invoke that defaulter correctly would require this Go code: -// -// for i := range pod.Spec.Containers { -// o := &pod.Spec.Containers[i] -// if o.LifecycleHook != nil { -// SetDefaults_LifecycleHook(o.LifecycleHook) -// } -// } -// -// That would be represented by a call tree like: -// -// callNode -// field: "Spec" -// children: -// - field: "Containers" -// children: -// - index: true -// children: -// - field: "LifecycleHook" -// elem: true -// call: -// - SetDefaults_LifecycleHook -// -// which we can traverse to build that Go struct (you must call the field Spec, then Containers, then range over -// that field, then check whether the LifecycleHook field is nil, before calling SetDefaults_LifecycleHook on -// the pointer to that field). -type callNode struct { - // field is the name of the Go member to access - field string - // key is true if this is a map and we must range over the key and values - key bool - // index is true if this is a slice and we must range over the slice values - index bool - // elem is true if the previous elements refer to a pointer (typically just field) - elem bool - - // call is all of the functions that must be invoked on this particular node, in order - call []*types.Type - // children is the child call nodes that must also be traversed - children []callNode - - // defaultValue is the defaultValue of a callNode struct - // Only primitive types and pointer types are eligible to have a default value - defaultValue defaultValue - - // defaultIsPrimitive is used to determine how to assign the default value. - // Primitive types will be directly assigned while complex types will use JSON unmarshalling - defaultIsPrimitive bool - - // markerOnly is true if the callNode exists solely to fill in a default value - markerOnly bool - - // defaultType is the transitive underlying/element type of the node. - // The provided default value literal or reference is expected to be - // convertible to this type. - // - // e.g: - // node type = *string -> defaultType = string - // node type = StringPointerAlias -> defaultType = string - // Only populated if defaultIsPrimitive is true - defaultType *types.Type - - // defaultTopLevelType is the final type the value should resolve to - // This is in constrast with default type, which resolves aliases and pointers. - defaultTopLevelType *types.Type -} - -type defaultValue struct { - // The value was written directly in the marker comment and - // has been parsed as JSON - InlineConstant string - // The name of the symbol relative to the parsed package path - // i.e. k8s.io/pkg.apis.v1.Foo if from another package or simply `Foo` - // if within the same package. - SymbolReference types.Name -} - -func (d defaultValue) IsEmpty() bool { - resolved := d.Resolved() - return resolved == "" -} - -func (d defaultValue) Resolved() string { - if len(d.InlineConstant) > 0 { - return d.InlineConstant - } - return d.SymbolReference.String() -} - -// CallNodeVisitorFunc is a function for visiting a call tree. ancestors is the list of all parents -// of this node to the root of the tree - will be empty at the root. -type CallNodeVisitorFunc func(ancestors []*callNode, node *callNode) - -func (n *callNode) VisitInOrder(fn CallNodeVisitorFunc) { - n.visitInOrder(nil, fn) -} - -func (n *callNode) visitInOrder(ancestors []*callNode, fn CallNodeVisitorFunc) { - fn(ancestors, n) - ancestors = append(ancestors, n) - for i := range n.children { - n.children[i].visitInOrder(ancestors, fn) - } -} - -var ( - indexVariables = "ijklmnop" - localVariables = "abcdefgh" -) - -// varsForDepth creates temporary variables guaranteed to be unique within lexical Go scopes -// of this depth in a function. It uses canonical Go loop variables for the first 7 levels -// and then resorts to uglier prefixes. -func varsForDepth(depth int) (index, local string) { - if depth > len(indexVariables) { - index = fmt.Sprintf("i%d", depth) - } else { - index = indexVariables[depth : depth+1] - } - if depth > len(localVariables) { - local = fmt.Sprintf("local%d", depth) - } else { - local = localVariables[depth : depth+1] - } - return -} - -// writeCalls generates a list of function calls based on the calls field for the provided variable -// name and pointer. -func (n *callNode) writeCalls(varName string, isVarPointer bool, sw *generator.SnippetWriter) { - accessor := varName - if !isVarPointer { - accessor = "&" + accessor - } - for _, fn := range n.call { - sw.Do("$.fn|raw$($.var$)\n", generator.Args{ - "fn": fn, - "var": accessor, - }) - } -} - -func getTypeZeroValue(t string) (interface{}, error) { - defaultZero, ok := typeZeroValue[t] - if !ok { - return nil, fmt.Errorf("Cannot find zero value for type %v in typeZeroValue", t) - } - - // To generate the code for empty string, they must be quoted - if defaultZero == "" { - defaultZero = strconv.Quote(defaultZero.(string)) - } - return defaultZero, nil -} - -func (n *callNode) writeDefaulter(varName string, index string, isVarPointer bool, sw *generator.SnippetWriter) { - if n.defaultValue.IsEmpty() { - return - } - args := generator.Args{ - "defaultValue": n.defaultValue.Resolved(), - "varName": varName, - "index": index, - "varTopType": n.defaultTopLevelType, - } - - variablePlaceholder := "" - - if n.index { - // Defaulting for array - variablePlaceholder = "$.varName$[$.index$]" - } else if n.key { - // Defaulting for map - variablePlaceholder = "$.varName$[$.index$]" - mapDefaultVar := args["index"].(string) + "_default" - args["mapDefaultVar"] = mapDefaultVar - } else { - // Defaulting for primitive type - variablePlaceholder = "$.varName$" - } - - // defaultIsPrimitive is true if the type or underlying type (in an array/map) is primitive - // or is a pointer to a primitive type - // (Eg: int, map[string]*string, []int) - if n.defaultIsPrimitive { - // If the default value is a primitive when the assigned type is a pointer - // keep using the address-of operator on the primitive value until the types match - if pointerPath := getPointerElementPath(n.defaultTopLevelType); len(pointerPath) > 0 { - // If the destination is a pointer, the last element in - // defaultDepth is the element type of the bottommost pointer: - // the base type of our default value. - destElemType := pointerPath[len(pointerPath)-1] - pointerArgs := args.WithArgs(generator.Args{ - "varDepth": len(pointerPath), - "baseElemType": destElemType, - }) - - sw.Do(fmt.Sprintf("if %s == nil {\n", variablePlaceholder), pointerArgs) - if len(n.defaultValue.InlineConstant) > 0 { - // If default value is a literal then it can be assigned via var stmt - sw.Do("var ptrVar$.varDepth$ $.baseElemType|raw$ = $.defaultValue$\n", pointerArgs) - } else { - // If default value is not a literal then it may need to be casted - // to the base type of the destination pointer - sw.Do("ptrVar$.varDepth$ := $.baseElemType|raw$($.defaultValue$)\n", pointerArgs) - } - - for i := len(pointerPath); i >= 1; i-- { - dest := fmt.Sprintf("ptrVar%d", i-1) - assignment := ":=" - if i == 1 { - // Last assignment is into the storage destination - dest = variablePlaceholder - assignment = "=" - } - - sourceType := "*" + destElemType.String() - if i == len(pointerPath) { - // Initial value is not a pointer - sourceType = destElemType.String() - } - destElemType = pointerPath[i-1] - - // Cannot include `dest` into args since its value may be - // `variablePlaceholder` which is a template, not a value - elementArgs := pointerArgs.WithArgs(generator.Args{ - "assignment": assignment, - "source": fmt.Sprintf("ptrVar%d", i), - "destElemType": destElemType, - }) - - // Skip cast if type is exact match - if destElemType.String() == sourceType { - sw.Do(fmt.Sprintf("%v $.assignment$ &$.source$\n", dest), elementArgs) - } else { - sw.Do(fmt.Sprintf("%v $.assignment$ (*$.destElemType|raw$)(&$.source$)\n", dest), elementArgs) - } - } - } else { - // For primitive types, nil checks cannot be used and the zero value must be determined - defaultZero, err := getTypeZeroValue(n.defaultType.String()) - if err != nil { - klog.Error(err) - } - args["defaultZero"] = defaultZero - - sw.Do(fmt.Sprintf("if %s == $.defaultZero$ {\n", variablePlaceholder), args) - - if len(n.defaultValue.InlineConstant) > 0 { - sw.Do(fmt.Sprintf("%s = $.defaultValue$", variablePlaceholder), args) - } else { - sw.Do(fmt.Sprintf("%s = $.varTopType|raw$($.defaultValue$)", variablePlaceholder), args) - } - } - } else { - sw.Do(fmt.Sprintf("if %s == nil {\n", variablePlaceholder), args) - // Map values are not directly addressable and we need a temporary variable to do json unmarshalling - // This applies to maps with non-primitive values (eg: map[string]SubStruct) - if n.key { - sw.Do("$.mapDefaultVar$ := $.varName$[$.index$]\n", args) - sw.Do("if err := json.Unmarshal([]byte(`$.defaultValue$`), &$.mapDefaultVar$); err != nil {\n", args) - } else { - variablePointer := variablePlaceholder - if !isVarPointer { - variablePointer = "&" + variablePointer - } - sw.Do(fmt.Sprintf("if err := json.Unmarshal([]byte(`$.defaultValue$`), %s); err != nil {\n", variablePointer), args) - } - sw.Do("panic(err)\n", nil) - sw.Do("}\n", nil) - if n.key { - sw.Do("$.varName$[$.index$] = $.mapDefaultVar$\n", args) - } - } - sw.Do("}\n", nil) -} - -// WriteMethod performs an in-order traversal of the calltree, generating loops and if blocks as necessary -// to correctly turn the call tree into a method body that invokes all calls on all child nodes of the call tree. -// Depth is used to generate local variables at the proper depth. -func (n *callNode) WriteMethod(varName string, depth int, ancestors []*callNode, sw *generator.SnippetWriter) { - // if len(n.call) > 0 { - // sw.Do(fmt.Sprintf("// %s\n", callPath(append(ancestors, n)).String()), nil) - // } - - if len(n.field) > 0 { - varName = varName + "." + n.field - } - - index, local := varsForDepth(depth) - vars := generator.Args{ - "index": index, - "local": local, - "var": varName, - } - - isPointer := n.elem && !n.index - if isPointer && len(ancestors) > 0 { - sw.Do("if $.var$ != nil {\n", vars) - } - - switch { - case n.index: - sw.Do("for $.index$ := range $.var$ {\n", vars) - if !n.markerOnly { - if n.elem { - sw.Do("$.local$ := $.var$[$.index$]\n", vars) - } else { - sw.Do("$.local$ := &$.var$[$.index$]\n", vars) - } - } - - n.writeDefaulter(varName, index, isPointer, sw) - n.writeCalls(local, true, sw) - for i := range n.children { - n.children[i].WriteMethod(local, depth+1, append(ancestors, n), sw) - } - sw.Do("}\n", nil) - case n.key: - if !n.defaultValue.IsEmpty() { - // Map keys are typed and cannot share the same index variable as arrays and other maps - index = index + "_" + ancestors[len(ancestors)-1].field - vars["index"] = index - sw.Do("for $.index$ := range $.var$ {\n", vars) - n.writeDefaulter(varName, index, isPointer, sw) - sw.Do("}\n", nil) - } - default: - n.writeDefaulter(varName, index, isPointer, sw) - n.writeCalls(varName, isPointer, sw) - for i := range n.children { - n.children[i].WriteMethod(varName, depth, append(ancestors, n), sw) - } - } - - if isPointer && len(ancestors) > 0 { - sw.Do("}\n", nil) - } -} - -type callPath []*callNode - -// String prints a representation of a callPath that roughly approximates what a Go accessor -// would look like. Used for debugging only. -func (path callPath) String() string { - if len(path) == 0 { - return "" - } - var parts []string - for _, p := range path { - last := len(parts) - 1 - switch { - case p.elem: - if len(parts) > 0 { - parts[last] = "*" + parts[last] - } else { - parts = append(parts, "*") - } - case p.index: - if len(parts) > 0 { - parts[last] = parts[last] + "[i]" - } else { - parts = append(parts, "[i]") - } - case p.key: - if len(parts) > 0 { - parts[last] = parts[last] + "[key]" - } else { - parts = append(parts, "[key]") - } - default: - if len(p.field) > 0 { - parts = append(parts, p.field) - } else { - parts = append(parts, "") - } - } - } - var calls []string - for _, fn := range path[len(path)-1].call { - calls = append(calls, fn.Name.String()) - } - if len(calls) == 0 { - calls = append(calls, "") - } - - return strings.Join(parts, ".") + " calls " + strings.Join(calls, ", ") -} diff --git a/vendor/k8s.io/gengo/examples/import-boss/generators/import_restrict.go b/vendor/k8s.io/gengo/examples/import-boss/generators/import_restrict.go deleted file mode 100644 index d7eb20b8..00000000 --- a/vendor/k8s.io/gengo/examples/import-boss/generators/import_restrict.go +++ /dev/null @@ -1,443 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -// Package generators has the generators for the import-boss utility. -package generators - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "sort" - "strings" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - "sigs.k8s.io/yaml" - - "k8s.io/klog/v2" -) - -const ( - goModFile = "go.mod" - importBossFileType = "import-boss" -) - -// NameSystems returns the name system used by the generators in this package. -func NameSystems() namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer("", nil), - } -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "raw" -} - -// Packages makes the import-boss package definition. -func Packages(c *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - pkgs := generator.Packages{} - c.FileTypes = map[string]generator.FileType{ - importBossFileType: importRuleFile{c}, - } - - for _, p := range c.Universe { - if !inputIncludes(arguments.InputDirs, p) { - // Don't run on e.g. third party dependencies. - continue - } - savedPackage := p - pkgs = append(pkgs, &generator.DefaultPackage{ - PackageName: p.Name, - PackagePath: p.Path, - Source: p.SourcePath, - // GeneratorFunc returns a list of generators. Each generator makes a - // single file. - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - return []generator.Generator{&importRules{ - myPackage: savedPackage, - }} - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - return false - }, - }) - } - - return pkgs -} - -// inputIncludes returns true if the given package is a (sub) package of one of -// the InputDirs. -func inputIncludes(inputs []string, p *types.Package) bool { - // TODO: This does not handle conversion of local paths (./foo) into - // canonical packages (github.com/example/project/foo). - for _, input := range inputs { - // Normalize paths - input := strings.TrimSuffix(input, "/") - input = strings.TrimPrefix(input, "./vendor/") - seek := strings.TrimSuffix(p.Path, "/") - - if input == seek { - return true - } - if strings.HasSuffix(input, "...") { - input = strings.TrimSuffix(input, "...") - if strings.HasPrefix(seek+"/", input) { - return true - } - } - } - return false -} - -// A single import restriction rule. -type Rule struct { - // All import paths that match this regexp... - SelectorRegexp string - // ... must have one of these prefixes ... - AllowedPrefixes []string - // ... and must not have one of these prefixes. - ForbiddenPrefixes []string -} - -type InverseRule struct { - Rule - // True if the rule is to be applied to transitive imports. - Transitive bool -} - -type fileFormat struct { - CurrentImports []string - - Rules []Rule - InverseRules []InverseRule - - path string -} - -func readFile(path string) (*fileFormat, error) { - currentBytes, err := ioutil.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("couldn't read %v: %v", path, err) - } - - var current fileFormat - err = yaml.Unmarshal(currentBytes, ¤t) - if err != nil { - return nil, fmt.Errorf("couldn't unmarshal %v: %v", path, err) - } - current.path = path - return ¤t, nil -} - -func writeFile(path string, ff *fileFormat) error { - raw, err := json.MarshalIndent(ff, "", "\t") - if err != nil { - return fmt.Errorf("couldn't format data for file %v.\n%#v", path, ff) - } - f, err := os.Create(path) - if err != nil { - return fmt.Errorf("couldn't open %v for writing: %v", path, err) - } - defer f.Close() - _, err = f.Write(raw) - return err -} - -// This does the actual checking, since it knows the literal destination file. -type importRuleFile struct { - context *generator.Context -} - -func (irf importRuleFile) AssembleFile(f *generator.File, path string) error { - return irf.VerifyFile(f, path) -} - -// TODO: make a flag to enable this, or expose this information in some other way. -func (importRuleFile) listEntireImportTree(f *generator.File, path string) error { - // If the file exists, populate its current imports. This is mostly to help - // humans figure out what they need to fix. - if _, err := os.Stat(path); err != nil { - // Ignore packages which haven't opted in by adding an .import-restrictions file. - return nil - } - - current, err := readFile(path) - if err != nil { - return err - } - - current.CurrentImports = []string{} - for v := range f.Imports { - current.CurrentImports = append(current.CurrentImports, v) - } - sort.Strings(current.CurrentImports) - - return writeFile(path, current) -} - -// removeLastDir removes the last directory, but leaves the file name -// unchanged. It returns the new path and the removed directory. So: -// "a/b/c/file" -> ("a/b/file", "c") -func removeLastDir(path string) (newPath, removedDir string) { - dir, file := filepath.Split(path) - dir = strings.TrimSuffix(dir, string(filepath.Separator)) - return filepath.Join(filepath.Dir(dir), file), filepath.Base(dir) -} - -// isGoModRoot checks if a directory is the root directory for a package -// by checking for the existence of a 'go.mod' file in that directory. -func isGoModRoot(path string) bool { - _, err := os.Stat(filepath.Join(filepath.Dir(path), goModFile)) - return err == nil -} - -// recursiveRead collects all '.import-restriction' files, between the current directory, -// and the package root when Go modules are enabled, or $GOPATH/src when they are not. -func recursiveRead(path string) ([]*fileFormat, error) { - restrictionFiles := make([]*fileFormat, 0) - - for { - if _, err := os.Stat(path); err == nil { - rules, err := readFile(path) - if err != nil { - return nil, err - } - - restrictionFiles = append(restrictionFiles, rules) - } - - nextPath, removedDir := removeLastDir(path) - if nextPath == path || isGoModRoot(path) || removedDir == "src" { - break - } - - path = nextPath - } - - return restrictionFiles, nil -} - -func (irf importRuleFile) VerifyFile(f *generator.File, path string) error { - restrictionFiles, err := recursiveRead(filepath.Join(f.PackageSourcePath, f.Name)) - if err != nil { - return fmt.Errorf("error finding rules file: %v", err) - } - - if err := irf.verifyRules(restrictionFiles, f); err != nil { - return err - } - - return irf.verifyInverseRules(restrictionFiles, f) -} - -func (irf importRuleFile) verifyRules(restrictionFiles []*fileFormat, f *generator.File) error { - selectors := make([][]*regexp.Regexp, len(restrictionFiles)) - for i, restrictionFile := range restrictionFiles { - for _, r := range restrictionFile.Rules { - re, err := regexp.Compile(r.SelectorRegexp) - if err != nil { - return fmt.Errorf("regexp `%s` in file %q doesn't compile: %v", r.SelectorRegexp, restrictionFile.path, err) - } - - selectors[i] = append(selectors[i], re) - } - } - - forbiddenImports := map[string]string{} - allowedMismatchedImports := []string{} - - for v := range f.Imports { - explicitlyAllowed := false - - NextRestrictionFiles: - for i, rules := range restrictionFiles { - for j, r := range rules.Rules { - matching := selectors[i][j].MatchString(v) - klog.V(5).Infof("Checking %v matches %v: %v\n", r.SelectorRegexp, v, matching) - if !matching { - continue - } - for _, forbidden := range r.ForbiddenPrefixes { - klog.V(4).Infof("Checking %v against %v\n", v, forbidden) - if strings.HasPrefix(v, forbidden) { - forbiddenImports[v] = forbidden - } - } - for _, allowed := range r.AllowedPrefixes { - klog.V(4).Infof("Checking %v against %v\n", v, allowed) - if strings.HasPrefix(v, allowed) { - explicitlyAllowed = true - break - } - } - - if !explicitlyAllowed { - allowedMismatchedImports = append(allowedMismatchedImports, v) - } else { - klog.V(2).Infof("%v importing %v allowed by %v\n", f.PackagePath, v, restrictionFiles[i].path) - break NextRestrictionFiles - } - } - } - } - - if len(forbiddenImports) > 0 || len(allowedMismatchedImports) > 0 { - var errorBuilder strings.Builder - for i, f := range forbiddenImports { - fmt.Fprintf(&errorBuilder, "import %v has forbidden prefix %v\n", i, f) - } - if len(allowedMismatchedImports) > 0 { - sort.Sort(sort.StringSlice(allowedMismatchedImports)) - fmt.Fprintf(&errorBuilder, "the following imports did not match any allowed prefix:\n") - for _, i := range allowedMismatchedImports { - fmt.Fprintf(&errorBuilder, " %v\n", i) - } - } - return errors.New(errorBuilder.String()) - } - - return nil -} - -// verifyInverseRules checks that all packages that import a package are allowed to import it. -func (irf importRuleFile) verifyInverseRules(restrictionFiles []*fileFormat, f *generator.File) error { - // compile all Selector regex in all restriction files - selectors := make([][]*regexp.Regexp, len(restrictionFiles)) - for i, restrictionFile := range restrictionFiles { - for _, r := range restrictionFile.InverseRules { - re, err := regexp.Compile(r.SelectorRegexp) - if err != nil { - return fmt.Errorf("regexp `%s` in file %q doesn't compile: %v", r.SelectorRegexp, restrictionFile.path, err) - } - - selectors[i] = append(selectors[i], re) - } - } - - directImport := map[string]bool{} - for _, imp := range irf.context.IncomingImports()[f.PackagePath] { - directImport[imp] = true - } - - forbiddenImports := map[string]string{} - allowedMismatchedImports := []string{} - - for _, v := range irf.context.TransitiveIncomingImports()[f.PackagePath] { - explicitlyAllowed := false - - NextRestrictionFiles: - for i, rules := range restrictionFiles { - for j, r := range rules.InverseRules { - if !r.Transitive && !directImport[v] { - continue - } - - re := selectors[i][j] - matching := re.MatchString(v) - klog.V(4).Infof("Checking %v matches %v (importing %v: %v\n", r.SelectorRegexp, v, f.PackagePath, matching) - if !matching { - continue - } - for _, forbidden := range r.ForbiddenPrefixes { - klog.V(4).Infof("Checking %v against %v\n", v, forbidden) - if strings.HasPrefix(v, forbidden) { - forbiddenImports[v] = forbidden - } - } - for _, allowed := range r.AllowedPrefixes { - klog.V(4).Infof("Checking %v against %v\n", v, allowed) - if strings.HasPrefix(v, allowed) { - explicitlyAllowed = true - break - } - } - if !explicitlyAllowed { - allowedMismatchedImports = append(allowedMismatchedImports, v) - } else { - klog.V(2).Infof("%v importing %v allowed by %v\n", v, f.PackagePath, restrictionFiles[i].path) - break NextRestrictionFiles - } - } - } - } - - if len(forbiddenImports) > 0 || len(allowedMismatchedImports) > 0 { - var errorBuilder strings.Builder - for i, f := range forbiddenImports { - fmt.Fprintf(&errorBuilder, "(inverse): import %v has forbidden prefix %v\n", i, f) - } - if len(allowedMismatchedImports) > 0 { - sort.Sort(sort.StringSlice(allowedMismatchedImports)) - fmt.Fprintf(&errorBuilder, "(inverse): the following imports did not match any allowed prefix:\n") - for _, i := range allowedMismatchedImports { - fmt.Fprintf(&errorBuilder, " %v\n", i) - } - } - return errors.New(errorBuilder.String()) - } - - return nil -} - -// importRules produces a file with a set for a single type. -type importRules struct { - myPackage *types.Package - imports namer.ImportTracker -} - -var ( - _ = generator.Generator(&importRules{}) - _ = generator.FileType(importRuleFile{}) -) - -func (r *importRules) Name() string { return "import rules" } -func (r *importRules) Filter(*generator.Context, *types.Type) bool { return false } -func (r *importRules) Namers(*generator.Context) namer.NameSystems { return nil } -func (r *importRules) PackageVars(*generator.Context) []string { return []string{} } -func (r *importRules) PackageConsts(*generator.Context) []string { return []string{} } -func (r *importRules) GenerateType(*generator.Context, *types.Type, io.Writer) error { return nil } -func (r *importRules) Filename() string { return ".import-restrictions" } -func (r *importRules) FileType() string { return importBossFileType } -func (r *importRules) Init(c *generator.Context, w io.Writer) error { return nil } -func (r *importRules) Finalize(*generator.Context, io.Writer) error { return nil } - -func dfsImports(dest *[]string, seen map[string]bool, p *types.Package) { - for _, p2 := range p.Imports { - if seen[p2.Path] { - continue - } - seen[p2.Path] = true - dfsImports(dest, seen, p2) - *dest = append(*dest, p2.Path) - } -} - -func (r *importRules) Imports(*generator.Context) []string { - all := []string{} - dfsImports(&all, map[string]bool{}, r.myPackage) - return all -} diff --git a/vendor/k8s.io/gengo/examples/set-gen/generators/sets.go b/vendor/k8s.io/gengo/examples/set-gen/generators/sets.go deleted file mode 100644 index e89f5ad7..00000000 --- a/vendor/k8s.io/gengo/examples/set-gen/generators/sets.go +++ /dev/null @@ -1,378 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// Package generators has the generators for the set-gen utility. -package generators - -import ( - "io" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/klog/v2" -) - -// NameSystems returns the name system used by the generators in this package. -func NameSystems() namer.NameSystems { - return namer.NameSystems{ - "public": namer.NewPublicNamer(0), - "private": namer.NewPrivateNamer(0), - "raw": namer.NewRawNamer("", nil), - } -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "public" -} - -// Packages makes the sets package definition. -func Packages(_ *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - - return generator.Packages{&generator.DefaultPackage{ - PackageName: "sets", - PackagePath: arguments.OutputPackagePath, - HeaderText: boilerplate, - PackageDocumentation: []byte( - `// Package sets has auto-generated set types. -`), - // GeneratorFunc returns a list of generators. Each generator makes a - // single file. - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - generators = []generator.Generator{ - // Always generate a "doc.go" file. - generator.DefaultGen{OptionalName: "doc"}, - // Make a separate file for the Empty type, since it's shared by every type. - generator.DefaultGen{ - OptionalName: "empty", - OptionalBody: []byte(emptyTypeDecl), - }, - } - // Since we want a file per type that we generate a set for, we - // have to provide a function for this. - for _, t := range c.Order { - generators = append(generators, &genSet{ - DefaultGen: generator.DefaultGen{ - // Use the privatized version of the - // type name as the file name. - // - // TODO: make a namer that converts - // camelCase to '-' separation for file - // names? - OptionalName: c.Namers["private"].Name(t), - }, - outputPackage: arguments.OutputPackagePath, - typeToMatch: t, - imports: generator.NewImportTracker(), - }) - } - return generators - }, - FilterFunc: func(c *generator.Context, t *types.Type) bool { - // It would be reasonable to filter by the type's package here. - // It might be necessary if your input directory has a big - // import graph. - switch t.Kind { - case types.Map, types.Slice, types.Pointer: - // These types can't be keys in a map. - return false - case types.Builtin: - return true - case types.Struct: - // Only some structs can be keys in a map. This is triggered by the line - // // +genset - // or - // // +genset=true - return extractBoolTagOrDie("genset", t.CommentLines) == true - } - return false - }, - }} -} - -// genSet produces a file with a set for a single type. -type genSet struct { - generator.DefaultGen - outputPackage string - typeToMatch *types.Type - imports namer.ImportTracker -} - -// Filter ignores all but one type because we're making a single file per type. -func (g *genSet) Filter(c *generator.Context, t *types.Type) bool { return t == g.typeToMatch } - -func (g *genSet) Namers(c *generator.Context) namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.outputPackage, g.imports), - } -} - -func (g *genSet) Imports(c *generator.Context) (imports []string) { - return append(g.imports.ImportLines(), "reflect", "sort") -} - -// args constructs arguments for templates. Usage: -// g.args(t, "key1", value1, "key2", value2, ...) -// -// 't' is loaded with the key 'type'. -// -// We could use t directly as the argument, but doing it this way makes it easy -// to mix in additional parameters. This feature is not used in this set -// generator, but is present as an example. -func (g *genSet) args(t *types.Type, kv ...interface{}) interface{} { - m := map[interface{}]interface{}{"type": t} - for i := 0; i < len(kv)/2; i++ { - m[kv[i*2]] = kv[i*2+1] - } - return m -} - -// GenerateType makes the body of a file implementing a set for type t. -func (g *genSet) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - sw.Do(setCode, g.args(t)) - sw.Do("func less$.type|public$(lhs, rhs $.type|raw$) bool {\n", g.args(t)) - g.lessBody(sw, t) - sw.Do("}\n", g.args(t)) - return sw.Error() -} - -func (g *genSet) lessBody(sw *generator.SnippetWriter, t *types.Type) { - // TODO: make this recursive, handle pointers and multiple nested structs... - switch t.Kind { - case types.Struct: - for _, m := range types.FlattenMembers(t.Members) { - sw.Do("if lhs.$.Name$ < rhs.$.Name$ { return true }\n", m) - sw.Do("if lhs.$.Name$ > rhs.$.Name$ { return false }\n", m) - } - sw.Do("return false\n", nil) - default: - sw.Do("return lhs < rhs\n", nil) - } -} - -// written to the "empty.go" file. -var emptyTypeDecl = ` -// Empty is public since it is used by some internal API objects for conversions between external -// string arrays and internal sets, and conversion logic requires public types today. -type Empty struct{} -` - -// Written for every type. If you've never used text/template before: -// $.type$ refers to the source type; |public means to -// call the function giving the public name, |raw the raw type name. -var setCode = `// sets.$.type|public$ is a set of $.type|raw$s, implemented via map[$.type|raw$]struct{} for minimal memory consumption. -type $.type|public$ map[$.type|raw$]Empty - -// New$.type|public$ creates a $.type|public$ from a list of values. -func New$.type|public$(items ...$.type|raw$) $.type|public$ { - ss := make($.type|public$, len(items)) - ss.Insert(items...) - return ss -} - -// $.type|public$KeySet creates a $.type|public$ from a keys of a map[$.type|raw$](? extends interface{}). -// If the value passed in is not actually a map, this will panic. -func $.type|public$KeySet(theMap interface{}) $.type|public$ { - v := reflect.ValueOf(theMap) - ret := $.type|public${} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().($.type|raw$)) - } - return ret -} - -// Insert adds items to the set. -func (s $.type|public$) Insert(items ...$.type|raw$) $.type|public$ { - for _, item := range items { - s[item] = Empty{} - } - return s -} - -// Delete removes all items from the set. -func (s $.type|public$) Delete(items ...$.type|raw$) $.type|public$ { - for _, item := range items { - delete(s, item) - } - return s -} - -// Has returns true if and only if item is contained in the set. -func (s $.type|public$) Has(item $.type|raw$) bool { - _, contained := s[item] - return contained -} - -// HasAll returns true if and only if all items are contained in the set. -func (s $.type|public$) HasAll(items ...$.type|raw$) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true -} - -// HasAny returns true if any items are contained in the set. -func (s $.type|public$) HasAny(items ...$.type|raw$) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false -} - -// Clone returns a new set which is a copy of the current set. -func (s $.type|public$) Clone() $.type|public$ { - result := make($.type|public$, len(s)) - for key := range s { - result.Insert(key) - } - return result -} - -// Difference returns a set of objects that are not in s2. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.Difference(s2) = {a3} -// s2.Difference(s1) = {a4, a5} -func (s1 $.type|public$) Difference(s2 $.type|public$) $.type|public$ { - result := New$.type|public$() - for key := range s1 { - if !s2.Has(key) { - result.Insert(key) - } - } - return result -} - -// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.SymmetricDifference(s2) = {a3, a4, a5} -// s2.SymmetricDifference(s1) = {a3, a4, a5} -func (s1 $.type|public$) SymmetricDifference(s2 $.type|public$) $.type|public$ { - return s1.Difference(s2).Union(s2.Difference(s1)) -} - -// Union returns a new set which includes items in either s1 or s2. -// For example: -// s1 = {a1, a2} -// s2 = {a3, a4} -// s1.Union(s2) = {a1, a2, a3, a4} -// s2.Union(s1) = {a1, a2, a3, a4} -func (s1 $.type|public$) Union(s2 $.type|public$) $.type|public$ { - result := s1.Clone() - for key := range s2 { - result.Insert(key) - } - return result -} - -// Intersection returns a new set which includes the item in BOTH s1 and s2 -// For example: -// s1 = {a1, a2} -// s2 = {a2, a3} -// s1.Intersection(s2) = {a2} -func (s1 $.type|public$) Intersection(s2 $.type|public$) $.type|public$ { - var walk, other $.type|public$ - result := New$.type|public$() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result -} - -// IsSuperset returns true if and only if s1 is a superset of s2. -func (s1 $.type|public$) IsSuperset(s2 $.type|public$) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true -} - -// Equal returns true if and only if s1 is equal (as a set) to s2. -// Two sets are equal if their membership is identical. -// (In practice, this means same elements, order doesn't matter) -func (s1 $.type|public$) Equal(s2 $.type|public$) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) -} - -type sortableSliceOf$.type|public$ []$.type|raw$ - -func (s sortableSliceOf$.type|public$) Len() int { return len(s) } -func (s sortableSliceOf$.type|public$) Less(i, j int) bool { return less$.type|public$(s[i], s[j]) } -func (s sortableSliceOf$.type|public$) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// List returns the contents as a sorted $.type|raw$ slice. -func (s $.type|public$) List() []$.type|raw$ { - res := make(sortableSliceOf$.type|public$, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []$.type|raw$(res) -} - -// UnsortedList returns the slice with contents in random order. -func (s $.type|public$) UnsortedList() []$.type|raw$ { - res :=make([]$.type|raw$, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res -} - -// Returns a single element from the set. -func (s $.type|public$) PopAny() ($.type|raw$, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue $.type|raw$ - return zeroValue, false -} - -// Len returns the size of the set. -func (s $.type|public$) Len() int { - return len(s) -} - -` diff --git a/vendor/k8s.io/gengo/examples/set-gen/sets/byte.go b/vendor/k8s.io/gengo/examples/set-gen/sets/byte.go deleted file mode 100644 index e9660c2f..00000000 --- a/vendor/k8s.io/gengo/examples/set-gen/sets/byte.go +++ /dev/null @@ -1,221 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -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. -*/ - -// Code generated by set-gen. DO NOT EDIT. - -package sets - -import ( - "reflect" - "sort" -) - -// sets.Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption. -type Byte map[byte]Empty - -// NewByte creates a Byte from a list of values. -func NewByte(items ...byte) Byte { - ss := make(Byte, len(items)) - ss.Insert(items...) - return ss -} - -// ByteKeySet creates a Byte from a keys of a map[byte](? extends interface{}). -// If the value passed in is not actually a map, this will panic. -func ByteKeySet(theMap interface{}) Byte { - v := reflect.ValueOf(theMap) - ret := Byte{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(byte)) - } - return ret -} - -// Insert adds items to the set. -func (s Byte) Insert(items ...byte) Byte { - for _, item := range items { - s[item] = Empty{} - } - return s -} - -// Delete removes all items from the set. -func (s Byte) Delete(items ...byte) Byte { - for _, item := range items { - delete(s, item) - } - return s -} - -// Has returns true if and only if item is contained in the set. -func (s Byte) Has(item byte) bool { - _, contained := s[item] - return contained -} - -// HasAll returns true if and only if all items are contained in the set. -func (s Byte) HasAll(items ...byte) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true -} - -// HasAny returns true if any items are contained in the set. -func (s Byte) HasAny(items ...byte) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false -} - -// Clone returns a new set which is a copy of the current set. -func (s Byte) Clone() Byte { - result := make(Byte, len(s)) - for key := range s { - result.Insert(key) - } - return result -} - -// Difference returns a set of objects that are not in s2. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.Difference(s2) = {a3} -// s2.Difference(s1) = {a4, a5} -func (s1 Byte) Difference(s2 Byte) Byte { - result := NewByte() - for key := range s1 { - if !s2.Has(key) { - result.Insert(key) - } - } - return result -} - -// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.SymmetricDifference(s2) = {a3, a4, a5} -// s2.SymmetricDifference(s1) = {a3, a4, a5} -func (s1 Byte) SymmetricDifference(s2 Byte) Byte { - return s1.Difference(s2).Union(s2.Difference(s1)) -} - -// Union returns a new set which includes items in either s1 or s2. -// For example: -// s1 = {a1, a2} -// s2 = {a3, a4} -// s1.Union(s2) = {a1, a2, a3, a4} -// s2.Union(s1) = {a1, a2, a3, a4} -func (s1 Byte) Union(s2 Byte) Byte { - result := s1.Clone() - for key := range s2 { - result.Insert(key) - } - return result -} - -// Intersection returns a new set which includes the item in BOTH s1 and s2 -// For example: -// s1 = {a1, a2} -// s2 = {a2, a3} -// s1.Intersection(s2) = {a2} -func (s1 Byte) Intersection(s2 Byte) Byte { - var walk, other Byte - result := NewByte() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result -} - -// IsSuperset returns true if and only if s1 is a superset of s2. -func (s1 Byte) IsSuperset(s2 Byte) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true -} - -// Equal returns true if and only if s1 is equal (as a set) to s2. -// Two sets are equal if their membership is identical. -// (In practice, this means same elements, order doesn't matter) -func (s1 Byte) Equal(s2 Byte) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) -} - -type sortableSliceOfByte []byte - -func (s sortableSliceOfByte) Len() int { return len(s) } -func (s sortableSliceOfByte) Less(i, j int) bool { return lessByte(s[i], s[j]) } -func (s sortableSliceOfByte) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// List returns the contents as a sorted byte slice. -func (s Byte) List() []byte { - res := make(sortableSliceOfByte, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []byte(res) -} - -// UnsortedList returns the slice with contents in random order. -func (s Byte) UnsortedList() []byte { - res := make([]byte, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res -} - -// Returns a single element from the set. -func (s Byte) PopAny() (byte, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue byte - return zeroValue, false -} - -// Len returns the size of the set. -func (s Byte) Len() int { - return len(s) -} - -func lessByte(lhs, rhs byte) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/gengo/examples/set-gen/sets/int.go b/vendor/k8s.io/gengo/examples/set-gen/sets/int.go deleted file mode 100644 index f614f06e..00000000 --- a/vendor/k8s.io/gengo/examples/set-gen/sets/int.go +++ /dev/null @@ -1,221 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -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. -*/ - -// Code generated by set-gen. DO NOT EDIT. - -package sets - -import ( - "reflect" - "sort" -) - -// sets.Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption. -type Int map[int]Empty - -// NewInt creates a Int from a list of values. -func NewInt(items ...int) Int { - ss := make(Int, len(items)) - ss.Insert(items...) - return ss -} - -// IntKeySet creates a Int from a keys of a map[int](? extends interface{}). -// If the value passed in is not actually a map, this will panic. -func IntKeySet(theMap interface{}) Int { - v := reflect.ValueOf(theMap) - ret := Int{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(int)) - } - return ret -} - -// Insert adds items to the set. -func (s Int) Insert(items ...int) Int { - for _, item := range items { - s[item] = Empty{} - } - return s -} - -// Delete removes all items from the set. -func (s Int) Delete(items ...int) Int { - for _, item := range items { - delete(s, item) - } - return s -} - -// Has returns true if and only if item is contained in the set. -func (s Int) Has(item int) bool { - _, contained := s[item] - return contained -} - -// HasAll returns true if and only if all items are contained in the set. -func (s Int) HasAll(items ...int) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true -} - -// HasAny returns true if any items are contained in the set. -func (s Int) HasAny(items ...int) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false -} - -// Clone returns a new set which is a copy of the current set. -func (s Int) Clone() Int { - result := make(Int, len(s)) - for key := range s { - result.Insert(key) - } - return result -} - -// Difference returns a set of objects that are not in s2. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.Difference(s2) = {a3} -// s2.Difference(s1) = {a4, a5} -func (s1 Int) Difference(s2 Int) Int { - result := NewInt() - for key := range s1 { - if !s2.Has(key) { - result.Insert(key) - } - } - return result -} - -// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.SymmetricDifference(s2) = {a3, a4, a5} -// s2.SymmetricDifference(s1) = {a3, a4, a5} -func (s1 Int) SymmetricDifference(s2 Int) Int { - return s1.Difference(s2).Union(s2.Difference(s1)) -} - -// Union returns a new set which includes items in either s1 or s2. -// For example: -// s1 = {a1, a2} -// s2 = {a3, a4} -// s1.Union(s2) = {a1, a2, a3, a4} -// s2.Union(s1) = {a1, a2, a3, a4} -func (s1 Int) Union(s2 Int) Int { - result := s1.Clone() - for key := range s2 { - result.Insert(key) - } - return result -} - -// Intersection returns a new set which includes the item in BOTH s1 and s2 -// For example: -// s1 = {a1, a2} -// s2 = {a2, a3} -// s1.Intersection(s2) = {a2} -func (s1 Int) Intersection(s2 Int) Int { - var walk, other Int - result := NewInt() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result -} - -// IsSuperset returns true if and only if s1 is a superset of s2. -func (s1 Int) IsSuperset(s2 Int) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true -} - -// Equal returns true if and only if s1 is equal (as a set) to s2. -// Two sets are equal if their membership is identical. -// (In practice, this means same elements, order doesn't matter) -func (s1 Int) Equal(s2 Int) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) -} - -type sortableSliceOfInt []int - -func (s sortableSliceOfInt) Len() int { return len(s) } -func (s sortableSliceOfInt) Less(i, j int) bool { return lessInt(s[i], s[j]) } -func (s sortableSliceOfInt) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// List returns the contents as a sorted int slice. -func (s Int) List() []int { - res := make(sortableSliceOfInt, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []int(res) -} - -// UnsortedList returns the slice with contents in random order. -func (s Int) UnsortedList() []int { - res := make([]int, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res -} - -// Returns a single element from the set. -func (s Int) PopAny() (int, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue int - return zeroValue, false -} - -// Len returns the size of the set. -func (s Int) Len() int { - return len(s) -} - -func lessInt(lhs, rhs int) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/gengo/examples/set-gen/sets/int64.go b/vendor/k8s.io/gengo/examples/set-gen/sets/int64.go deleted file mode 100644 index 995d99bd..00000000 --- a/vendor/k8s.io/gengo/examples/set-gen/sets/int64.go +++ /dev/null @@ -1,221 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -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. -*/ - -// Code generated by set-gen. DO NOT EDIT. - -package sets - -import ( - "reflect" - "sort" -) - -// sets.Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption. -type Int64 map[int64]Empty - -// NewInt64 creates a Int64 from a list of values. -func NewInt64(items ...int64) Int64 { - ss := make(Int64, len(items)) - ss.Insert(items...) - return ss -} - -// Int64KeySet creates a Int64 from a keys of a map[int64](? extends interface{}). -// If the value passed in is not actually a map, this will panic. -func Int64KeySet(theMap interface{}) Int64 { - v := reflect.ValueOf(theMap) - ret := Int64{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(int64)) - } - return ret -} - -// Insert adds items to the set. -func (s Int64) Insert(items ...int64) Int64 { - for _, item := range items { - s[item] = Empty{} - } - return s -} - -// Delete removes all items from the set. -func (s Int64) Delete(items ...int64) Int64 { - for _, item := range items { - delete(s, item) - } - return s -} - -// Has returns true if and only if item is contained in the set. -func (s Int64) Has(item int64) bool { - _, contained := s[item] - return contained -} - -// HasAll returns true if and only if all items are contained in the set. -func (s Int64) HasAll(items ...int64) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true -} - -// HasAny returns true if any items are contained in the set. -func (s Int64) HasAny(items ...int64) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false -} - -// Clone returns a new set which is a copy of the current set. -func (s Int64) Clone() Int64 { - result := make(Int64, len(s)) - for key := range s { - result.Insert(key) - } - return result -} - -// Difference returns a set of objects that are not in s2. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.Difference(s2) = {a3} -// s2.Difference(s1) = {a4, a5} -func (s1 Int64) Difference(s2 Int64) Int64 { - result := NewInt64() - for key := range s1 { - if !s2.Has(key) { - result.Insert(key) - } - } - return result -} - -// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.SymmetricDifference(s2) = {a3, a4, a5} -// s2.SymmetricDifference(s1) = {a3, a4, a5} -func (s1 Int64) SymmetricDifference(s2 Int64) Int64 { - return s1.Difference(s2).Union(s2.Difference(s1)) -} - -// Union returns a new set which includes items in either s1 or s2. -// For example: -// s1 = {a1, a2} -// s2 = {a3, a4} -// s1.Union(s2) = {a1, a2, a3, a4} -// s2.Union(s1) = {a1, a2, a3, a4} -func (s1 Int64) Union(s2 Int64) Int64 { - result := s1.Clone() - for key := range s2 { - result.Insert(key) - } - return result -} - -// Intersection returns a new set which includes the item in BOTH s1 and s2 -// For example: -// s1 = {a1, a2} -// s2 = {a2, a3} -// s1.Intersection(s2) = {a2} -func (s1 Int64) Intersection(s2 Int64) Int64 { - var walk, other Int64 - result := NewInt64() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result -} - -// IsSuperset returns true if and only if s1 is a superset of s2. -func (s1 Int64) IsSuperset(s2 Int64) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true -} - -// Equal returns true if and only if s1 is equal (as a set) to s2. -// Two sets are equal if their membership is identical. -// (In practice, this means same elements, order doesn't matter) -func (s1 Int64) Equal(s2 Int64) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) -} - -type sortableSliceOfInt64 []int64 - -func (s sortableSliceOfInt64) Len() int { return len(s) } -func (s sortableSliceOfInt64) Less(i, j int) bool { return lessInt64(s[i], s[j]) } -func (s sortableSliceOfInt64) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// List returns the contents as a sorted int64 slice. -func (s Int64) List() []int64 { - res := make(sortableSliceOfInt64, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []int64(res) -} - -// UnsortedList returns the slice with contents in random order. -func (s Int64) UnsortedList() []int64 { - res := make([]int64, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res -} - -// Returns a single element from the set. -func (s Int64) PopAny() (int64, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue int64 - return zeroValue, false -} - -// Len returns the size of the set. -func (s Int64) Len() int { - return len(s) -} - -func lessInt64(lhs, rhs int64) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/gengo/examples/set-gen/sets/string.go b/vendor/k8s.io/gengo/examples/set-gen/sets/string.go deleted file mode 100644 index 4a4a92fd..00000000 --- a/vendor/k8s.io/gengo/examples/set-gen/sets/string.go +++ /dev/null @@ -1,221 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -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. -*/ - -// Code generated by set-gen. DO NOT EDIT. - -package sets - -import ( - "reflect" - "sort" -) - -// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption. -type String map[string]Empty - -// NewString creates a String from a list of values. -func NewString(items ...string) String { - ss := make(String, len(items)) - ss.Insert(items...) - return ss -} - -// StringKeySet creates a String from a keys of a map[string](? extends interface{}). -// If the value passed in is not actually a map, this will panic. -func StringKeySet(theMap interface{}) String { - v := reflect.ValueOf(theMap) - ret := String{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(string)) - } - return ret -} - -// Insert adds items to the set. -func (s String) Insert(items ...string) String { - for _, item := range items { - s[item] = Empty{} - } - return s -} - -// Delete removes all items from the set. -func (s String) Delete(items ...string) String { - for _, item := range items { - delete(s, item) - } - return s -} - -// Has returns true if and only if item is contained in the set. -func (s String) Has(item string) bool { - _, contained := s[item] - return contained -} - -// HasAll returns true if and only if all items are contained in the set. -func (s String) HasAll(items ...string) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true -} - -// HasAny returns true if any items are contained in the set. -func (s String) HasAny(items ...string) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false -} - -// Clone returns a new set which is a copy of the current set. -func (s String) Clone() String { - result := make(String, len(s)) - for key := range s { - result.Insert(key) - } - return result -} - -// Difference returns a set of objects that are not in s2. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.Difference(s2) = {a3} -// s2.Difference(s1) = {a4, a5} -func (s1 String) Difference(s2 String) String { - result := NewString() - for key := range s1 { - if !s2.Has(key) { - result.Insert(key) - } - } - return result -} - -// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection. -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.SymmetricDifference(s2) = {a3, a4, a5} -// s2.SymmetricDifference(s1) = {a3, a4, a5} -func (s1 String) SymmetricDifference(s2 String) String { - return s1.Difference(s2).Union(s2.Difference(s1)) -} - -// Union returns a new set which includes items in either s1 or s2. -// For example: -// s1 = {a1, a2} -// s2 = {a3, a4} -// s1.Union(s2) = {a1, a2, a3, a4} -// s2.Union(s1) = {a1, a2, a3, a4} -func (s1 String) Union(s2 String) String { - result := s1.Clone() - for key := range s2 { - result.Insert(key) - } - return result -} - -// Intersection returns a new set which includes the item in BOTH s1 and s2 -// For example: -// s1 = {a1, a2} -// s2 = {a2, a3} -// s1.Intersection(s2) = {a2} -func (s1 String) Intersection(s2 String) String { - var walk, other String - result := NewString() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result -} - -// IsSuperset returns true if and only if s1 is a superset of s2. -func (s1 String) IsSuperset(s2 String) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true -} - -// Equal returns true if and only if s1 is equal (as a set) to s2. -// Two sets are equal if their membership is identical. -// (In practice, this means same elements, order doesn't matter) -func (s1 String) Equal(s2 String) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) -} - -type sortableSliceOfString []string - -func (s sortableSliceOfString) Len() int { return len(s) } -func (s sortableSliceOfString) Less(i, j int) bool { return lessString(s[i], s[j]) } -func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// List returns the contents as a sorted string slice. -func (s String) List() []string { - res := make(sortableSliceOfString, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []string(res) -} - -// UnsortedList returns the slice with contents in random order. -func (s String) UnsortedList() []string { - res := make([]string, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res -} - -// Returns a single element from the set. -func (s String) PopAny() (string, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue string - return zeroValue, false -} - -// Len returns the size of the set. -func (s String) Len() int { - return len(s) -} - -func lessString(lhs, rhs string) bool { - return lhs < rhs -} diff --git a/vendor/k8s.io/gengo/generator/default_generator.go b/vendor/k8s.io/gengo/generator/default_generator.go deleted file mode 100644 index f9476682..00000000 --- a/vendor/k8s.io/gengo/generator/default_generator.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generator - -import ( - "io" - - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -const ( - GolangFileType = "golang" -) - -// DefaultGen implements a do-nothing Generator. -// -// It can be used to implement static content files. -type DefaultGen struct { - // OptionalName, if present, will be used for the generator's name, and - // the filename (with ".go" appended). - OptionalName string - - // OptionalBody, if present, will be used as the return from the "Init" - // method. This causes it to be static content for the entire file if - // no other generator touches the file. - OptionalBody []byte -} - -func (d DefaultGen) Name() string { return d.OptionalName } -func (d DefaultGen) Filter(*Context, *types.Type) bool { return true } -func (d DefaultGen) Namers(*Context) namer.NameSystems { return nil } -func (d DefaultGen) Imports(*Context) []string { return []string{} } -func (d DefaultGen) PackageVars(*Context) []string { return []string{} } -func (d DefaultGen) PackageConsts(*Context) []string { return []string{} } -func (d DefaultGen) GenerateType(*Context, *types.Type, io.Writer) error { return nil } -func (d DefaultGen) Filename() string { return d.OptionalName + ".go" } -func (d DefaultGen) FileType() string { return GolangFileType } -func (d DefaultGen) Finalize(*Context, io.Writer) error { return nil } - -func (d DefaultGen) Init(c *Context, w io.Writer) error { - _, err := w.Write(d.OptionalBody) - return err -} - -var ( - _ = Generator(DefaultGen{}) -) diff --git a/vendor/k8s.io/gengo/generator/default_package.go b/vendor/k8s.io/gengo/generator/default_package.go deleted file mode 100644 index dcf08832..00000000 --- a/vendor/k8s.io/gengo/generator/default_package.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generator - -import ( - "k8s.io/gengo/types" -) - -// DefaultPackage contains a default implementation of Package. -type DefaultPackage struct { - // Short name of package, used in the "package xxxx" line. - PackageName string - // Import path of the package, and the location on disk of the package. - PackagePath string - // The location of the package on disk. - Source string - - // Emitted at the top of every file. - HeaderText []byte - - // Emitted only for a "doc.go" file; appended to the HeaderText for - // that file. - PackageDocumentation []byte - - // If non-nil, will be called on "Generators"; otherwise, the static - // list will be used. So you should set only one of these two fields. - GeneratorFunc func(*Context) []Generator - GeneratorList []Generator - - // Optional; filters the types exposed to the generators. - FilterFunc func(*Context, *types.Type) bool -} - -func (d *DefaultPackage) Name() string { return d.PackageName } -func (d *DefaultPackage) Path() string { return d.PackagePath } -func (d *DefaultPackage) SourcePath() string { return d.Source } - -func (d *DefaultPackage) Filter(c *Context, t *types.Type) bool { - if d.FilterFunc != nil { - return d.FilterFunc(c, t) - } - return true -} - -func (d *DefaultPackage) Generators(c *Context) []Generator { - if d.GeneratorFunc != nil { - return d.GeneratorFunc(c) - } - return d.GeneratorList -} - -func (d *DefaultPackage) Header(filename string) []byte { - if filename == "doc.go" { - return append(d.HeaderText, d.PackageDocumentation...) - } - return d.HeaderText -} - -var ( - _ = Package(&DefaultPackage{}) -) diff --git a/vendor/k8s.io/gengo/generator/doc.go b/vendor/k8s.io/gengo/generator/doc.go deleted file mode 100644 index d8e12534..00000000 --- a/vendor/k8s.io/gengo/generator/doc.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// Package generator defines an interface for code generators to implement. -// -// To use this package, you'll implement the "Package" and "Generator" -// interfaces; you'll call NewContext to load up the types you want to work -// with, and then you'll call one or more of the Execute methods. See the -// interface definitions for explanations. All output will have gofmt called on -// it automatically, so you do not need to worry about generating correct -// indentation. -// -// This package also exposes SnippetWriter. SnippetWriter reduces to a minimum -// the boilerplate involved in setting up a template from go's text/template -// package. Additionally, all naming systems in the Context will be added as -// functions to the parsed template, so that they can be called directly from -// your templates! -package generator // import "k8s.io/gengo/generator" diff --git a/vendor/k8s.io/gengo/generator/error_tracker.go b/vendor/k8s.io/gengo/generator/error_tracker.go deleted file mode 100644 index 964dae37..00000000 --- a/vendor/k8s.io/gengo/generator/error_tracker.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generator - -import ( - "io" -) - -// ErrorTracker tracks errors to the underlying writer, so that you can ignore -// them until you're ready to return. -type ErrorTracker struct { - io.Writer - err error -} - -// NewErrorTracker makes a new error tracker; note that it implements io.Writer. -func NewErrorTracker(w io.Writer) *ErrorTracker { - return &ErrorTracker{Writer: w} -} - -// Write intercepts calls to Write. -func (et *ErrorTracker) Write(p []byte) (n int, err error) { - if et.err != nil { - return 0, et.err - } - n, err = et.Writer.Write(p) - if err != nil { - et.err = err - } - return n, err -} - -// Error returns nil if no error has occurred, otherwise it returns the error. -func (et *ErrorTracker) Error() error { - return et.err -} diff --git a/vendor/k8s.io/gengo/generator/execute.go b/vendor/k8s.io/gengo/generator/execute.go deleted file mode 100644 index f096741b..00000000 --- a/vendor/k8s.io/gengo/generator/execute.go +++ /dev/null @@ -1,329 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generator - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - - "golang.org/x/tools/imports" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - - "k8s.io/klog/v2" -) - -func errs2strings(errors []error) []string { - strs := make([]string, len(errors)) - for i := range errors { - strs[i] = errors[i].Error() - } - return strs -} - -// ExecutePackages runs the generators for every package in 'packages'. 'outDir' -// is the base directory in which to place all the generated packages; it -// should be a physical path on disk, not an import path. e.g.: -// /path/to/home/path/to/gopath/src/ -// Each package has its import path already, this will be appended to 'outDir'. -func (c *Context) ExecutePackages(outDir string, packages Packages) error { - var errors []error - for _, p := range packages { - if err := c.ExecutePackage(outDir, p); err != nil { - errors = append(errors, err) - } - } - if len(errors) > 0 { - return fmt.Errorf("some packages had errors:\n%v\n", strings.Join(errs2strings(errors), "\n")) - } - return nil -} - -type DefaultFileType struct { - Format func([]byte) ([]byte, error) - Assemble func(io.Writer, *File) -} - -func (ft DefaultFileType) AssembleFile(f *File, pathname string) error { - klog.V(5).Infof("Assembling file %q", pathname) - destFile, err := os.Create(pathname) - if err != nil { - return err - } - defer destFile.Close() - - b := &bytes.Buffer{} - et := NewErrorTracker(b) - ft.Assemble(et, f) - if et.Error() != nil { - return et.Error() - } - if formatted, err := ft.Format(b.Bytes()); err != nil { - err = fmt.Errorf("unable to format file %q (%v).", pathname, err) - // Write the file anyway, so they can see what's going wrong and fix the generator. - if _, err2 := destFile.Write(b.Bytes()); err2 != nil { - return err2 - } - return err - } else { - _, err = destFile.Write(formatted) - return err - } -} - -func (ft DefaultFileType) VerifyFile(f *File, pathname string) error { - klog.V(5).Infof("Verifying file %q", pathname) - friendlyName := filepath.Join(f.PackageName, f.Name) - b := &bytes.Buffer{} - et := NewErrorTracker(b) - ft.Assemble(et, f) - if et.Error() != nil { - return et.Error() - } - formatted, err := ft.Format(b.Bytes()) - if err != nil { - return fmt.Errorf("unable to format the output for %q: %v", friendlyName, err) - } - existing, err := ioutil.ReadFile(pathname) - if err != nil { - return fmt.Errorf("unable to read file %q for comparison: %v", friendlyName, err) - } - if bytes.Compare(formatted, existing) == 0 { - return nil - } - // Be nice and find the first place where they differ - i := 0 - for i < len(formatted) && i < len(existing) && formatted[i] == existing[i] { - i++ - } - eDiff, fDiff := existing[i:], formatted[i:] - if len(eDiff) > 100 { - eDiff = eDiff[:100] - } - if len(fDiff) > 100 { - fDiff = fDiff[:100] - } - return fmt.Errorf("output for %q differs; first existing/expected diff: \n %q\n %q", friendlyName, string(eDiff), string(fDiff)) -} - -func assembleGolangFile(w io.Writer, f *File) { - w.Write(f.Header) - fmt.Fprintf(w, "package %v\n\n", f.PackageName) - - if len(f.Imports) > 0 { - fmt.Fprint(w, "import (\n") - for i := range f.Imports { - if strings.Contains(i, "\"") { - // they included quotes, or are using the - // `name "path/to/pkg"` format. - fmt.Fprintf(w, "\t%s\n", i) - } else { - fmt.Fprintf(w, "\t%q\n", i) - } - } - fmt.Fprint(w, ")\n\n") - } - - if f.Vars.Len() > 0 { - fmt.Fprint(w, "var (\n") - w.Write(f.Vars.Bytes()) - fmt.Fprint(w, ")\n\n") - } - - if f.Consts.Len() > 0 { - fmt.Fprint(w, "const (\n") - w.Write(f.Consts.Bytes()) - fmt.Fprint(w, ")\n\n") - } - - w.Write(f.Body.Bytes()) -} - -func importsWrapper(src []byte) ([]byte, error) { - return imports.Process("", src, nil) -} - -func NewGolangFile() *DefaultFileType { - return &DefaultFileType{ - Format: importsWrapper, - Assemble: assembleGolangFile, - } -} - -// format should be one line only, and not end with \n. -func addIndentHeaderComment(b *bytes.Buffer, format string, args ...interface{}) { - if b.Len() > 0 { - fmt.Fprintf(b, "\n// "+format+"\n", args...) - } else { - fmt.Fprintf(b, "// "+format+"\n", args...) - } -} - -func (c *Context) filteredBy(f func(*Context, *types.Type) bool) *Context { - c2 := *c - c2.Order = []*types.Type{} - for _, t := range c.Order { - if f(c, t) { - c2.Order = append(c2.Order, t) - } - } - return &c2 -} - -// make a new context; inheret c.Namers, but add on 'namers'. In case of a name -// collision, the namer in 'namers' wins. -func (c *Context) addNameSystems(namers namer.NameSystems) *Context { - if namers == nil { - return c - } - c2 := *c - // Copy the existing name systems so we don't corrupt a parent context - c2.Namers = namer.NameSystems{} - for k, v := range c.Namers { - c2.Namers[k] = v - } - - for name, namer := range namers { - c2.Namers[name] = namer - } - return &c2 -} - -// ExecutePackage executes a single package. 'outDir' is the base directory in -// which to place the package; it should be a physical path on disk, not an -// import path. e.g.: '/path/to/home/path/to/gopath/src/' The package knows its -// import path already, this will be appended to 'outDir'. -func (c *Context) ExecutePackage(outDir string, p Package) error { - path := filepath.Join(outDir, p.Path()) - - // When working outside of GOPATH, we typically won't want to generate the - // full path for a package. For example, if our current project's root/base - // package is github.com/foo/bar, outDir=., p.Path()=github.com/foo/bar/generated, - // then we really want to be writing files to ./generated, not ./github.com/foo/bar/generated. - // The following will trim a path prefix (github.com/foo/bar) from p.Path() to arrive at - // a relative path that works with projects not in GOPATH. - if c.TrimPathPrefix != "" { - separator := string(filepath.Separator) - if !strings.HasSuffix(c.TrimPathPrefix, separator) { - c.TrimPathPrefix += separator - } - - path = strings.TrimPrefix(path, c.TrimPathPrefix) - } - klog.V(5).Infof("Processing package %q, disk location %q", p.Name(), path) - // Filter out any types the *package* doesn't care about. - packageContext := c.filteredBy(p.Filter) - os.MkdirAll(path, 0755) - files := map[string]*File{} - for _, g := range p.Generators(packageContext) { - // Filter out types the *generator* doesn't care about. - genContext := packageContext.filteredBy(g.Filter) - // Now add any extra name systems defined by this generator - genContext = genContext.addNameSystems(g.Namers(genContext)) - - fileType := g.FileType() - if len(fileType) == 0 { - return fmt.Errorf("generator %q must specify a file type", g.Name()) - } - f := files[g.Filename()] - if f == nil { - // This is the first generator to reference this file, so start it. - f = &File{ - Name: g.Filename(), - FileType: fileType, - PackageName: p.Name(), - PackagePath: p.Path(), - PackageSourcePath: p.SourcePath(), - Header: p.Header(g.Filename()), - Imports: map[string]struct{}{}, - } - files[f.Name] = f - } else { - if f.FileType != g.FileType() { - return fmt.Errorf("file %q already has type %q, but generator %q wants to use type %q", f.Name, f.FileType, g.Name(), g.FileType()) - } - } - - if vars := g.PackageVars(genContext); len(vars) > 0 { - addIndentHeaderComment(&f.Vars, "Package-wide variables from generator %q.", g.Name()) - for _, v := range vars { - if _, err := fmt.Fprintf(&f.Vars, "%s\n", v); err != nil { - return err - } - } - } - if consts := g.PackageConsts(genContext); len(consts) > 0 { - addIndentHeaderComment(&f.Consts, "Package-wide consts from generator %q.", g.Name()) - for _, v := range consts { - if _, err := fmt.Fprintf(&f.Consts, "%s\n", v); err != nil { - return err - } - } - } - if err := genContext.executeBody(&f.Body, g); err != nil { - return err - } - if imports := g.Imports(genContext); len(imports) > 0 { - for _, i := range imports { - f.Imports[i] = struct{}{} - } - } - } - - var errors []error - for _, f := range files { - finalPath := filepath.Join(path, f.Name) - assembler, ok := c.FileTypes[f.FileType] - if !ok { - return fmt.Errorf("the file type %q registered for file %q does not exist in the context", f.FileType, f.Name) - } - var err error - if c.Verify { - err = assembler.VerifyFile(f, finalPath) - } else { - err = assembler.AssembleFile(f, finalPath) - } - if err != nil { - errors = append(errors, err) - } - } - if len(errors) > 0 { - return fmt.Errorf("errors in package %q:\n%v\n", p.Path(), strings.Join(errs2strings(errors), "\n")) - } - return nil -} - -func (c *Context) executeBody(w io.Writer, generator Generator) error { - et := NewErrorTracker(w) - if err := generator.Init(c, et); err != nil { - return err - } - for _, t := range c.Order { - if err := generator.GenerateType(c, t, et); err != nil { - return err - } - } - if err := generator.Finalize(c, et); err != nil { - return err - } - return et.Error() -} diff --git a/vendor/k8s.io/gengo/generator/generator.go b/vendor/k8s.io/gengo/generator/generator.go deleted file mode 100644 index 5614ae3b..00000000 --- a/vendor/k8s.io/gengo/generator/generator.go +++ /dev/null @@ -1,259 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generator - -import ( - "bytes" - "io" - - "k8s.io/gengo/namer" - "k8s.io/gengo/parser" - "k8s.io/gengo/types" -) - -// Package contains the contract for generating a package. -type Package interface { - // Name returns the package short name. - Name() string - // Path returns the package import path. - Path() string - // SourcePath returns the location of the package on disk. - SourcePath() string - - // Filter should return true if this package cares about this type. - // Otherwise, this type will be omitted from the type ordering for - // this package. - Filter(*Context, *types.Type) bool - - // Header should return a header for the file, including comment markers. - // Useful for copyright notices and doc strings. Include an - // autogeneration notice! Do not include the "package x" line. - Header(filename string) []byte - - // Generators returns the list of generators for this package. It is - // allowed for more than one generator to write to the same file. - // A Context is passed in case the list of generators depends on the - // input types. - Generators(*Context) []Generator -} - -type File struct { - Name string - FileType string - PackageName string - Header []byte - PackagePath string - PackageSourcePath string - Imports map[string]struct{} - Vars bytes.Buffer - Consts bytes.Buffer - Body bytes.Buffer -} - -type FileType interface { - AssembleFile(f *File, path string) error - VerifyFile(f *File, path string) error -} - -// Packages is a list of packages to generate. -type Packages []Package - -// Generator is the contract for anything that wants to do auto-generation. -// It's expected that the io.Writers passed to the below functions will be -// ErrorTrackers; this allows implementations to not check for io errors, -// making more readable code. -// -// The call order for the functions that take a Context is: -// 1. Filter() // Subsequent calls see only types that pass this. -// 2. Namers() // Subsequent calls see the namers provided by this. -// 3. PackageVars() -// 4. PackageConsts() -// 5. Init() -// 6. GenerateType() // Called N times, once per type in the context's Order. -// 7. Imports() -// -// You may have multiple generators for the same file. -type Generator interface { - // The name of this generator. Will be included in generated comments. - Name() string - - // Filter should return true if this generator cares about this type. - // (otherwise, GenerateType will not be called.) - // - // Filter is called before any of the generator's other functions; - // subsequent calls will get a context with only the types that passed - // this filter. - Filter(*Context, *types.Type) bool - - // If this generator needs special namers, return them here. These will - // override the original namers in the context if there is a collision. - // You may return nil if you don't need special names. These names will - // be available in the context passed to the rest of the generator's - // functions. - // - // A use case for this is to return a namer that tracks imports. - Namers(*Context) namer.NameSystems - - // Init should write an init function, and any other content that's not - // generated per-type. (It's not intended for generator specific - // initialization! Do that when your Package constructs the - // Generators.) - Init(*Context, io.Writer) error - - // Finalize should write finish up functions, and any other content that's not - // generated per-type. - Finalize(*Context, io.Writer) error - - // PackageVars should emit an array of variable lines. They will be - // placed in a var ( ... ) block. There's no need to include a leading - // \t or trailing \n. - PackageVars(*Context) []string - - // PackageConsts should emit an array of constant lines. They will be - // placed in a const ( ... ) block. There's no need to include a leading - // \t or trailing \n. - PackageConsts(*Context) []string - - // GenerateType should emit the code for a particular type. - GenerateType(*Context, *types.Type, io.Writer) error - - // Imports should return a list of necessary imports. They will be - // formatted correctly. You do not need to include quotation marks, - // return only the package name; alternatively, you can also return - // imports in the format `name "path/to/pkg"`. Imports will be called - // after Init, PackageVars, PackageConsts, and GenerateType, to allow - // you to keep track of what imports you actually need. - Imports(*Context) []string - - // Preferred file name of this generator, not including a path. It is - // allowed for multiple generators to use the same filename, but it's - // up to you to make sure they don't have colliding import names. - // TODO: provide per-file import tracking, removing the requirement - // that generators coordinate.. - Filename() string - - // A registered file type in the context to generate this file with. If - // the FileType is not found in the context, execution will stop. - FileType() string -} - -// Context is global context for individual generators to consume. -type Context struct { - // A map from the naming system to the names for that system. E.g., you - // might have public names and several private naming systems. - Namers namer.NameSystems - - // All the types, in case you want to look up something. - Universe types.Universe - - // Incoming imports, i.e. packages importing the given package. - incomingImports map[string][]string - - // Incoming transitive imports, i.e. the transitive closure of IncomingImports - incomingTransitiveImports map[string][]string - - // All the user-specified packages. This is after recursive expansion. - Inputs []string - - // The canonical ordering of the types (will be filtered by both the - // Package's and Generator's Filter methods). - Order []*types.Type - - // A set of types this context can process. If this is empty or nil, - // the default "golang" filetype will be provided. - FileTypes map[string]FileType - - // If true, Execute* calls will just verify that the existing output is - // correct. (You may set this after calling NewContext.) - Verify bool - - // Allows generators to add packages at runtime. - builder *parser.Builder - - // If specified, trim the prefix from a package's path before writing files. - TrimPathPrefix string -} - -// NewContext generates a context from the given builder, naming systems, and -// the naming system you wish to construct the canonical ordering from. -func NewContext(b *parser.Builder, nameSystems namer.NameSystems, canonicalOrderName string) (*Context, error) { - universe, err := b.FindTypes() - if err != nil { - return nil, err - } - - c := &Context{ - Namers: namer.NameSystems{}, - Universe: universe, - Inputs: b.FindPackages(), - FileTypes: map[string]FileType{ - GolangFileType: NewGolangFile(), - }, - builder: b, - } - - for name, systemNamer := range nameSystems { - c.Namers[name] = systemNamer - if name == canonicalOrderName { - orderer := namer.Orderer{Namer: systemNamer} - c.Order = orderer.OrderUniverse(universe) - } - } - return c, nil -} - -// IncomingImports returns the incoming imports for each package. The map is lazily computed. -func (ctxt *Context) IncomingImports() map[string][]string { - if ctxt.incomingImports == nil { - incoming := map[string][]string{} - for _, pkg := range ctxt.Universe { - for imp := range pkg.Imports { - incoming[imp] = append(incoming[imp], pkg.Path) - } - } - ctxt.incomingImports = incoming - } - return ctxt.incomingImports -} - -// TransitiveIncomingImports returns the transitive closure of the incoming imports for each package. -// The map is lazily computed. -func (ctxt *Context) TransitiveIncomingImports() map[string][]string { - if ctxt.incomingTransitiveImports == nil { - ctxt.incomingTransitiveImports = transitiveClosure(ctxt.IncomingImports()) - } - return ctxt.incomingTransitiveImports -} - -// AddDir adds a Go package to the context. The specified path must be a single -// go package import path. GOPATH, GOROOT, and the location of your go binary -// (`which go`) will all be searched, in the normal Go fashion. -// Deprecated. Please use AddDirectory. -func (ctxt *Context) AddDir(path string) error { - ctxt.incomingImports = nil - ctxt.incomingTransitiveImports = nil - return ctxt.builder.AddDirTo(path, &ctxt.Universe) -} - -// AddDirectory adds a Go package to the context. The specified path must be a -// single go package import path. GOPATH, GOROOT, and the location of your go -// binary (`which go`) will all be searched, in the normal Go fashion. -func (ctxt *Context) AddDirectory(path string) (*types.Package, error) { - ctxt.incomingImports = nil - ctxt.incomingTransitiveImports = nil - return ctxt.builder.AddDirectoryTo(path, &ctxt.Universe) -} diff --git a/vendor/k8s.io/gengo/generator/import_tracker.go b/vendor/k8s.io/gengo/generator/import_tracker.go deleted file mode 100644 index 99525c40..00000000 --- a/vendor/k8s.io/gengo/generator/import_tracker.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generator - -import ( - "go/token" - "strings" - - "k8s.io/klog/v2" - - "k8s.io/gengo/namer" - "k8s.io/gengo/types" -) - -// NewImportTrackerForPackage creates a new import tracker which is aware -// of a generator's output package. The tracker will not add import lines -// when symbols or types are added from the same package, and LocalNameOf -// will return empty string for the output package. -// -// e.g.: -// -// tracker := NewImportTrackerForPackage("bar.com/pkg/foo") -// tracker.AddSymbol(types.Name{"bar.com/pkg/foo.MyType"}) -// tracker.AddSymbol(types.Name{"bar.com/pkg/baz.MyType"}) -// tracker.AddSymbol(types.Name{"bar.com/pkg/baz/baz.MyType"}) -// -// tracker.LocalNameOf("bar.com/pkg/foo") -> "" -// tracker.LocalNameOf("bar.com/pkg/baz") -> "baz" -// tracker.LocalNameOf("bar.com/pkg/baz/baz") -> "bazbaz" -// tracker.ImportLines() -> {`baz "bar.com/pkg/baz"`, `bazbaz "bar.com/pkg/baz/baz"`} -func NewImportTrackerForPackage(local string, typesToAdd ...*types.Type) *namer.DefaultImportTracker { - tracker := namer.NewDefaultImportTracker(types.Name{Package: local}) - tracker.IsInvalidType = func(*types.Type) bool { return false } - tracker.LocalName = func(name types.Name) string { return golangTrackerLocalName(&tracker, name) } - tracker.PrintImport = func(path, name string) string { return name + " \"" + path + "\"" } - - tracker.AddTypes(typesToAdd...) - return &tracker -} - -func NewImportTracker(typesToAdd ...*types.Type) *namer.DefaultImportTracker { - return NewImportTrackerForPackage("", typesToAdd...) -} - -func golangTrackerLocalName(tracker namer.ImportTracker, t types.Name) string { - path := t.Package - - // Using backslashes in package names causes gengo to produce Go code which - // will not compile with the gc compiler. See the comment on GoSeperator. - if strings.ContainsRune(path, '\\') { - klog.Warningf("Warning: backslash used in import path '%v', this is unsupported.\n", path) - } - - dirs := strings.Split(path, namer.GoSeperator) - for n := len(dirs) - 1; n >= 0; n-- { - // follow kube convention of not having anything between directory names - name := strings.Join(dirs[n:], "") - name = strings.Replace(name, "_", "", -1) - // These characters commonly appear in import paths for go - // packages, but aren't legal go names. So we'll sanitize. - name = strings.Replace(name, ".", "", -1) - name = strings.Replace(name, "-", "", -1) - if _, found := tracker.PathOf(name); found { - // This name collides with some other package - continue - } - - // If the import name is a Go keyword, prefix with an underscore. - if token.Lookup(name).IsKeyword() { - name = "_" + name - } - return name - } - panic("can't find import for " + path) -} diff --git a/vendor/k8s.io/gengo/generator/snippet_writer.go b/vendor/k8s.io/gengo/generator/snippet_writer.go deleted file mode 100644 index 590775ff..00000000 --- a/vendor/k8s.io/gengo/generator/snippet_writer.go +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package generator - -import ( - "fmt" - "io" - "runtime" - "text/template" -) - -// SnippetWriter is an attempt to make the template library usable. -// Methods are chainable, and you don't have to check Error() until you're all -// done. -type SnippetWriter struct { - w io.Writer - context *Context - // Left & right delimiters. text/template defaults to "{{" and "}}" - // which is totally unusable for go code based templates. - left, right string - funcMap template.FuncMap - err error -} - -// w is the destination; left and right are the delimiters; @ and $ are both -// reasonable choices. -// -// c is used to make a function for every naming system, to which you can pass -// a type and get the corresponding name. -func NewSnippetWriter(w io.Writer, c *Context, left, right string) *SnippetWriter { - sw := &SnippetWriter{ - w: w, - context: c, - left: left, - right: right, - funcMap: template.FuncMap{}, - } - for name, namer := range c.Namers { - sw.funcMap[name] = namer.Name - } - return sw -} - -// Do parses format and runs args through it. You can have arbitrary logic in -// the format (see the text/template documentation), but consider running many -// short templates with ordinary go logic in between--this may be more -// readable. Do is chainable. Any error causes every other call to do to be -// ignored, and the error will be returned by Error(). So you can check it just -// once, at the end of your function. -// -// 'args' can be quite literally anything; read the text/template documentation -// for details. Maps and structs work particularly nicely. Conveniently, the -// types package is designed to have structs that are easily referencable from -// the template language. -// -// Example: -// -// sw := generator.NewSnippetWriter(outBuffer, context, "$", "$") -// sw.Do(`The public type name is: $.type|public$`, map[string]interface{}{"type": t}) -// return sw.Error() -// -// Where: -// * "$" starts a template directive -// * "." references the entire thing passed as args -// * "type" therefore sees a map and looks up the key "type" -// * "|" means "pass the thing on the left to the thing on the right" -// * "public" is the name of a naming system, so the SnippetWriter has given -// the template a function called "public" that takes a *types.Type and -// returns the naming system's name. E.g., if the type is "string" this might -// return "String". -// * the second "$" ends the template directive. -// -// The map is actually not necessary. The below does the same thing: -// -// sw.Do(`The public type name is: $.|public$`, t) -// -// You may or may not find it more readable to use the map with a descriptive -// key, but if you want to pass more than one arg, the map or a custom struct -// becomes a requirement. You can do arbitrary logic inside these templates, -// but you should consider doing the logic in go and stitching them together -// for the sake of your readers. -// -// TODO: Change Do() to optionally take a list of pairs of parameters (key, value) -// and have it construct a combined map with that and args. -func (s *SnippetWriter) Do(format string, args interface{}) *SnippetWriter { - if s.err != nil { - return s - } - // Name the template by source file:line so it can be found when - // there's an error. - _, file, line, _ := runtime.Caller(1) - tmpl, err := template. - New(fmt.Sprintf("%s:%d", file, line)). - Delims(s.left, s.right). - Funcs(s.funcMap). - Parse(format) - if err != nil { - s.err = err - return s - } - err = tmpl.Execute(s.w, args) - if err != nil { - s.err = err - } - return s -} - -// Args exists to make it convenient to construct arguments for -// SnippetWriter.Do. -type Args map[interface{}]interface{} - -// With makes a copy of a and adds the given key, value pair. -func (a Args) With(key, value interface{}) Args { - a2 := Args{key: value} - for k, v := range a { - a2[k] = v - } - return a2 -} - -// WithArgs makes a copy of a and adds the given arguments. -func (a Args) WithArgs(rhs Args) Args { - a2 := Args{} - for k, v := range rhs { - a2[k] = v - } - for k, v := range a { - a2[k] = v - } - return a2 -} - -func (s *SnippetWriter) Out() io.Writer { - return s.w -} - -// Error returns any encountered error. -func (s *SnippetWriter) Error() error { - return s.err -} diff --git a/vendor/k8s.io/gengo/generator/transitive_closure.go b/vendor/k8s.io/gengo/generator/transitive_closure.go deleted file mode 100644 index 385a49fc..00000000 --- a/vendor/k8s.io/gengo/generator/transitive_closure.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package generator - -import "sort" - -type edge struct { - from string - to string -} - -func transitiveClosure(in map[string][]string) map[string][]string { - adj := make(map[edge]bool) - imports := make(map[string]struct{}) - for from, tos := range in { - for _, to := range tos { - adj[edge{from, to}] = true - imports[to] = struct{}{} - } - } - - // Warshal's algorithm - for k := range in { - for i := range in { - if !adj[edge{i, k}] { - continue - } - for j := range imports { - if adj[edge{i, j}] { - continue - } - if adj[edge{k, j}] { - adj[edge{i, j}] = true - } - } - } - } - - out := make(map[string][]string, len(in)) - for i := range in { - for j := range imports { - if adj[edge{i, j}] { - out[i] = append(out[i], j) - } - } - - sort.Strings(out[i]) - } - - return out -} diff --git a/vendor/k8s.io/gengo/namer/doc.go b/vendor/k8s.io/gengo/namer/doc.go deleted file mode 100644 index 8a44ea99..00000000 --- a/vendor/k8s.io/gengo/namer/doc.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// Package namer has support for making different type naming systems. -// -// This is because sometimes you want to refer to the literal type, sometimes -// you want to make a name for the thing you're generating, and you want to -// make the name based on the type. For example, if you have `type foo string`, -// you want to be able to generate something like `func FooPrinter(f *foo) { -// Print(string(*f)) }`; that is, you want to refer to a public name, a literal -// name, and the underlying literal name. -// -// This package supports the idea of a "Namer" and a set of "NameSystems" to -// support these use cases. -// -// Additionally, a "RawNamer" can optionally keep track of what needs to be -// imported. -package namer // import "k8s.io/gengo/namer" diff --git a/vendor/k8s.io/gengo/namer/import_tracker.go b/vendor/k8s.io/gengo/namer/import_tracker.go deleted file mode 100644 index 2bf1d503..00000000 --- a/vendor/k8s.io/gengo/namer/import_tracker.go +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package namer - -import ( - "sort" - - "k8s.io/gengo/types" -) - -// ImportTracker may be passed to a namer.RawNamer, to track the imports needed -// for the types it names. -// -// TODO: pay attention to the package name (instead of renaming every package). -type DefaultImportTracker struct { - pathToName map[string]string - // forbidden names are in here. (e.g. "go" is a directory in which - // there is code, but "go" is not a legal name for a package, so we put - // it here to prevent us from naming any package "go") - nameToPath map[string]string - local types.Name - - // Returns true if a given types is an invalid type and should be ignored. - IsInvalidType func(*types.Type) bool - // Returns the final local name for the given name - LocalName func(types.Name) string - // Returns the "import" line for a given (path, name). - PrintImport func(string, string) string -} - -func NewDefaultImportTracker(local types.Name) DefaultImportTracker { - return DefaultImportTracker{ - pathToName: map[string]string{}, - nameToPath: map[string]string{}, - local: local, - } -} - -func (tracker *DefaultImportTracker) AddTypes(types ...*types.Type) { - for _, t := range types { - tracker.AddType(t) - } -} -func (tracker *DefaultImportTracker) AddSymbol(symbol types.Name) { - if tracker.local.Package == symbol.Package { - return - } - - if len(symbol.Package) == 0 { - return - } - path := symbol.Path - if len(path) == 0 { - path = symbol.Package - } - if _, ok := tracker.pathToName[path]; ok { - return - } - - name := tracker.LocalName(symbol) - tracker.nameToPath[name] = path - tracker.pathToName[path] = name -} - -func (tracker *DefaultImportTracker) AddType(t *types.Type) { - if tracker.local.Package == t.Name.Package { - return - } - - if tracker.IsInvalidType(t) { - if t.Kind == types.Builtin { - return - } - if _, ok := tracker.nameToPath[t.Name.Package]; !ok { - tracker.nameToPath[t.Name.Package] = "" - } - return - } - - tracker.AddSymbol(t.Name) -} - -func (tracker *DefaultImportTracker) ImportLines() []string { - importPaths := []string{} - for path := range tracker.pathToName { - importPaths = append(importPaths, path) - } - sort.Sort(sort.StringSlice(importPaths)) - out := []string{} - for _, path := range importPaths { - out = append(out, tracker.PrintImport(path, tracker.pathToName[path])) - } - return out -} - -// LocalNameOf returns the name you would use to refer to the package at the -// specified path within the body of a file. -func (tracker *DefaultImportTracker) LocalNameOf(path string) string { - return tracker.pathToName[path] -} - -// PathOf returns the path that a given localName is referring to within the -// body of a file. -func (tracker *DefaultImportTracker) PathOf(localName string) (string, bool) { - name, ok := tracker.nameToPath[localName] - return name, ok -} diff --git a/vendor/k8s.io/gengo/namer/namer.go b/vendor/k8s.io/gengo/namer/namer.go deleted file mode 100644 index a0f1a24a..00000000 --- a/vendor/k8s.io/gengo/namer/namer.go +++ /dev/null @@ -1,395 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package namer - -import ( - "fmt" - "path/filepath" - "strconv" - "strings" - - "k8s.io/gengo/types" -) - -const ( - // GoSeperator is used to split go import paths. - // Forward slash is used instead of filepath.Seperator because it is the - // only universally-accepted path delimiter and the only delimiter not - // potentially forbidden by Go compilers. (In particular gc does not allow - // the use of backslashes in import paths.) - // See https://golang.org/ref/spec#Import_declarations. - // See also https://github.com/kubernetes/gengo/issues/83#issuecomment-367040772. - GoSeperator = "/" -) - -// Returns whether a name is a private Go name. -func IsPrivateGoName(name string) bool { - return len(name) == 0 || strings.ToLower(name[:1]) == name[:1] -} - -// NewPublicNamer is a helper function that returns a namer that makes -// CamelCase names. See the NameStrategy struct for an explanation of the -// arguments to this constructor. -func NewPublicNamer(prependPackageNames int, ignoreWords ...string) *NameStrategy { - n := &NameStrategy{ - Join: Joiner(IC, IC), - IgnoreWords: map[string]bool{}, - PrependPackageNames: prependPackageNames, - } - for _, w := range ignoreWords { - n.IgnoreWords[w] = true - } - return n -} - -// NewPrivateNamer is a helper function that returns a namer that makes -// camelCase names. See the NameStrategy struct for an explanation of the -// arguments to this constructor. -func NewPrivateNamer(prependPackageNames int, ignoreWords ...string) *NameStrategy { - n := &NameStrategy{ - Join: Joiner(IL, IC), - IgnoreWords: map[string]bool{}, - PrependPackageNames: prependPackageNames, - } - for _, w := range ignoreWords { - n.IgnoreWords[w] = true - } - return n -} - -// NewRawNamer will return a Namer that makes a name by which you would -// directly refer to a type, optionally keeping track of the import paths -// necessary to reference the names it provides. Tracker may be nil. -// The 'pkg' is the full package name, in which the Namer is used - all -// types from that package will be referenced by just type name without -// referencing the package. -// -// For example, if the type is map[string]int, a raw namer will literally -// return "map[string]int". -// -// Or if the type, in package foo, is "type Bar struct { ... }", then the raw -// namer will return "foo.Bar" as the name of the type, and if 'tracker' was -// not nil, will record that package foo needs to be imported. -func NewRawNamer(pkg string, tracker ImportTracker) *rawNamer { - return &rawNamer{pkg: pkg, tracker: tracker} -} - -// Names is a map from Type to name, as defined by some Namer. -type Names map[*types.Type]string - -// Namer takes a type, and assigns a name. -// -// The purpose of this complexity is so that you can assign coherent -// side-by-side systems of names for the types. For example, you might want a -// public interface, a private implementation struct, and also to reference -// literally the type name. -// -// Note that it is safe to call your own Name() function recursively to find -// the names of keys, elements, etc. This is because anonymous types can't have -// cycles in their names, and named types don't require the sort of recursion -// that would be problematic. -type Namer interface { - Name(*types.Type) string -} - -// NameSystems is a map of a system name to a namer for that system. -type NameSystems map[string]Namer - -// NameStrategy is a general Namer. The easiest way to use it is to copy the -// Public/PrivateNamer variables, and modify the members you wish to change. -// -// The Name method produces a name for the given type, of the forms: -// Anonymous types: -// Named types: -// -// In all cases, every part of the name is run through the capitalization -// functions. -// -// The IgnoreWords map can be set if you have directory names that are -// semantically meaningless for naming purposes, e.g. "proto". -// -// Prefix and Suffix can be used to disambiguate parallel systems of type -// names. For example, if you want to generate an interface and an -// implementation, you might want to suffix one with "Interface" and the other -// with "Implementation". Another common use-- if you want to generate private -// types, and one of your source types could be "string", you can't use the -// default lowercase private namer. You'll have to add a suffix or prefix. -type NameStrategy struct { - Prefix, Suffix string - Join func(pre string, parts []string, post string) string - - // Add non-meaningful package directory names here (e.g. "proto") and - // they will be ignored. - IgnoreWords map[string]bool - - // If > 0, prepend exactly that many package directory names (or as - // many as there are). Package names listed in "IgnoreWords" will be - // ignored. - // - // For example, if Ignore words lists "proto" and type Foo is in - // pkg/server/frobbing/proto, then a value of 1 will give a type name - // of FrobbingFoo, 2 gives ServerFrobbingFoo, etc. - PrependPackageNames int - - // A cache of names thus far assigned by this namer. - Names -} - -// IC ensures the first character is uppercase. -func IC(in string) string { - if in == "" { - return in - } - return strings.ToUpper(in[:1]) + in[1:] -} - -// IL ensures the first character is lowercase. -func IL(in string) string { - if in == "" { - return in - } - return strings.ToLower(in[:1]) + in[1:] -} - -// Joiner lets you specify functions that preprocess the various components of -// a name before joining them. You can construct e.g. camelCase or CamelCase or -// any other way of joining words. (See the IC and IL convenience functions.) -func Joiner(first, others func(string) string) func(pre string, in []string, post string) string { - return func(pre string, in []string, post string) string { - tmp := []string{others(pre)} - for i := range in { - tmp = append(tmp, others(in[i])) - } - tmp = append(tmp, others(post)) - return first(strings.Join(tmp, "")) - } -} - -func (ns *NameStrategy) removePrefixAndSuffix(s string) string { - // The join function may have changed capitalization. - lowerIn := strings.ToLower(s) - lowerP := strings.ToLower(ns.Prefix) - lowerS := strings.ToLower(ns.Suffix) - b, e := 0, len(s) - if strings.HasPrefix(lowerIn, lowerP) { - b = len(ns.Prefix) - } - if strings.HasSuffix(lowerIn, lowerS) { - e -= len(ns.Suffix) - } - return s[b:e] -} - -var ( - importPathNameSanitizer = strings.NewReplacer("-", "_", ".", "") -) - -// filters out unwanted directory names and sanitizes remaining names. -func (ns *NameStrategy) filterDirs(path string) []string { - allDirs := strings.Split(path, GoSeperator) - dirs := make([]string, 0, len(allDirs)) - for _, p := range allDirs { - if ns.IgnoreWords == nil || !ns.IgnoreWords[p] { - dirs = append(dirs, importPathNameSanitizer.Replace(p)) - } - } - return dirs -} - -// See the comment on NameStrategy. -func (ns *NameStrategy) Name(t *types.Type) string { - if ns.Names == nil { - ns.Names = Names{} - } - if s, ok := ns.Names[t]; ok { - return s - } - - if t.Name.Package != "" { - dirs := append(ns.filterDirs(t.Name.Package), t.Name.Name) - i := ns.PrependPackageNames + 1 - dn := len(dirs) - if i > dn { - i = dn - } - name := ns.Join(ns.Prefix, dirs[dn-i:], ns.Suffix) - ns.Names[t] = name - return name - } - - // Only anonymous types remain. - var name string - switch t.Kind { - case types.Builtin: - name = ns.Join(ns.Prefix, []string{t.Name.Name}, ns.Suffix) - case types.Map: - name = ns.Join(ns.Prefix, []string{ - "Map", - ns.removePrefixAndSuffix(ns.Name(t.Key)), - "To", - ns.removePrefixAndSuffix(ns.Name(t.Elem)), - }, ns.Suffix) - case types.Slice: - name = ns.Join(ns.Prefix, []string{ - "Slice", - ns.removePrefixAndSuffix(ns.Name(t.Elem)), - }, ns.Suffix) - case types.Array: - name = ns.Join(ns.Prefix, []string{ - "Array", - ns.removePrefixAndSuffix(fmt.Sprintf("%d", t.Len)), - ns.removePrefixAndSuffix(ns.Name(t.Elem)), - }, ns.Suffix) - case types.Pointer: - name = ns.Join(ns.Prefix, []string{ - "Pointer", - ns.removePrefixAndSuffix(ns.Name(t.Elem)), - }, ns.Suffix) - case types.Struct: - names := []string{"Struct"} - for _, m := range t.Members { - names = append(names, ns.removePrefixAndSuffix(ns.Name(m.Type))) - } - name = ns.Join(ns.Prefix, names, ns.Suffix) - case types.Chan: - name = ns.Join(ns.Prefix, []string{ - "Chan", - ns.removePrefixAndSuffix(ns.Name(t.Elem)), - }, ns.Suffix) - case types.Interface: - // TODO: add to name test - names := []string{"Interface"} - for _, m := range t.Methods { - // TODO: include function signature - names = append(names, m.Name.Name) - } - name = ns.Join(ns.Prefix, names, ns.Suffix) - case types.Func: - // TODO: add to name test - parts := []string{"Func"} - for _, pt := range t.Signature.Parameters { - parts = append(parts, ns.removePrefixAndSuffix(ns.Name(pt))) - } - parts = append(parts, "Returns") - for _, rt := range t.Signature.Results { - parts = append(parts, ns.removePrefixAndSuffix(ns.Name(rt))) - } - name = ns.Join(ns.Prefix, parts, ns.Suffix) - default: - name = "unnameable_" + string(t.Kind) - } - ns.Names[t] = name - return name -} - -// ImportTracker allows a raw namer to keep track of the packages needed for -// import. You can implement yourself or use the one in the generation package. -type ImportTracker interface { - AddType(*types.Type) - AddSymbol(types.Name) - LocalNameOf(packagePath string) string - PathOf(localName string) (string, bool) - ImportLines() []string -} - -type rawNamer struct { - pkg string - tracker ImportTracker - Names -} - -// Name makes a name the way you'd write it to literally refer to type t, -// making ordinary assumptions about how you've imported t's package (or using -// r.tracker to specifically track the package imports). -func (r *rawNamer) Name(t *types.Type) string { - if r.Names == nil { - r.Names = Names{} - } - if name, ok := r.Names[t]; ok { - return name - } - if t.Name.Package != "" { - var name string - if r.tracker != nil { - r.tracker.AddType(t) - if t.Name.Package == r.pkg { - name = t.Name.Name - } else { - name = r.tracker.LocalNameOf(t.Name.Package) + "." + t.Name.Name - } - } else { - if t.Name.Package == r.pkg { - name = t.Name.Name - } else { - name = filepath.Base(t.Name.Package) + "." + t.Name.Name - } - } - r.Names[t] = name - return name - } - var name string - switch t.Kind { - case types.Builtin: - name = t.Name.Name - case types.Map: - name = "map[" + r.Name(t.Key) + "]" + r.Name(t.Elem) - case types.Slice: - name = "[]" + r.Name(t.Elem) - case types.Array: - l := strconv.Itoa(int(t.Len)) - name = "[" + l + "]" + r.Name(t.Elem) - case types.Pointer: - name = "*" + r.Name(t.Elem) - case types.Struct: - elems := []string{} - for _, m := range t.Members { - elems = append(elems, m.Name+" "+r.Name(m.Type)) - } - name = "struct{" + strings.Join(elems, "; ") + "}" - case types.Chan: - // TODO: include directionality - name = "chan " + r.Name(t.Elem) - case types.Interface: - // TODO: add to name test - elems := []string{} - for _, m := range t.Methods { - // TODO: include function signature - elems = append(elems, m.Name.Name) - } - name = "interface{" + strings.Join(elems, "; ") + "}" - case types.Func: - // TODO: add to name test - params := []string{} - for _, pt := range t.Signature.Parameters { - params = append(params, r.Name(pt)) - } - results := []string{} - for _, rt := range t.Signature.Results { - results = append(results, r.Name(rt)) - } - name = "func(" + strings.Join(params, ",") + ")" - if len(results) == 1 { - name += " " + results[0] - } else if len(results) > 1 { - name += " (" + strings.Join(results, ",") + ")" - } - default: - name = "unnameable_" + string(t.Kind) - } - r.Names[t] = name - return name -} diff --git a/vendor/k8s.io/gengo/namer/order.go b/vendor/k8s.io/gengo/namer/order.go deleted file mode 100644 index fd89be9b..00000000 --- a/vendor/k8s.io/gengo/namer/order.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package namer - -import ( - "sort" - - "k8s.io/gengo/types" -) - -// Orderer produces an ordering of types given a Namer. -type Orderer struct { - Namer -} - -// OrderUniverse assigns a name to every type in the Universe, including Types, -// Functions and Variables, and returns a list sorted by those names. -func (o *Orderer) OrderUniverse(u types.Universe) []*types.Type { - list := tList{ - namer: o.Namer, - } - for _, p := range u { - for _, t := range p.Types { - list.types = append(list.types, t) - } - for _, f := range p.Functions { - list.types = append(list.types, f) - } - for _, v := range p.Variables { - list.types = append(list.types, v) - } - for _, v := range p.Constants { - list.types = append(list.types, v) - } - } - sort.Sort(list) - return list.types -} - -// OrderTypes assigns a name to every type, and returns a list sorted by those -// names. -func (o *Orderer) OrderTypes(typeList []*types.Type) []*types.Type { - list := tList{ - namer: o.Namer, - types: typeList, - } - sort.Sort(list) - return list.types -} - -type tList struct { - namer Namer - types []*types.Type -} - -func (t tList) Len() int { return len(t.types) } -func (t tList) Less(i, j int) bool { return t.namer.Name(t.types[i]) < t.namer.Name(t.types[j]) } -func (t tList) Swap(i, j int) { t.types[i], t.types[j] = t.types[j], t.types[i] } diff --git a/vendor/k8s.io/gengo/namer/plural_namer.go b/vendor/k8s.io/gengo/namer/plural_namer.go deleted file mode 100644 index 0e3ebbf2..00000000 --- a/vendor/k8s.io/gengo/namer/plural_namer.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package namer - -import ( - "strings" - - "k8s.io/gengo/types" -) - -var consonants = "bcdfghjklmnpqrstvwxyz" - -type pluralNamer struct { - // key is the case-sensitive type name, value is the case-insensitive - // intended output. - exceptions map[string]string - finalize func(string) string -} - -// NewPublicPluralNamer returns a namer that returns the plural form of the input -// type's name, starting with a uppercase letter. -func NewPublicPluralNamer(exceptions map[string]string) *pluralNamer { - return &pluralNamer{exceptions, IC} -} - -// NewPrivatePluralNamer returns a namer that returns the plural form of the input -// type's name, starting with a lowercase letter. -func NewPrivatePluralNamer(exceptions map[string]string) *pluralNamer { - return &pluralNamer{exceptions, IL} -} - -// NewAllLowercasePluralNamer returns a namer that returns the plural form of the input -// type's name, with all letters in lowercase. -func NewAllLowercasePluralNamer(exceptions map[string]string) *pluralNamer { - return &pluralNamer{exceptions, strings.ToLower} -} - -// Name returns the plural form of the type's name. If the type's name is found -// in the exceptions map, the map value is returned. -func (r *pluralNamer) Name(t *types.Type) string { - singular := t.Name.Name - var plural string - var ok bool - if plural, ok = r.exceptions[singular]; ok { - return r.finalize(plural) - } - if len(singular) < 2 { - return r.finalize(singular) - } - - switch rune(singular[len(singular)-1]) { - case 's', 'x', 'z': - plural = esPlural(singular) - case 'y': - sl := rune(singular[len(singular)-2]) - if isConsonant(sl) { - plural = iesPlural(singular) - } else { - plural = sPlural(singular) - } - case 'h': - sl := rune(singular[len(singular)-2]) - if sl == 'c' || sl == 's' { - plural = esPlural(singular) - } else { - plural = sPlural(singular) - } - case 'e': - sl := rune(singular[len(singular)-2]) - if sl == 'f' { - plural = vesPlural(singular[:len(singular)-1]) - } else { - plural = sPlural(singular) - } - case 'f': - plural = vesPlural(singular) - default: - plural = sPlural(singular) - } - return r.finalize(plural) -} - -func iesPlural(singular string) string { - return singular[:len(singular)-1] + "ies" -} - -func vesPlural(singular string) string { - return singular[:len(singular)-1] + "ves" -} - -func esPlural(singular string) string { - return singular + "es" -} - -func sPlural(singular string) string { - return singular + "s" -} - -func isConsonant(char rune) bool { - for _, c := range consonants { - if char == c { - return true - } - } - return false -} diff --git a/vendor/k8s.io/gengo/parser/doc.go b/vendor/k8s.io/gengo/parser/doc.go deleted file mode 100644 index 8231b6d4..00000000 --- a/vendor/k8s.io/gengo/parser/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// Package parser provides code to parse go files, type-check them, extract the -// types. -package parser // import "k8s.io/gengo/parser" diff --git a/vendor/k8s.io/gengo/parser/parse.go b/vendor/k8s.io/gengo/parser/parse.go deleted file mode 100644 index bbd71929..00000000 --- a/vendor/k8s.io/gengo/parser/parse.go +++ /dev/null @@ -1,925 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package parser - -import ( - "fmt" - "go/ast" - "go/build" - "go/constant" - "go/parser" - "go/token" - tc "go/types" - "io/ioutil" - "os" - "os/exec" - "path" - "path/filepath" - "regexp" - "sort" - "strings" - - "k8s.io/gengo/types" - "k8s.io/klog/v2" -) - -// This clarifies when a pkg path has been canonicalized. -type importPathString string - -// Builder lets you add all the go files in all the packages that you care -// about, then constructs the type source data. -type Builder struct { - context *build.Context - - // If true, include *_test.go - IncludeTestFiles bool - - // Map of package names to more canonical information about the package. - // This might hold the same value for multiple names, e.g. if someone - // referenced ./pkg/name or in the case of vendoring, which canonicalizes - // differently that what humans would type. - // - // This must only be accessed via getLoadedBuildPackage and setLoadedBuildPackage - buildPackages map[importPathString]*build.Package - - fset *token.FileSet - // map of package path to list of parsed files - parsed map[importPathString][]parsedFile - // map of package path to absolute path (to prevent overlap) - absPaths map[importPathString]string - - // Set by typeCheckPackage(), used by importPackage() and friends. - typeCheckedPackages map[importPathString]*tc.Package - - // Map of package path to whether the user requested it or it was from - // an import. - userRequested map[importPathString]bool - - // All comments from everywhere in every parsed file. - endLineToCommentGroup map[fileLine]*ast.CommentGroup - - // map of package to list of packages it imports. - importGraph map[importPathString]map[string]struct{} -} - -// parsedFile is for tracking files with name -type parsedFile struct { - name string - file *ast.File -} - -// key type for finding comments. -type fileLine struct { - file string - line int -} - -// New constructs a new builder. -func New() *Builder { - c := build.Default - if c.GOROOT == "" { - if p, err := exec.Command("which", "go").CombinedOutput(); err == nil { - // The returned string will have some/path/bin/go, so remove the last two elements. - c.GOROOT = filepath.Dir(filepath.Dir(strings.Trim(string(p), "\n"))) - } else { - klog.Warningf("Warning: $GOROOT not set, and unable to run `which go` to find it: %v\n", err) - } - } - // Force this to off, since we don't properly parse CGo. All symbols must - // have non-CGo equivalents. - c.CgoEnabled = false - return &Builder{ - context: &c, - buildPackages: map[importPathString]*build.Package{}, - typeCheckedPackages: map[importPathString]*tc.Package{}, - fset: token.NewFileSet(), - parsed: map[importPathString][]parsedFile{}, - absPaths: map[importPathString]string{}, - userRequested: map[importPathString]bool{}, - endLineToCommentGroup: map[fileLine]*ast.CommentGroup{}, - importGraph: map[importPathString]map[string]struct{}{}, - } -} - -// AddBuildTags adds the specified build tags to the parse context. -func (b *Builder) AddBuildTags(tags ...string) { - b.context.BuildTags = append(b.context.BuildTags, tags...) -} - -func (b *Builder) getLoadedBuildPackage(importPath string) (*build.Package, bool) { - canonicalized := canonicalizeImportPath(importPath) - if string(canonicalized) != importPath { - klog.V(5).Infof("getLoadedBuildPackage: %s normalized to %s", importPath, canonicalized) - } - buildPkg, ok := b.buildPackages[canonicalized] - return buildPkg, ok -} -func (b *Builder) setLoadedBuildPackage(importPath string, buildPkg *build.Package) { - canonicalizedImportPath := canonicalizeImportPath(importPath) - if string(canonicalizedImportPath) != importPath { - klog.V(5).Infof("setLoadedBuildPackage: importPath %s normalized to %s", importPath, canonicalizedImportPath) - } - - canonicalizedBuildPkgImportPath := canonicalizeImportPath(buildPkg.ImportPath) - if string(canonicalizedBuildPkgImportPath) != buildPkg.ImportPath { - klog.V(5).Infof("setLoadedBuildPackage: buildPkg.ImportPath %s normalized to %s", buildPkg.ImportPath, canonicalizedBuildPkgImportPath) - } - - if canonicalizedImportPath != canonicalizedBuildPkgImportPath { - klog.V(5).Infof("setLoadedBuildPackage: normalized importPath (%s) differs from buildPkg.ImportPath (%s)", canonicalizedImportPath, canonicalizedBuildPkgImportPath) - } - b.buildPackages[canonicalizedImportPath] = buildPkg - b.buildPackages[canonicalizedBuildPkgImportPath] = buildPkg -} - -// Get package information from the go/build package. Automatically excludes -// e.g. test files and files for other platforms-- there is quite a bit of -// logic of that nature in the build package. -func (b *Builder) importBuildPackage(dir string) (*build.Package, error) { - if buildPkg, ok := b.getLoadedBuildPackage(dir); ok { - return buildPkg, nil - } - // This validates the `package foo // github.com/bar/foo` comments. - buildPkg, err := b.importWithMode(dir, build.ImportComment) - if err != nil { - if _, ok := err.(*build.NoGoError); !ok { - return nil, fmt.Errorf("unable to import %q: %v", dir, err) - } - } - if buildPkg == nil { - // Might be an empty directory. Try to just find the dir. - buildPkg, err = b.importWithMode(dir, build.FindOnly) - if err != nil { - return nil, err - } - } - - // Remember it under the user-provided name. - klog.V(5).Infof("saving buildPackage %s", dir) - b.setLoadedBuildPackage(dir, buildPkg) - - return buildPkg, nil -} - -// AddFileForTest adds a file to the set, without verifying that the provided -// pkg actually exists on disk. The pkg must be of the form "canonical/pkg/path" -// and the path must be the absolute path to the file. Because this bypasses -// the normal recursive finding of package dependencies (on disk), test should -// sort their test files topologically first, so all deps are resolved by the -// time we need them. -func (b *Builder) AddFileForTest(pkg string, path string, src []byte) error { - if err := b.addFile(importPathString(pkg), path, src, true); err != nil { - return err - } - if _, err := b.typeCheckPackage(importPathString(pkg), true); err != nil { - return err - } - return nil -} - -// addFile adds a file to the set. The pkgPath must be of the form -// "canonical/pkg/path" and the path must be the absolute path to the file. A -// flag indicates whether this file was user-requested or just from following -// the import graph. -func (b *Builder) addFile(pkgPath importPathString, path string, src []byte, userRequested bool) error { - for _, p := range b.parsed[pkgPath] { - if path == p.name { - klog.V(5).Infof("addFile %s %s already parsed, skipping", pkgPath, path) - return nil - } - } - klog.V(6).Infof("addFile %s %s", pkgPath, path) - p, err := parser.ParseFile(b.fset, path, src, parser.DeclarationErrors|parser.ParseComments) - if err != nil { - return err - } - - // This is redundant with addDir, but some tests call AddFileForTest, which - // call into here without calling addDir. - b.userRequested[pkgPath] = userRequested || b.userRequested[pkgPath] - - b.parsed[pkgPath] = append(b.parsed[pkgPath], parsedFile{path, p}) - for _, c := range p.Comments { - position := b.fset.Position(c.End()) - b.endLineToCommentGroup[fileLine{position.Filename, position.Line}] = c - } - - // We have to get the packages from this specific file, in case the - // user added individual files instead of entire directories. - if b.importGraph[pkgPath] == nil { - b.importGraph[pkgPath] = map[string]struct{}{} - } - for _, im := range p.Imports { - importedPath := strings.Trim(im.Path.Value, `"`) - b.importGraph[pkgPath][importedPath] = struct{}{} - } - return nil -} - -// AddDir adds an entire directory, scanning it for go files. 'dir' should have -// a single go package in it. GOPATH, GOROOT, and the location of your go -// binary (`which go`) will all be searched if dir doesn't literally resolve. -func (b *Builder) AddDir(dir string) error { - _, err := b.importPackage(dir, true) - return err -} - -// AddDirRecursive is just like AddDir, but it also recursively adds -// subdirectories; it returns an error only if the path couldn't be resolved; -// any directories recursed into without go source are ignored. -func (b *Builder) AddDirRecursive(dir string) error { - // Add the root. - if _, err := b.importPackage(dir, true); err != nil { - klog.Warningf("Ignoring directory %v: %v", dir, err) - } - - // filepath.Walk does not follow symlinks. We therefore evaluate symlinks and use that with - // filepath.Walk. - buildPkg, ok := b.getLoadedBuildPackage(dir) - if !ok { - return fmt.Errorf("no loaded build package for %s", dir) - } - realPath, err := filepath.EvalSymlinks(buildPkg.Dir) - if err != nil { - return err - } - - fn := func(filePath string, info os.FileInfo, err error) error { - if info != nil && info.IsDir() { - rel := filepath.ToSlash(strings.TrimPrefix(filePath, realPath)) - if rel != "" { - // Make a pkg path. - buildPkg, ok := b.getLoadedBuildPackage(dir) - if !ok { - return fmt.Errorf("no loaded build package for %s", dir) - } - pkg := path.Join(string(canonicalizeImportPath(buildPkg.ImportPath)), rel) - - // Add it. - if _, err := b.importPackage(pkg, true); err != nil { - klog.Warningf("Ignoring child directory %v: %v", pkg, err) - } - } - } - return nil - } - if err := filepath.Walk(realPath, fn); err != nil { - return err - } - return nil -} - -// AddDirTo adds an entire directory to a given Universe. Unlike AddDir, this -// processes the package immediately, which makes it safe to use from within a -// generator (rather than just at init time. 'dir' must be a single go package. -// GOPATH, GOROOT, and the location of your go binary (`which go`) will all be -// searched if dir doesn't literally resolve. -// Deprecated. Please use AddDirectoryTo. -func (b *Builder) AddDirTo(dir string, u *types.Universe) error { - // We want all types from this package, as if they were directly added - // by the user. They WERE added by the user, in effect. - if _, err := b.importPackage(dir, true); err != nil { - return err - } - pkg, ok := b.getLoadedBuildPackage(dir) - if !ok { - return fmt.Errorf("no such package: %q", dir) - } - return b.findTypesIn(canonicalizeImportPath(pkg.ImportPath), u) -} - -// AddDirectoryTo adds an entire directory to a given Universe. Unlike AddDir, -// this processes the package immediately, which makes it safe to use from -// within a generator (rather than just at init time. 'dir' must be a single go -// package. GOPATH, GOROOT, and the location of your go binary (`which go`) -// will all be searched if dir doesn't literally resolve. -func (b *Builder) AddDirectoryTo(dir string, u *types.Universe) (*types.Package, error) { - // We want all types from this package, as if they were directly added - // by the user. They WERE added by the user, in effect. - if _, err := b.importPackage(dir, true); err != nil { - return nil, err - } - pkg, ok := b.getLoadedBuildPackage(dir) - if !ok || pkg == nil { - return nil, fmt.Errorf("no such package: %q", dir) - } - path := canonicalizeImportPath(pkg.ImportPath) - if err := b.findTypesIn(path, u); err != nil { - return nil, err - } - return u.Package(string(path)), nil -} - -// The implementation of AddDir. A flag indicates whether this directory was -// user-requested or just from following the import graph. -func (b *Builder) addDir(dir string, userRequested bool) error { - klog.V(5).Infof("addDir %s", dir) - buildPkg, err := b.importBuildPackage(dir) - if err != nil { - return err - } - canonicalPackage := canonicalizeImportPath(buildPkg.ImportPath) - pkgPath := canonicalPackage - if dir != string(canonicalPackage) { - klog.V(5).Infof("addDir %s, canonical path is %s", dir, pkgPath) - } - - // Sanity check the pkg dir has not changed. - if prev, found := b.absPaths[pkgPath]; found { - if buildPkg.Dir != prev { - return fmt.Errorf("package %q (%s) previously resolved to %s", pkgPath, buildPkg.Dir, prev) - } - } else { - b.absPaths[pkgPath] = buildPkg.Dir - } - - files := []string{} - files = append(files, buildPkg.GoFiles...) - if b.IncludeTestFiles { - files = append(files, buildPkg.TestGoFiles...) - } - - for _, file := range files { - if !strings.HasSuffix(file, ".go") { - continue - } - absPath := filepath.Join(buildPkg.Dir, file) - data, err := ioutil.ReadFile(absPath) - if err != nil { - return fmt.Errorf("while loading %q: %v", absPath, err) - } - err = b.addFile(pkgPath, absPath, data, userRequested) - if err != nil { - return fmt.Errorf("while parsing %q: %v", absPath, err) - } - } - return nil -} - -// regexErrPackageNotFound helps test the expected error for not finding a package. -var regexErrPackageNotFound = regexp.MustCompile(`^unable to import ".*?":.*`) - -func isErrPackageNotFound(err error) bool { - return regexErrPackageNotFound.MatchString(err.Error()) -} - -// importPackage is a function that will be called by the type check package when it -// needs to import a go package. 'path' is the import path. -func (b *Builder) importPackage(dir string, userRequested bool) (*tc.Package, error) { - klog.V(5).Infof("importPackage %s", dir) - - var pkgPath = importPathString(dir) - - // Get the canonical path if we can. - if buildPkg, _ := b.getLoadedBuildPackage(dir); buildPkg != nil { - canonicalPackage := canonicalizeImportPath(buildPkg.ImportPath) - klog.V(5).Infof("importPackage %s, canonical path is %s", dir, canonicalPackage) - pkgPath = canonicalPackage - } - - // If we have not seen this before, process it now. - ignoreError := false - if _, found := b.parsed[pkgPath]; !found { - // Ignore errors in paths that we're importing solely because - // they're referenced by other packages. - ignoreError = true - - // Add it. - if err := b.addDir(dir, userRequested); err != nil { - if isErrPackageNotFound(err) { - klog.V(6).Info(err) - return nil, nil - } - - return nil, err - } - - // Get the canonical path now that it has been added. - if buildPkg, _ := b.getLoadedBuildPackage(dir); buildPkg != nil { - canonicalPackage := canonicalizeImportPath(buildPkg.ImportPath) - klog.V(5).Infof("importPackage %s, canonical path is %s", dir, canonicalPackage) - pkgPath = canonicalPackage - } - } - - // If it was previously known, just check that the user-requestedness hasn't - // changed. - b.userRequested[pkgPath] = userRequested || b.userRequested[pkgPath] - - // Run the type checker. We may end up doing this to pkgs that are already - // done, or are in the queue to be done later, but it will short-circuit, - // and we can't miss pkgs that are only depended on. - pkg, err := b.typeCheckPackage(pkgPath, !ignoreError) - if err != nil { - switch { - case ignoreError && pkg != nil: - klog.V(4).Infof("type checking encountered some issues in %q, but ignoring.\n", pkgPath) - case !ignoreError && pkg != nil: - klog.V(3).Infof("type checking encountered some errors in %q\n", pkgPath) - return nil, err - default: - return nil, err - } - } - - return pkg, nil -} - -type importAdapter struct { - b *Builder -} - -func (a importAdapter) Import(path string) (*tc.Package, error) { - return a.b.importPackage(path, false) -} - -// typeCheckPackage will attempt to return the package even if there are some -// errors, so you may check whether the package is nil or not even if you get -// an error. -func (b *Builder) typeCheckPackage(pkgPath importPathString, logErr bool) (*tc.Package, error) { - klog.V(5).Infof("typeCheckPackage %s", pkgPath) - if pkg, ok := b.typeCheckedPackages[pkgPath]; ok { - if pkg != nil { - klog.V(6).Infof("typeCheckPackage %s already done", pkgPath) - return pkg, nil - } - // We store a nil right before starting work on a package. So - // if we get here and it's present and nil, that means there's - // another invocation of this function on the call stack - // already processing this package. - return nil, fmt.Errorf("circular dependency for %q", pkgPath) - } - parsedFiles, ok := b.parsed[pkgPath] - if !ok { - return nil, fmt.Errorf("No files for pkg %q", pkgPath) - } - files := make([]*ast.File, len(parsedFiles)) - for i := range parsedFiles { - files[i] = parsedFiles[i].file - } - b.typeCheckedPackages[pkgPath] = nil - c := tc.Config{ - IgnoreFuncBodies: true, - // Note that importAdapter can call b.importPackage which calls this - // method. So there can't be cycles in the import graph. - Importer: importAdapter{b}, - Error: func(err error) { - if logErr { - klog.V(2).Infof("type checker: %v\n", err) - } else { - klog.V(3).Infof("type checker: %v\n", err) - } - }, - } - pkg, err := c.Check(string(pkgPath), b.fset, files, nil) - b.typeCheckedPackages[pkgPath] = pkg // record the result whether or not there was an error - return pkg, err -} - -// FindPackages fetches a list of the user-imported packages. -// Note that you need to call b.FindTypes() first. -func (b *Builder) FindPackages() []string { - // Iterate packages in a predictable order. - pkgPaths := []string{} - for k := range b.typeCheckedPackages { - pkgPaths = append(pkgPaths, string(k)) - } - sort.Strings(pkgPaths) - - result := []string{} - for _, pkgPath := range pkgPaths { - if b.userRequested[importPathString(pkgPath)] { - // Since walkType is recursive, all types that are in packages that - // were directly mentioned will be included. We don't need to - // include all types in all transitive packages, though. - result = append(result, pkgPath) - } - } - return result -} - -// FindTypes finalizes the package imports, and searches through all the -// packages for types. -func (b *Builder) FindTypes() (types.Universe, error) { - // Take a snapshot of pkgs to iterate, since this will recursively mutate - // b.parsed. Iterate in a predictable order. - pkgPaths := []string{} - for pkgPath := range b.parsed { - pkgPaths = append(pkgPaths, string(pkgPath)) - } - sort.Strings(pkgPaths) - - u := types.Universe{} - for _, pkgPath := range pkgPaths { - if err := b.findTypesIn(importPathString(pkgPath), &u); err != nil { - return nil, err - } - } - return u, nil -} - -// addCommentsToType takes any accumulated comment lines prior to obj and -// attaches them to the type t. -func (b *Builder) addCommentsToType(obj tc.Object, t *types.Type) { - c1 := b.priorCommentLines(obj.Pos(), 1) - // c1.Text() is safe if c1 is nil - t.CommentLines = splitLines(c1.Text()) - if c1 == nil { - t.SecondClosestCommentLines = splitLines(b.priorCommentLines(obj.Pos(), 2).Text()) - } else { - t.SecondClosestCommentLines = splitLines(b.priorCommentLines(c1.List[0].Slash, 2).Text()) - } -} - -// findTypesIn finalizes the package import and searches through the package -// for types. -func (b *Builder) findTypesIn(pkgPath importPathString, u *types.Universe) error { - klog.V(5).Infof("findTypesIn %s", pkgPath) - pkg := b.typeCheckedPackages[pkgPath] - if pkg == nil { - return fmt.Errorf("findTypesIn(%s): package is not known", pkgPath) - } - if !b.userRequested[pkgPath] { - // Since walkType is recursive, all types that the - // packages they asked for depend on will be included. - // But we don't need to include all types in all - // *packages* they depend on. - klog.V(5).Infof("findTypesIn %s: package is not user requested", pkgPath) - return nil - } - - // We're keeping this package. This call will create the record. - u.Package(string(pkgPath)).Name = pkg.Name() - u.Package(string(pkgPath)).Path = pkg.Path() - u.Package(string(pkgPath)).SourcePath = b.absPaths[pkgPath] - - for _, f := range b.parsed[pkgPath] { - if _, fileName := filepath.Split(f.name); fileName == "doc.go" { - tp := u.Package(string(pkgPath)) - // findTypesIn might be called multiple times. Clean up tp.Comments - // to avoid repeatedly fill same comments to it. - tp.Comments = []string{} - for i := range f.file.Comments { - tp.Comments = append(tp.Comments, splitLines(f.file.Comments[i].Text())...) - } - if f.file.Doc != nil { - tp.DocComments = splitLines(f.file.Doc.Text()) - } - } - } - - s := pkg.Scope() - for _, n := range s.Names() { - obj := s.Lookup(n) - tn, ok := obj.(*tc.TypeName) - if ok { - t := b.walkType(*u, nil, tn.Type()) - b.addCommentsToType(obj, t) - } - tf, ok := obj.(*tc.Func) - // We only care about functions, not concrete/abstract methods. - if ok && tf.Type() != nil && tf.Type().(*tc.Signature).Recv() == nil { - t := b.addFunction(*u, nil, tf) - b.addCommentsToType(obj, t) - } - tv, ok := obj.(*tc.Var) - if ok && !tv.IsField() { - t := b.addVariable(*u, nil, tv) - b.addCommentsToType(obj, t) - } - tconst, ok := obj.(*tc.Const) - if ok { - t := b.addConstant(*u, nil, tconst) - b.addCommentsToType(obj, t) - } - } - - importedPkgs := []string{} - for k := range b.importGraph[pkgPath] { - importedPkgs = append(importedPkgs, string(k)) - } - sort.Strings(importedPkgs) - for _, p := range importedPkgs { - u.AddImports(string(pkgPath), p) - } - return nil -} - -func (b *Builder) importWithMode(dir string, mode build.ImportMode) (*build.Package, error) { - // This is a bit of a hack. The srcDir argument to Import() should - // properly be the dir of the file which depends on the package to be - // imported, so that vendoring can work properly and local paths can - // resolve. We assume that there is only one level of vendoring, and that - // the CWD is inside the GOPATH, so this should be safe. Nobody should be - // using local (relative) paths except on the CLI, so CWD is also - // sufficient. - cwd, err := os.Getwd() - if err != nil { - return nil, fmt.Errorf("unable to get current directory: %v", err) - } - - // normalize to drop /vendor/ if present - dir = string(canonicalizeImportPath(dir)) - - buildPkg, err := b.context.Import(filepath.ToSlash(dir), cwd, mode) - if err != nil { - return nil, err - } - return buildPkg, nil -} - -// if there's a comment on the line `lines` before pos, return its text, otherwise "". -func (b *Builder) priorCommentLines(pos token.Pos, lines int) *ast.CommentGroup { - position := b.fset.Position(pos) - key := fileLine{position.Filename, position.Line - lines} - return b.endLineToCommentGroup[key] -} - -func splitLines(str string) []string { - return strings.Split(strings.TrimRight(str, "\n"), "\n") -} - -func tcFuncNameToName(in string) types.Name { - name := strings.TrimPrefix(in, "func ") - nameParts := strings.Split(name, "(") - return tcNameToName(nameParts[0]) -} - -func tcVarNameToName(in string) types.Name { - nameParts := strings.Split(in, " ") - // nameParts[0] is "var". - // nameParts[2:] is the type of the variable, we ignore it for now. - return tcNameToName(nameParts[1]) -} - -func tcNameToName(in string) types.Name { - // Detect anonymous type names. (These may have '.' characters because - // embedded types may have packages, so we detect them specially.) - if strings.HasPrefix(in, "struct{") || - strings.HasPrefix(in, "<-chan") || - strings.HasPrefix(in, "chan<-") || - strings.HasPrefix(in, "chan ") || - strings.HasPrefix(in, "func(") || - strings.HasPrefix(in, "func (") || - strings.HasPrefix(in, "*") || - strings.HasPrefix(in, "map[") || - strings.HasPrefix(in, "[") { - return types.Name{Name: in} - } - - // Otherwise, if there are '.' characters present, the name has a - // package path in front. - nameParts := strings.Split(in, ".") - name := types.Name{Name: in} - if n := len(nameParts); n >= 2 { - // The final "." is the name of the type--previous ones must - // have been in the package path. - name.Package, name.Name = strings.Join(nameParts[:n-1], "."), nameParts[n-1] - } - return name -} - -func (b *Builder) convertSignature(u types.Universe, t *tc.Signature) *types.Signature { - signature := &types.Signature{} - for i := 0; i < t.Params().Len(); i++ { - signature.Parameters = append(signature.Parameters, b.walkType(u, nil, t.Params().At(i).Type())) - signature.ParameterNames = append(signature.ParameterNames, t.Params().At(i).Name()) - } - for i := 0; i < t.Results().Len(); i++ { - signature.Results = append(signature.Results, b.walkType(u, nil, t.Results().At(i).Type())) - signature.ResultNames = append(signature.ResultNames, t.Results().At(i).Name()) - } - if r := t.Recv(); r != nil { - signature.Receiver = b.walkType(u, nil, r.Type()) - } - signature.Variadic = t.Variadic() - return signature -} - -// walkType adds the type, and any necessary child types. -func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *types.Type { - // Most of the cases are underlying types of the named type. - name := tcNameToName(in.String()) - if useName != nil { - name = *useName - } - - switch t := in.(type) { - case *tc.Struct: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Struct - for i := 0; i < t.NumFields(); i++ { - f := t.Field(i) - m := types.Member{ - Name: f.Name(), - Embedded: f.Anonymous(), - Tags: t.Tag(i), - Type: b.walkType(u, nil, f.Type()), - CommentLines: splitLines(b.priorCommentLines(f.Pos(), 1).Text()), - } - out.Members = append(out.Members, m) - } - return out - case *tc.Map: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Map - out.Elem = b.walkType(u, nil, t.Elem()) - out.Key = b.walkType(u, nil, t.Key()) - return out - case *tc.Pointer: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Pointer - out.Elem = b.walkType(u, nil, t.Elem()) - return out - case *tc.Slice: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Slice - out.Elem = b.walkType(u, nil, t.Elem()) - return out - case *tc.Array: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Array - out.Elem = b.walkType(u, nil, t.Elem()) - out.Len = in.(*tc.Array).Len() - return out - case *tc.Chan: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Chan - out.Elem = b.walkType(u, nil, t.Elem()) - // TODO: need to store direction, otherwise raw type name - // cannot be properly written. - return out - case *tc.Basic: - out := u.Type(types.Name{ - Package: "", - Name: t.Name(), - }) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Unsupported - return out - case *tc.Signature: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Func - out.Signature = b.convertSignature(u, t) - return out - case *tc.Interface: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Interface - t.Complete() - for i := 0; i < t.NumMethods(); i++ { - if out.Methods == nil { - out.Methods = map[string]*types.Type{} - } - method := t.Method(i) - name := tcNameToName(method.String()) - mt := b.walkType(u, &name, method.Type()) - mt.CommentLines = splitLines(b.priorCommentLines(method.Pos(), 1).Text()) - out.Methods[method.Name()] = mt - } - return out - case *tc.Named: - var out *types.Type - switch t.Underlying().(type) { - case *tc.Named, *tc.Basic, *tc.Map, *tc.Slice: - name := tcNameToName(t.String()) - out = u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Alias - out.Underlying = b.walkType(u, nil, t.Underlying()) - default: - // tc package makes everything "named" with an - // underlying anonymous type--we remove that annoying - // "feature" for users. This flattens those types - // together. - name := tcNameToName(t.String()) - if out := u.Type(name); out.Kind != types.Unknown { - return out // short circuit if we've already made this. - } - out = b.walkType(u, &name, t.Underlying()) - } - // If the underlying type didn't already add methods, add them. - // (Interface types will have already added methods.) - if len(out.Methods) == 0 { - for i := 0; i < t.NumMethods(); i++ { - if out.Methods == nil { - out.Methods = map[string]*types.Type{} - } - method := t.Method(i) - name := tcNameToName(method.String()) - mt := b.walkType(u, &name, method.Type()) - mt.CommentLines = splitLines(b.priorCommentLines(method.Pos(), 1).Text()) - out.Methods[method.Name()] = mt - } - } - return out - default: - out := u.Type(name) - if out.Kind != types.Unknown { - return out - } - out.Kind = types.Unsupported - klog.Warningf("Making unsupported type entry %q for: %#v\n", out, t) - return out - } -} - -func (b *Builder) addFunction(u types.Universe, useName *types.Name, in *tc.Func) *types.Type { - name := tcFuncNameToName(in.String()) - if useName != nil { - name = *useName - } - out := u.Function(name) - out.Kind = types.DeclarationOf - out.Underlying = b.walkType(u, nil, in.Type()) - return out -} - -func (b *Builder) addVariable(u types.Universe, useName *types.Name, in *tc.Var) *types.Type { - name := tcVarNameToName(in.String()) - if useName != nil { - name = *useName - } - out := u.Variable(name) - out.Kind = types.DeclarationOf - out.Underlying = b.walkType(u, nil, in.Type()) - return out -} - -func (b *Builder) addConstant(u types.Universe, useName *types.Name, in *tc.Const) *types.Type { - name := tcVarNameToName(in.String()) - if useName != nil { - name = *useName - } - out := u.Constant(name) - out.Kind = types.DeclarationOf - out.Underlying = b.walkType(u, nil, in.Type()) - - var constval string - - // For strings, we use `StringVal()` to get the un-truncated, - // un-quoted string. For other values, `.String()` is preferable to - // get something relatively human readable (especially since for - // floating point types, `ExactString()` will generate numeric - // expressions using `big.(*Float).Text()`. - switch in.Val().Kind() { - case constant.String: - constval = constant.StringVal(in.Val()) - default: - constval = in.Val().String() - } - - out.ConstValue = &constval - return out -} - -// canonicalizeImportPath takes an import path and returns the actual package. -// It doesn't support nested vendoring. -func canonicalizeImportPath(importPath string) importPathString { - if !strings.Contains(importPath, "/vendor/") { - return importPathString(importPath) - } - - return importPathString(importPath[strings.Index(importPath, "/vendor/")+len("/vendor/"):]) -} diff --git a/vendor/k8s.io/gengo/types/comments.go b/vendor/k8s.io/gengo/types/comments.go deleted file mode 100644 index 8150c383..00000000 --- a/vendor/k8s.io/gengo/types/comments.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// Package types contains go type information, packaged in a way that makes -// auto-generation convenient, whether by template or straight go functions. -package types - -import ( - "fmt" - "strings" -) - -// ExtractCommentTags parses comments for lines of the form: -// -// 'marker' + "key=value". -// -// Values are optional; "" is the default. A tag can be specified more than -// one time and all values are returned. If the resulting map has an entry for -// a key, the value (a slice) is guaranteed to have at least 1 element. -// -// Example: if you pass "+" for 'marker', and the following lines are in -// the comments: -// +foo=value1 -// +bar -// +foo=value2 -// +baz="qux" -// Then this function will return: -// map[string][]string{"foo":{"value1, "value2"}, "bar": {""}, "baz": {"qux"}} -func ExtractCommentTags(marker string, lines []string) map[string][]string { - out := map[string][]string{} - for _, line := range lines { - line = strings.Trim(line, " ") - if len(line) == 0 { - continue - } - if !strings.HasPrefix(line, marker) { - continue - } - // TODO: we could support multiple values per key if we split on spaces - kv := strings.SplitN(line[len(marker):], "=", 2) - if len(kv) == 2 { - out[kv[0]] = append(out[kv[0]], kv[1]) - } else if len(kv) == 1 { - out[kv[0]] = append(out[kv[0]], "") - } - } - return out -} - -// ExtractSingleBoolCommentTag parses comments for lines of the form: -// -// 'marker' + "key=value1" -// -// If the tag is not found, the default value is returned. Values are asserted -// to be boolean ("true" or "false"), and any other value will cause an error -// to be returned. If the key has multiple values, the first one will be used. -func ExtractSingleBoolCommentTag(marker string, key string, defaultVal bool, lines []string) (bool, error) { - values := ExtractCommentTags(marker, lines)[key] - if values == nil { - return defaultVal, nil - } - if values[0] == "true" { - return true, nil - } - if values[0] == "false" { - return false, nil - } - return false, fmt.Errorf("tag value for %q is not boolean: %q", key, values[0]) -} diff --git a/vendor/k8s.io/gengo/types/doc.go b/vendor/k8s.io/gengo/types/doc.go deleted file mode 100644 index 74a969a7..00000000 --- a/vendor/k8s.io/gengo/types/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -// Package types contains go type information, packaged in a way that makes -// auto-generation convenient, whether by template or straight go functions. -package types // import "k8s.io/gengo/types" diff --git a/vendor/k8s.io/gengo/types/flatten.go b/vendor/k8s.io/gengo/types/flatten.go deleted file mode 100644 index 585014e8..00000000 --- a/vendor/k8s.io/gengo/types/flatten.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package types - -// FlattenMembers recursively takes any embedded members and puts them in the -// top level, correctly hiding them if the top level hides them. There must not -// be a cycle-- that implies infinite members. -// -// This is useful for e.g. computing all the valid keys in a json struct, -// properly considering any configuration of embedded structs. -func FlattenMembers(m []Member) []Member { - embedded := []Member{} - normal := []Member{} - type nameInfo struct { - top bool - i int - } - names := map[string]nameInfo{} - for i := range m { - if m[i].Embedded && m[i].Type.Kind == Struct { - embedded = append(embedded, m[i]) - } else { - normal = append(normal, m[i]) - names[m[i].Name] = nameInfo{true, len(normal) - 1} - } - } - for i := range embedded { - for _, e := range FlattenMembers(embedded[i].Type.Members) { - if info, found := names[e.Name]; found { - if info.top { - continue - } - if n := normal[info.i]; n.Name == e.Name && n.Type == e.Type { - continue - } - panic("conflicting members") - } - normal = append(normal, e) - names[e.Name] = nameInfo{false, len(normal) - 1} - } - } - return normal -} diff --git a/vendor/k8s.io/gengo/types/types.go b/vendor/k8s.io/gengo/types/types.go deleted file mode 100644 index 77650255..00000000 --- a/vendor/k8s.io/gengo/types/types.go +++ /dev/null @@ -1,537 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -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. -*/ - -package types - -import "strings" - -// Ref makes a reference to the given type. It can only be used for e.g. -// passing to namers. -func Ref(packageName, typeName string) *Type { - return &Type{Name: Name{ - Name: typeName, - Package: packageName, - }} -} - -// A type name may have a package qualifier. -type Name struct { - // Empty if embedded or builtin. This is the package path unless Path is specified. - Package string - // The type name. - Name string - // An optional location of the type definition for languages that can have disjoint - // packages and paths. - Path string -} - -// String returns the name formatted as a string. -func (n Name) String() string { - if n.Package == "" { - return n.Name - } - return n.Package + "." + n.Name -} - -// ParseFullyQualifiedName parses a name like k8s.io/kubernetes/pkg/api.Pod into a Name. -func ParseFullyQualifiedName(fqn string) Name { - cs := strings.Split(fqn, ".") - pkg := "" - if len(cs) > 1 { - pkg = strings.Join(cs[0:len(cs)-1], ".") - } - return Name{ - Name: cs[len(cs)-1], - Package: pkg, - } -} - -// The possible classes of types. -type Kind string - -const ( - // Builtin is a primitive, like bool, string, int. - Builtin Kind = "Builtin" - Struct Kind = "Struct" - Map Kind = "Map" - Slice Kind = "Slice" - Pointer Kind = "Pointer" - - // Alias is an alias of another type, e.g. in: - // type Foo string - // type Bar Foo - // Bar is an alias of Foo. - // - // In the real go type system, Foo is a "Named" string; but to simplify - // generation, this type system will just say that Foo *is* a builtin. - // We then need "Alias" as a way for us to say that Bar *is* a Foo. - Alias Kind = "Alias" - - // Interface is any type that could have differing types at run time. - Interface Kind = "Interface" - - // Array is just like slice, but has a fixed length. - Array Kind = "Array" - - // The remaining types are included for completeness, but are not well - // supported. - Chan Kind = "Chan" - Func Kind = "Func" - - // DeclarationOf is different from other Kinds; it indicates that instead of - // representing an actual Type, the type is a declaration of an instance of - // a type. E.g., a top-level function, variable, or constant. See the - // comment for Type.Name for more detail. - DeclarationOf Kind = "DeclarationOf" - Unknown Kind = "" - Unsupported Kind = "Unsupported" - - // Protobuf is protobuf type. - Protobuf Kind = "Protobuf" -) - -// Package holds package-level information. -// Fields are public, as everything in this package, to enable consumption by -// templates (for example). But it is strongly encouraged for code to build by -// using the provided functions. -type Package struct { - // Canonical name of this package-- its path. - Path string - - // The location this package was loaded from - SourcePath string - - // Short name of this package; the name that appears in the - // 'package x' line. - Name string - - // The comment right above the package declaration in doc.go, if any. - DocComments []string - - // All comments from doc.go, if any. - // TODO: remove Comments and use DocComments everywhere. - Comments []string - - // Types within this package, indexed by their name (*not* including - // package name). - Types map[string]*Type - - // Functions within this package, indexed by their name (*not* including - // package name). - Functions map[string]*Type - - // Global variables within this package, indexed by their name (*not* including - // package name). - Variables map[string]*Type - - // Global constants within this package, indexed by their name (*not* including - // package name). - Constants map[string]*Type - - // Packages imported by this package, indexed by (canonicalized) - // package path. - Imports map[string]*Package -} - -// Has returns true if the given name references a type known to this package. -func (p *Package) Has(name string) bool { - _, has := p.Types[name] - return has -} - -// Type gets the given Type in this Package. If the Type is not already -// defined, this will add it and return the new Type value. The caller is -// expected to finish initialization. -func (p *Package) Type(typeName string) *Type { - if t, ok := p.Types[typeName]; ok { - return t - } - if p.Path == "" { - // Import the standard builtin types! - if t, ok := builtins.Types[typeName]; ok { - p.Types[typeName] = t - return t - } - } - t := &Type{Name: Name{Package: p.Path, Name: typeName}} - p.Types[typeName] = t - return t -} - -// Function gets the given function Type in this Package. If the function is -// not already defined, this will add it. If a function is added, it's the -// caller's responsibility to finish construction of the function by setting -// Underlying to the correct type. -func (p *Package) Function(funcName string) *Type { - if t, ok := p.Functions[funcName]; ok { - return t - } - t := &Type{Name: Name{Package: p.Path, Name: funcName}} - t.Kind = DeclarationOf - p.Functions[funcName] = t - return t -} - -// Variable gets the given variable Type in this Package. If the variable is -// not already defined, this will add it. If a variable is added, it's the caller's -// responsibility to finish construction of the variable by setting Underlying -// to the correct type. -func (p *Package) Variable(varName string) *Type { - if t, ok := p.Variables[varName]; ok { - return t - } - t := &Type{Name: Name{Package: p.Path, Name: varName}} - t.Kind = DeclarationOf - p.Variables[varName] = t - return t -} - -// Constant gets the given constant Type in this Package. If the constant is -// not already defined, this will add it. If a constant is added, it's the caller's -// responsibility to finish construction of the constant by setting Underlying -// to the correct type. -func (p *Package) Constant(constName string) *Type { - if t, ok := p.Constants[constName]; ok { - return t - } - t := &Type{Name: Name{Package: p.Path, Name: constName}} - t.Kind = DeclarationOf - p.Constants[constName] = t - return t -} - -// HasImport returns true if p imports packageName. Package names include the -// package directory. -func (p *Package) HasImport(packageName string) bool { - _, has := p.Imports[packageName] - return has -} - -// Universe is a map of all packages. The key is the package name, but you -// should use Package(), Type(), Function(), or Variable() instead of direct -// access. -type Universe map[string]*Package - -// Type returns the canonical type for the given fully-qualified name. Builtin -// types will always be found, even if they haven't been explicitly added to -// the map. If a non-existing type is requested, this will create (a marker for) -// it. -func (u Universe) Type(n Name) *Type { - return u.Package(n.Package).Type(n.Name) -} - -// Function returns the canonical function for the given fully-qualified name. -// If a non-existing function is requested, this will create (a marker for) it. -// If a marker is created, it's the caller's responsibility to finish -// construction of the function by setting Underlying to the correct type. -func (u Universe) Function(n Name) *Type { - return u.Package(n.Package).Function(n.Name) -} - -// Variable returns the canonical variable for the given fully-qualified name. -// If a non-existing variable is requested, this will create (a marker for) it. -// If a marker is created, it's the caller's responsibility to finish -// construction of the variable by setting Underlying to the correct type. -func (u Universe) Variable(n Name) *Type { - return u.Package(n.Package).Variable(n.Name) -} - -// Constant returns the canonical constant for the given fully-qualified name. -// If a non-existing constant is requested, this will create (a marker for) it. -// If a marker is created, it's the caller's responsibility to finish -// construction of the constant by setting Underlying to the correct type. -func (u Universe) Constant(n Name) *Type { - return u.Package(n.Package).Constant(n.Name) -} - -// AddImports registers import lines for packageName. May be called multiple times. -// You are responsible for canonicalizing all package paths. -func (u Universe) AddImports(packagePath string, importPaths ...string) { - p := u.Package(packagePath) - for _, i := range importPaths { - p.Imports[i] = u.Package(i) - } -} - -// Package returns the Package for the given path. -// If a non-existing package is requested, this will create (a marker for) it. -// If a marker is created, it's the caller's responsibility to finish -// construction of the package. -func (u Universe) Package(packagePath string) *Package { - if p, ok := u[packagePath]; ok { - return p - } - p := &Package{ - Path: packagePath, - Types: map[string]*Type{}, - Functions: map[string]*Type{}, - Variables: map[string]*Type{}, - Constants: map[string]*Type{}, - Imports: map[string]*Package{}, - } - u[packagePath] = p - return p -} - -// Type represents a subset of possible go types. -type Type struct { - // There are two general categories of types, those explicitly named - // and those anonymous. Named ones will have a non-empty package in the - // name field. - // - // An exception: If Kind == DeclarationOf, then this name is the name of a - // top-level function, variable, or const, and the type can be found in Underlying. - // We do this to allow the naming system to work against these objects, even - // though they aren't strictly speaking types. - Name Name - - // The general kind of this type. - Kind Kind - - // If there are comment lines immediately before the type definition, - // they will be recorded here. - CommentLines []string - - // If there are comment lines preceding the `CommentLines`, they will be - // recorded here. There are two cases: - // --- - // SecondClosestCommentLines - // a blank line - // CommentLines - // type definition - // --- - // - // or - // --- - // SecondClosestCommentLines - // a blank line - // type definition - // --- - SecondClosestCommentLines []string - - // If Kind == Struct - Members []Member - - // If Kind == Map, Slice, Pointer, or Chan - Elem *Type - - // If Kind == Map, this is the map's key type. - Key *Type - - // If Kind == Alias, this is the underlying type. - // If Kind == DeclarationOf, this is the type of the declaration. - Underlying *Type - - // If Kind == Interface, this is the set of all required functions. - // Otherwise, if this is a named type, this is the list of methods that - // type has. (All elements will have Kind=="Func") - Methods map[string]*Type - - // If Kind == func, this is the signature of the function. - Signature *Signature - - // ConstValue contains a stringified constant value if - // Kind == DeclarationOf and this is a constant value - // declaration. For string constants, this field contains - // the entire, un-quoted value. For other types, it contains - // a human-readable literal. - ConstValue *string - - // TODO: Add: - // * channel direction - - // If Kind == Array - Len int64 -} - -// String returns the name of the type. -func (t *Type) String() string { - return t.Name.String() -} - -// IsPrimitive returns whether the type is a built-in type or is an alias to a -// built-in type. For example: strings and aliases of strings are primitives, -// structs are not. -func (t *Type) IsPrimitive() bool { - if t.Kind == Builtin || (t.Kind == Alias && t.Underlying.Kind == Builtin) { - return true - } - return false -} - -// IsAssignable returns whether the type is deep-assignable. For example, -// slices and maps and pointers are shallow copies, but ints and strings are -// complete. -func (t *Type) IsAssignable() bool { - if t.IsPrimitive() { - return true - } - if t.Kind == Struct { - for _, m := range t.Members { - if !m.Type.IsAssignable() { - return false - } - } - return true - } - return false -} - -// IsAnonymousStruct returns true if the type is an anonymous struct or an alias -// to an anonymous struct. -func (t *Type) IsAnonymousStruct() bool { - return (t.Kind == Struct && t.Name.Name == "struct{}") || (t.Kind == Alias && t.Underlying.IsAnonymousStruct()) -} - -// A single struct member -type Member struct { - // The name of the member. - Name string - - // If the member is embedded (anonymous) this will be true, and the - // Name will be the type name. - Embedded bool - - // If there are comment lines immediately before the member in the type - // definition, they will be recorded here. - CommentLines []string - - // If there are tags along with this member, they will be saved here. - Tags string - - // The type of this member. - Type *Type -} - -// String returns the name and type of the member. -func (m Member) String() string { - return m.Name + " " + m.Type.String() -} - -// Signature is a function's signature. -type Signature struct { - // If a method of some type, this is the type it's a member of. - Receiver *Type - Parameters []*Type - ParameterNames []string - Results []*Type - ResultNames []string - - // True if the last in parameter is of the form ...T. - Variadic bool - - // If there are comment lines immediately before this - // signature/method/function declaration, they will be recorded here. - CommentLines []string -} - -// Built in types. -var ( - String = &Type{ - Name: Name{Name: "string"}, - Kind: Builtin, - } - Int64 = &Type{ - Name: Name{Name: "int64"}, - Kind: Builtin, - } - Int32 = &Type{ - Name: Name{Name: "int32"}, - Kind: Builtin, - } - Int16 = &Type{ - Name: Name{Name: "int16"}, - Kind: Builtin, - } - Int = &Type{ - Name: Name{Name: "int"}, - Kind: Builtin, - } - Uint64 = &Type{ - Name: Name{Name: "uint64"}, - Kind: Builtin, - } - Uint32 = &Type{ - Name: Name{Name: "uint32"}, - Kind: Builtin, - } - Uint16 = &Type{ - Name: Name{Name: "uint16"}, - Kind: Builtin, - } - Uint = &Type{ - Name: Name{Name: "uint"}, - Kind: Builtin, - } - Uintptr = &Type{ - Name: Name{Name: "uintptr"}, - Kind: Builtin, - } - Float64 = &Type{ - Name: Name{Name: "float64"}, - Kind: Builtin, - } - Float32 = &Type{ - Name: Name{Name: "float32"}, - Kind: Builtin, - } - Float = &Type{ - Name: Name{Name: "float"}, - Kind: Builtin, - } - Bool = &Type{ - Name: Name{Name: "bool"}, - Kind: Builtin, - } - Byte = &Type{ - Name: Name{Name: "byte"}, - Kind: Builtin, - } - - builtins = &Package{ - Types: map[string]*Type{ - "bool": Bool, - "string": String, - "int": Int, - "int64": Int64, - "int32": Int32, - "int16": Int16, - "int8": Byte, - "uint": Uint, - "uint64": Uint64, - "uint32": Uint32, - "uint16": Uint16, - "uint8": Byte, - "uintptr": Uintptr, - "byte": Byte, - "float": Float, - "float64": Float64, - "float32": Float32, - }, - Imports: map[string]*Package{}, - Path: "", - Name: "", - } -) - -func IsInteger(t *Type) bool { - switch t { - case Int, Int64, Int32, Int16, Uint, Uint64, Uint32, Uint16, Byte: - return true - default: - return false - } -} diff --git a/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go b/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go deleted file mode 100644 index 19783370..00000000 --- a/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package args - -import ( - "fmt" - "path/filepath" - - "github.com/spf13/pflag" - "k8s.io/gengo/args" -) - -// CustomArgs is used by the gengo framework to pass args specific to this generator. -type CustomArgs struct { - // ReportFilename is added to CustomArgs for specifying name of report file used - // by API linter. If specified, API rule violations will be printed to report file. - // Otherwise default value "-" will be used which indicates stdout. - ReportFilename string -} - -// NewDefaults returns default arguments for the generator. Returning the arguments instead -// of using default flag parsing allows registering custom arguments afterwards -func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { - // Default() sets a couple of flag default values for example the boilerplate. - // WithoutDefaultFlagParsing() disables implicit addition of command line flags and parsing, - // which allows registering custom arguments afterwards - genericArgs := args.Default().WithoutDefaultFlagParsing() - genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kube-openapi/boilerplate/boilerplate.go.txt") - - customArgs := &CustomArgs{} - genericArgs.CustomArgs = customArgs - - // Default value for report filename is "-", which stands for stdout - customArgs.ReportFilename = "-" - // Default value for output file base name - genericArgs.OutputFileBaseName = "openapi_generated" - - return genericArgs, customArgs -} - -// AddFlags add the generator flags to the flag set. -func (c *CustomArgs) AddFlags(fs *pflag.FlagSet) { - fs.StringVarP(&c.ReportFilename, "report-filename", "r", c.ReportFilename, "Name of report file used by API linter to print API violations. Default \"-\" stands for standard output. NOTE that if valid filename other than \"-\" is specified, API linter won't return error on detected API violations. This allows further check of existing API violations without stopping the OpenAPI generation toolchain.") -} - -// Validate checks the given arguments. -func Validate(genericArgs *args.GeneratorArgs) error { - c, ok := genericArgs.CustomArgs.(*CustomArgs) - if !ok { - return fmt.Errorf("input arguments don't contain valid custom arguments") - } - if len(c.ReportFilename) == 0 { - return fmt.Errorf("report filename cannot be empty. specify a valid filename or use \"-\" for stdout") - } - if len(genericArgs.OutputFileBaseName) == 0 { - return fmt.Errorf("output file base name cannot be empty") - } - if len(genericArgs.OutputPackagePath) == 0 { - return fmt.Errorf("output package cannot be empty") - } - return nil -} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/README.md b/vendor/k8s.io/kube-openapi/pkg/generators/README.md deleted file mode 100644 index 72b4e5fb..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Generate OpenAPI definitions - -- To generate definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines. -- To exclude a type or a member from a tagged package/type, add "+k8s:openapi-gen=false" tag to the comment lines. - -# OpenAPI Extensions - -OpenAPI spec can have extensions on types. To define one or more extensions on a type or its member -add `+k8s:openapi-gen=x-kubernetes-$NAME:$VALUE` to the comment lines before type/member. A type/member can -have multiple extensions. The rest of the line in the comment will be used as $VALUE so there is no need to -escape or quote the value string. Extensions can be used to pass more information to client generators or -documentation generators. For example a type might have a friendly name to be displayed in documentation or -being used in a client's fluent interface. - -# Custom OpenAPI type definitions - -Custom types which otherwise don't map directly to OpenAPI can override their -OpenAPI definition by implementing a function named "OpenAPIDefinition" with -the following signature: - -```go - import openapi "k8s.io/kube-openapi/pkg/common" - - // ... - - type Time struct { - time.Time - } - - func (_ Time) OpenAPIDefinition() openapi.OpenAPIDefinition { - return openapi.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "date-time", - }, - }, - } - } -``` - -Alternatively, the type can avoid the "openapi" import by defining the following -methods. The following example produces the same OpenAPI definition as the -example above: - -```go - func (_ Time) OpenAPISchemaType() []string { return []string{"string"} } - func (_ Time) OpenAPISchemaFormat() string { return "date-time" } -``` diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go b/vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go deleted file mode 100644 index 2763cf88..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go +++ /dev/null @@ -1,219 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "bytes" - "fmt" - "io" - "os" - "sort" - - "k8s.io/kube-openapi/pkg/generators/rules" - - "k8s.io/gengo/generator" - "k8s.io/gengo/types" - "k8s.io/klog/v2" -) - -const apiViolationFileType = "api-violation" - -type apiViolationFile struct { - // Since our file actually is unrelated to the package structure, use a - // path that hasn't been mangled by the framework. - unmangledPath string -} - -func (a apiViolationFile) AssembleFile(f *generator.File, path string) error { - path = a.unmangledPath - klog.V(2).Infof("Assembling file %q", path) - if path == "-" { - _, err := io.Copy(os.Stdout, &f.Body) - return err - } - - output, err := os.Create(path) - if err != nil { - return err - } - defer output.Close() - _, err = io.Copy(output, &f.Body) - return err -} - -func (a apiViolationFile) VerifyFile(f *generator.File, path string) error { - if path == "-" { - // Nothing to verify against. - return nil - } - path = a.unmangledPath - - formatted := f.Body.Bytes() - existing, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("unable to read file %q for comparison: %v", path, err) - } - if bytes.Compare(formatted, existing) == 0 { - return nil - } - - // Be nice and find the first place where they differ - // (Copied from gengo's default file type) - i := 0 - for i < len(formatted) && i < len(existing) && formatted[i] == existing[i] { - i++ - } - eDiff, fDiff := existing[i:], formatted[i:] - if len(eDiff) > 100 { - eDiff = eDiff[:100] - } - if len(fDiff) > 100 { - fDiff = fDiff[:100] - } - return fmt.Errorf("output for %q differs; first existing/expected diff: \n %q\n %q", path, string(eDiff), string(fDiff)) -} - -func newAPIViolationGen() *apiViolationGen { - return &apiViolationGen{ - linter: newAPILinter(), - } -} - -type apiViolationGen struct { - generator.DefaultGen - - linter *apiLinter -} - -func (v *apiViolationGen) FileType() string { return apiViolationFileType } -func (v *apiViolationGen) Filename() string { - return "this file is ignored by the file assembler" -} - -func (v *apiViolationGen) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - klog.V(5).Infof("validating API rules for type %v", t) - if err := v.linter.validate(t); err != nil { - return err - } - return nil -} - -// Finalize prints the API rule violations to report file (if specified from -// arguments) or stdout (default) -func (v *apiViolationGen) Finalize(c *generator.Context, w io.Writer) error { - // NOTE: we don't return error here because we assume that the report file will - // get evaluated afterwards to determine if error should be raised. For example, - // you can have make rules that compare the report file with existing known - // violations (whitelist) and determine no error if no change is detected. - v.linter.report(w) - return nil -} - -// apiLinter is the framework hosting multiple API rules and recording API rule -// violations -type apiLinter struct { - // API rules that implement APIRule interface and output API rule violations - rules []APIRule - violations []apiViolation -} - -// newAPILinter creates an apiLinter object with API rules in package rules. Please -// add APIRule here when new API rule is implemented. -func newAPILinter() *apiLinter { - return &apiLinter{ - rules: []APIRule{ - &rules.NamesMatch{}, - &rules.OmitEmptyMatchCase{}, - &rules.ListTypeMissing{}, - }, - } -} - -// apiViolation uniquely identifies single API rule violation -type apiViolation struct { - // Name of rule from APIRule.Name() - rule string - - packageName string - typeName string - - // Optional: name of field that violates API rule. Empty fieldName implies that - // the entire type violates the rule. - field string -} - -// apiViolations implements sort.Interface for []apiViolation based on the fields: rule, -// packageName, typeName and field. -type apiViolations []apiViolation - -func (a apiViolations) Len() int { return len(a) } -func (a apiViolations) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a apiViolations) Less(i, j int) bool { - if a[i].rule != a[j].rule { - return a[i].rule < a[j].rule - } - if a[i].packageName != a[j].packageName { - return a[i].packageName < a[j].packageName - } - if a[i].typeName != a[j].typeName { - return a[i].typeName < a[j].typeName - } - return a[i].field < a[j].field -} - -// APIRule is the interface for validating API rule on Go types -type APIRule interface { - // Validate evaluates API rule on type t and returns a list of field names in - // the type that violate the rule. Empty field name [""] implies the entire - // type violates the rule. - Validate(t *types.Type) ([]string, error) - - // Name returns the name of APIRule - Name() string -} - -// validate runs all API rules on type t and records any API rule violation -func (l *apiLinter) validate(t *types.Type) error { - for _, r := range l.rules { - klog.V(5).Infof("validating API rule %v for type %v", r.Name(), t) - fields, err := r.Validate(t) - if err != nil { - return err - } - for _, field := range fields { - l.violations = append(l.violations, apiViolation{ - rule: r.Name(), - packageName: t.Name.Package, - typeName: t.Name.Name, - field: field, - }) - } - } - return nil -} - -// report prints any API rule violation to writer w and returns error if violation exists -func (l *apiLinter) report(w io.Writer) error { - sort.Sort(apiViolations(l.violations)) - for _, v := range l.violations { - fmt.Fprintf(w, "API rule violation: %s,%s,%s,%s\n", v.rule, v.packageName, v.typeName, v.field) - } - if len(l.violations) > 0 { - return fmt.Errorf("API rule violations exist") - } - return nil -} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/config.go b/vendor/k8s.io/kube-openapi/pkg/generators/config.go deleted file mode 100644 index d728f2a3..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/config.go +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "path/filepath" - - "k8s.io/gengo/args" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - "k8s.io/klog/v2" - - generatorargs "k8s.io/kube-openapi/cmd/openapi-gen/args" -) - -type identityNamer struct{} - -func (_ identityNamer) Name(t *types.Type) string { - return t.Name.String() -} - -var _ namer.Namer = identityNamer{} - -// NameSystems returns the name system used by the generators in this package. -func NameSystems() namer.NameSystems { - return namer.NameSystems{ - "raw": namer.NewRawNamer("", nil), - "sorting_namer": identityNamer{}, - } -} - -// DefaultNameSystem returns the default name system for ordering the types to be -// processed by the generators in this package. -func DefaultNameSystem() string { - return "sorting_namer" -} - -func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { - boilerplate, err := arguments.LoadGoBoilerplate() - if err != nil { - klog.Fatalf("Failed loading boilerplate: %v", err) - } - header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...) - header = append(header, []byte( - ` -// This file was autogenerated by openapi-gen. Do not edit it manually! - -`)...) - - reportPath := "-" - if customArgs, ok := arguments.CustomArgs.(*generatorargs.CustomArgs); ok { - reportPath = customArgs.ReportFilename - } - context.FileTypes[apiViolationFileType] = apiViolationFile{ - unmangledPath: reportPath, - } - - return generator.Packages{ - &generator.DefaultPackage{ - PackageName: filepath.Base(arguments.OutputPackagePath), - PackagePath: arguments.OutputPackagePath, - HeaderText: header, - GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { - return []generator.Generator{ - newOpenAPIGen( - arguments.OutputFileBaseName, - arguments.OutputPackagePath, - ), - newAPIViolationGen(), - } - }, - FilterFunc: apiTypeFilterFunc, - }, - } -} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/enum.go b/vendor/k8s.io/kube-openapi/pkg/generators/enum.go deleted file mode 100644 index 292a3c76..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/enum.go +++ /dev/null @@ -1,162 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "regexp" - "sort" - "strings" - - "k8s.io/gengo/generator" - "k8s.io/gengo/types" -) - -const tagEnumType = "enum" -const enumTypeDescriptionHeader = "Possible enum values:" - -type enumValue struct { - Name string - Value string - Comment string -} - -type enumType struct { - Name types.Name - Values []*enumValue -} - -// enumMap is a map from the name to the matching enum type. -type enumMap map[types.Name]*enumType - -type enumContext struct { - enumTypes enumMap -} - -func newEnumContext(c *generator.Context) *enumContext { - return &enumContext{enumTypes: parseEnums(c)} -} - -// EnumType checks and finds the enumType for a given type. -// If the given type is a known enum type, returns the enumType, true -// Otherwise, returns nil, false -func (ec *enumContext) EnumType(t *types.Type) (enum *enumType, isEnum bool) { - // if t is a pointer, use its underlying type instead - if t.Kind == types.Pointer { - t = t.Elem - } - enum, ok := ec.enumTypes[t.Name] - return enum, ok -} - -// ValueStrings returns all possible values of the enum type as strings -// the results are sorted and quoted as Go literals. -func (et *enumType) ValueStrings() []string { - var values []string - for _, value := range et.Values { - // use "%q" format to generate a Go literal of the string const value - values = append(values, fmt.Sprintf("%q", value.Value)) - } - sort.Strings(values) - return values -} - -// DescriptionLines returns a description of the enum in this format: -// -// Possible enum values: -// - `"value1"` description 1 -// - `"value2"` description 2 -func (et *enumType) DescriptionLines() []string { - if len(et.Values) == 0 { - return nil - } - var lines []string - for _, value := range et.Values { - lines = append(lines, value.Description()) - } - sort.Strings(lines) - // Prepend an empty string to initiate a new paragraph. - return append([]string{"", enumTypeDescriptionHeader}, lines...) -} - -func parseEnums(c *generator.Context) enumMap { - // First, find the builtin "string" type - stringType := c.Universe.Type(types.Name{Name: "string"}) - - // find all enum types. - enumTypes := make(enumMap) - for _, p := range c.Universe { - for _, t := range p.Types { - if isEnumType(stringType, t) { - if _, ok := enumTypes[t.Name]; !ok { - enumTypes[t.Name] = &enumType{ - Name: t.Name, - } - } - } - } - } - - // find all enum values from constants, and try to match each with its type. - for _, p := range c.Universe { - for _, c := range p.Constants { - enumType := c.Underlying - if _, ok := enumTypes[enumType.Name]; ok { - value := &enumValue{ - Name: c.Name.Name, - Value: *c.ConstValue, - Comment: strings.Join(c.CommentLines, " "), - } - enumTypes[enumType.Name].appendValue(value) - } - } - } - - return enumTypes -} - -func (et *enumType) appendValue(value *enumValue) { - et.Values = append(et.Values, value) -} - -// Description returns the description line for the enumValue -// with the format: -// - `"FooValue"` is the Foo value -func (ev *enumValue) Description() string { - comment := strings.TrimSpace(ev.Comment) - // The comment should starts with the type name, trim it first. - comment = strings.TrimPrefix(comment, ev.Name) - // Trim the possible space after previous step. - comment = strings.TrimSpace(comment) - // The comment may be multiline, cascade all consecutive whitespaces. - comment = whitespaceRegex.ReplaceAllString(comment, " ") - return fmt.Sprintf(" - `%q` %s", ev.Value, comment) -} - -// isEnumType checks if a given type is an enum by the definition -// An enum type should be an alias of string and has tag '+enum' in its comment. -// Additionally, pass the type of builtin 'string' to check against. -func isEnumType(stringType *types.Type, t *types.Type) bool { - return t.Kind == types.Alias && t.Underlying == stringType && hasEnumTag(t) -} - -func hasEnumTag(t *types.Type) bool { - return types.ExtractCommentTags("+", t.CommentLines)[tagEnumType] != nil -} - -// whitespaceRegex is the regex for consecutive whitespaces. -var whitespaceRegex = regexp.MustCompile(`\s+`) diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/extension.go b/vendor/k8s.io/kube-openapi/pkg/generators/extension.go deleted file mode 100644 index e37d93ef..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/extension.go +++ /dev/null @@ -1,202 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "sort" - "strings" - - "k8s.io/gengo/examples/set-gen/sets" - "k8s.io/gengo/types" -) - -const extensionPrefix = "x-kubernetes-" - -// extensionAttributes encapsulates common traits for particular extensions. -type extensionAttributes struct { - xName string - kind types.Kind - allowedValues sets.String - enforceArray bool -} - -// Extension tag to openapi extension attributes -var tagToExtension = map[string]extensionAttributes{ - "patchMergeKey": { - xName: "x-kubernetes-patch-merge-key", - kind: types.Slice, - }, - "patchStrategy": { - xName: "x-kubernetes-patch-strategy", - kind: types.Slice, - allowedValues: sets.NewString("merge", "retainKeys"), - }, - "listMapKey": { - xName: "x-kubernetes-list-map-keys", - kind: types.Slice, - enforceArray: true, - }, - "listType": { - xName: "x-kubernetes-list-type", - kind: types.Slice, - allowedValues: sets.NewString("atomic", "set", "map"), - }, - "mapType": { - xName: "x-kubernetes-map-type", - kind: types.Map, - allowedValues: sets.NewString("atomic", "granular"), - }, - "structType": { - xName: "x-kubernetes-map-type", - kind: types.Struct, - allowedValues: sets.NewString("atomic", "granular"), - }, - "validations": { - xName: "x-kubernetes-validations", - kind: types.Slice, - }, -} - -// Extension encapsulates information necessary to generate an OpenAPI extension. -type extension struct { - idlTag string // Example: listType - xName string // Example: x-kubernetes-list-type - values []string // Example: [atomic] -} - -func (e extension) hasAllowedValues() bool { - return tagToExtension[e.idlTag].allowedValues.Len() > 0 -} - -func (e extension) allowedValues() sets.String { - return tagToExtension[e.idlTag].allowedValues -} - -func (e extension) hasKind() bool { - return len(tagToExtension[e.idlTag].kind) > 0 -} - -func (e extension) kind() types.Kind { - return tagToExtension[e.idlTag].kind -} - -func (e extension) validateAllowedValues() error { - // allowedValues not set means no restrictions on values. - if !e.hasAllowedValues() { - return nil - } - // Check for missing value. - if len(e.values) == 0 { - return fmt.Errorf("%s needs a value, none given.", e.idlTag) - } - // For each extension value, validate that it is allowed. - allowedValues := e.allowedValues() - if !allowedValues.HasAll(e.values...) { - return fmt.Errorf("%v not allowed for %s. Allowed values: %v", - e.values, e.idlTag, allowedValues.List()) - } - return nil -} - -func (e extension) validateType(kind types.Kind) error { - // If this extension class has no kind, then don't validate the type. - if !e.hasKind() { - return nil - } - if kind != e.kind() { - return fmt.Errorf("tag %s on type %v; only allowed on type %v", - e.idlTag, kind, e.kind()) - } - return nil -} - -func (e extension) hasMultipleValues() bool { - return len(e.values) > 1 -} - -func (e extension) isAlwaysArrayFormat() bool { - return tagToExtension[e.idlTag].enforceArray -} - -// Returns sorted list of map keys. Needed for deterministic testing. -func sortedMapKeys(m map[string][]string) []string { - keys := make([]string, len(m)) - i := 0 - for k := range m { - keys[i] = k - i++ - } - sort.Strings(keys) - return keys -} - -// Parses comments to return openapi extensions. Returns a list of -// extensions which parsed correctly, as well as a list of the -// parse errors. Validating extensions is performed separately. -// NOTE: Non-empty errors does not mean extensions is empty. -func parseExtensions(comments []string) ([]extension, []error) { - extensions := []extension{} - errors := []error{} - // First, generate extensions from "+k8s:openapi-gen=x-kubernetes-*" annotations. - values := getOpenAPITagValue(comments) - for _, val := range values { - // Example: x-kubernetes-member-tag:member_test - if strings.HasPrefix(val, extensionPrefix) { - parts := strings.SplitN(val, ":", 2) - if len(parts) != 2 { - errors = append(errors, fmt.Errorf("invalid extension value: %v", val)) - continue - } - e := extension{ - idlTag: tagName, // Example: k8s:openapi-gen - xName: parts[0], // Example: x-kubernetes-member-tag - values: []string{parts[1]}, // Example: member_test - } - extensions = append(extensions, e) - } - } - // Next, generate extensions from "idlTags" (e.g. +listType) - tagValues := types.ExtractCommentTags("+", comments) - for _, idlTag := range sortedMapKeys(tagValues) { - xAttrs, exists := tagToExtension[idlTag] - if !exists { - continue - } - values := tagValues[idlTag] - e := extension{ - idlTag: idlTag, // listType - xName: xAttrs.xName, // x-kubernetes-list-type - values: values, // [atomic] - } - extensions = append(extensions, e) - } - return extensions, errors -} - -func validateMemberExtensions(extensions []extension, m *types.Member) []error { - errors := []error{} - for _, e := range extensions { - if err := e.validateAllowedValues(); err != nil { - errors = append(errors, err) - } - if err := e.validateType(m.Type.Kind); err != nil { - errors = append(errors, err) - } - } - return errors -} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go b/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go deleted file mode 100644 index a4bbe8b5..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go +++ /dev/null @@ -1,871 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "path/filepath" - "reflect" - "sort" - "strings" - - defaultergen "k8s.io/gengo/examples/defaulter-gen/generators" - "k8s.io/gengo/generator" - "k8s.io/gengo/namer" - "k8s.io/gengo/types" - openapi "k8s.io/kube-openapi/pkg/common" - - "k8s.io/klog/v2" -) - -// This is the comment tag that carries parameters for open API generation. -const tagName = "k8s:openapi-gen" -const tagOptional = "optional" -const tagDefault = "default" - -// Known values for the tag. -const ( - tagValueTrue = "true" - tagValueFalse = "false" -) - -// Used for temporary validation of patch struct tags. -// TODO: Remove patch struct tag validation because they we are now consuming OpenAPI on server. -var tempPatchTags = [...]string{ - "patchMergeKey", - "patchStrategy", -} - -func getOpenAPITagValue(comments []string) []string { - return types.ExtractCommentTags("+", comments)[tagName] -} - -func getSingleTagsValue(comments []string, tag string) (string, error) { - tags, ok := types.ExtractCommentTags("+", comments)[tag] - if !ok || len(tags) == 0 { - return "", nil - } - if len(tags) > 1 { - return "", fmt.Errorf("multiple values are not allowed for tag %s", tag) - } - return tags[0], nil -} - -func hasOpenAPITagValue(comments []string, value string) bool { - tagValues := getOpenAPITagValue(comments) - for _, val := range tagValues { - if val == value { - return true - } - } - return false -} - -// hasOptionalTag returns true if the member has +optional in its comments or -// omitempty in its json tags. -func hasOptionalTag(m *types.Member) bool { - hasOptionalCommentTag := types.ExtractCommentTags( - "+", m.CommentLines)[tagOptional] != nil - hasOptionalJsonTag := strings.Contains( - reflect.StructTag(m.Tags).Get("json"), "omitempty") - return hasOptionalCommentTag || hasOptionalJsonTag -} - -func apiTypeFilterFunc(c *generator.Context, t *types.Type) bool { - // There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen - if strings.HasPrefix(t.Name.Name, "codecSelfer") { - return false - } - pkg := c.Universe.Package(t.Name.Package) - if hasOpenAPITagValue(pkg.Comments, tagValueTrue) { - return !hasOpenAPITagValue(t.CommentLines, tagValueFalse) - } - if hasOpenAPITagValue(t.CommentLines, tagValueTrue) { - return true - } - return false -} - -const ( - specPackagePath = "k8s.io/kube-openapi/pkg/validation/spec" - openAPICommonPackagePath = "k8s.io/kube-openapi/pkg/common" -) - -// openApiGen produces a file with auto-generated OpenAPI functions. -type openAPIGen struct { - generator.DefaultGen - // TargetPackage is the package that will get GetOpenAPIDefinitions function returns all open API definitions. - targetPackage string - imports namer.ImportTracker -} - -func newOpenAPIGen(sanitizedName string, targetPackage string) generator.Generator { - return &openAPIGen{ - DefaultGen: generator.DefaultGen{ - OptionalName: sanitizedName, - }, - imports: generator.NewImportTrackerForPackage(targetPackage), - targetPackage: targetPackage, - } -} - -const nameTmpl = "schema_$.type|private$" - -func (g *openAPIGen) Namers(c *generator.Context) namer.NameSystems { - // Have the raw namer for this file track what it imports. - return namer.NameSystems{ - "raw": namer.NewRawNamer(g.targetPackage, g.imports), - "private": &namer.NameStrategy{ - Join: func(pre string, in []string, post string) string { - return strings.Join(in, "_") - }, - PrependPackageNames: 4, // enough to fully qualify from k8s.io/api/... - }, - } -} - -func (g *openAPIGen) isOtherPackage(pkg string) bool { - if pkg == g.targetPackage { - return false - } - if strings.HasSuffix(pkg, "\""+g.targetPackage+"\"") { - return false - } - return true -} - -func (g *openAPIGen) Imports(c *generator.Context) []string { - importLines := []string{} - for _, singleImport := range g.imports.ImportLines() { - importLines = append(importLines, singleImport) - } - return importLines -} - -func argsFromType(t *types.Type) generator.Args { - return generator.Args{ - "type": t, - "ReferenceCallback": types.Ref(openAPICommonPackagePath, "ReferenceCallback"), - "OpenAPIDefinition": types.Ref(openAPICommonPackagePath, "OpenAPIDefinition"), - "SpecSchemaType": types.Ref(specPackagePath, "Schema"), - } -} - -func (g *openAPIGen) Init(c *generator.Context, w io.Writer) error { - sw := generator.NewSnippetWriter(w, c, "$", "$") - sw.Do("func GetOpenAPIDefinitions(ref $.ReferenceCallback|raw$) map[string]$.OpenAPIDefinition|raw$ {\n", argsFromType(nil)) - sw.Do("return map[string]$.OpenAPIDefinition|raw${\n", argsFromType(nil)) - - for _, t := range c.Order { - err := newOpenAPITypeWriter(sw, c).generateCall(t) - if err != nil { - return err - } - } - - sw.Do("}\n", nil) - sw.Do("}\n\n", nil) - - return sw.Error() -} - -func (g *openAPIGen) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { - klog.V(5).Infof("generating for type %v", t) - sw := generator.NewSnippetWriter(w, c, "$", "$") - err := newOpenAPITypeWriter(sw, c).generate(t) - if err != nil { - return err - } - return sw.Error() -} - -func getJsonTags(m *types.Member) []string { - jsonTag := reflect.StructTag(m.Tags).Get("json") - if jsonTag == "" { - return []string{} - } - return strings.Split(jsonTag, ",") -} - -func getReferableName(m *types.Member) string { - jsonTags := getJsonTags(m) - if len(jsonTags) > 0 { - if jsonTags[0] == "-" { - return "" - } else { - return jsonTags[0] - } - } else { - return m.Name - } -} - -func shouldInlineMembers(m *types.Member) bool { - jsonTags := getJsonTags(m) - return len(jsonTags) > 1 && jsonTags[1] == "inline" -} - -type openAPITypeWriter struct { - *generator.SnippetWriter - context *generator.Context - refTypes map[string]*types.Type - enumContext *enumContext - GetDefinitionInterface *types.Type -} - -func newOpenAPITypeWriter(sw *generator.SnippetWriter, c *generator.Context) openAPITypeWriter { - return openAPITypeWriter{ - SnippetWriter: sw, - context: c, - refTypes: map[string]*types.Type{}, - enumContext: newEnumContext(c), - } -} - -func methodReturnsValue(mt *types.Type, pkg, name string) bool { - if len(mt.Signature.Parameters) != 0 || len(mt.Signature.Results) != 1 { - return false - } - r := mt.Signature.Results[0] - return r.Name.Name == name && r.Name.Package == pkg -} - -func hasOpenAPIV3DefinitionMethod(t *types.Type) bool { - for mn, mt := range t.Methods { - if mn != "OpenAPIV3Definition" { - continue - } - return methodReturnsValue(mt, openAPICommonPackagePath, "OpenAPIDefinition") - } - return false -} - -func hasOpenAPIDefinitionMethod(t *types.Type) bool { - for mn, mt := range t.Methods { - if mn != "OpenAPIDefinition" { - continue - } - return methodReturnsValue(mt, openAPICommonPackagePath, "OpenAPIDefinition") - } - return false -} - -func hasOpenAPIDefinitionMethods(t *types.Type) bool { - var hasSchemaTypeMethod, hasOpenAPISchemaFormat bool - for mn, mt := range t.Methods { - switch mn { - case "OpenAPISchemaType": - hasSchemaTypeMethod = methodReturnsValue(mt, "", "[]string") - case "OpenAPISchemaFormat": - hasOpenAPISchemaFormat = methodReturnsValue(mt, "", "string") - } - } - return hasSchemaTypeMethod && hasOpenAPISchemaFormat -} - -func hasOpenAPIV3OneOfMethod(t *types.Type) bool { - for mn, mt := range t.Methods { - if mn != "OpenAPIV3OneOfTypes" { - continue - } - return methodReturnsValue(mt, "", "[]string") - } - return false -} - -// typeShortName returns short package name (e.g. the name x appears in package x definition) dot type name. -func typeShortName(t *types.Type) string { - return filepath.Base(t.Name.Package) + "." + t.Name.Name -} - -func (g openAPITypeWriter) generateMembers(t *types.Type, required []string) ([]string, error) { - var err error - for t.Kind == types.Pointer { // fast-forward to effective type containing members - t = t.Elem - } - for _, m := range t.Members { - if hasOpenAPITagValue(m.CommentLines, tagValueFalse) { - continue - } - if shouldInlineMembers(&m) { - required, err = g.generateMembers(m.Type, required) - if err != nil { - return required, err - } - continue - } - name := getReferableName(&m) - if name == "" { - continue - } - if !hasOptionalTag(&m) { - required = append(required, name) - } - if err = g.generateProperty(&m, t); err != nil { - klog.Errorf("Error when generating: %v, %v\n", name, m) - return required, err - } - } - return required, nil -} - -func (g openAPITypeWriter) generateCall(t *types.Type) error { - // Only generate for struct type and ignore the rest - switch t.Kind { - case types.Struct: - args := argsFromType(t) - g.Do("\"$.$\": ", t.Name) - - hasV2Definition := hasOpenAPIDefinitionMethod(t) - hasV2DefinitionTypeAndFormat := hasOpenAPIDefinitionMethods(t) - hasV3Definition := hasOpenAPIV3DefinitionMethod(t) - - switch { - case hasV2DefinitionTypeAndFormat: - g.Do(nameTmpl+"(ref),\n", args) - case hasV2Definition && hasV3Definition: - g.Do("common.EmbedOpenAPIDefinitionIntoV2Extension($.type|raw${}.OpenAPIV3Definition(), $.type|raw${}.OpenAPIDefinition()),\n", args) - case hasV2Definition: - g.Do("$.type|raw${}.OpenAPIDefinition(),\n", args) - case hasV3Definition: - g.Do("$.type|raw${}.OpenAPIV3Definition(),\n", args) - default: - g.Do(nameTmpl+"(ref),\n", args) - } - } - return g.Error() -} - -func (g openAPITypeWriter) generate(t *types.Type) error { - // Only generate for struct type and ignore the rest - switch t.Kind { - case types.Struct: - hasV2Definition := hasOpenAPIDefinitionMethod(t) - hasV2DefinitionTypeAndFormat := hasOpenAPIDefinitionMethods(t) - hasV3OneOfTypes := hasOpenAPIV3OneOfMethod(t) - hasV3Definition := hasOpenAPIV3DefinitionMethod(t) - - if hasV2Definition || (hasV3Definition && !hasV2DefinitionTypeAndFormat) { - // already invoked directly - return nil - } - - args := argsFromType(t) - g.Do("func "+nameTmpl+"(ref $.ReferenceCallback|raw$) $.OpenAPIDefinition|raw$ {\n", args) - switch { - case hasV2DefinitionTypeAndFormat && hasV3Definition: - g.Do("return common.EmbedOpenAPIDefinitionIntoV2Extension($.type|raw${}.OpenAPIV3Definition(), $.OpenAPIDefinition|raw${\n"+ - "Schema: spec.Schema{\n"+ - "SchemaProps: spec.SchemaProps{\n", args) - g.generateDescription(t.CommentLines) - g.Do("Type:$.type|raw${}.OpenAPISchemaType(),\n"+ - "Format:$.type|raw${}.OpenAPISchemaFormat(),\n"+ - "},\n"+ - "},\n"+ - "})\n}\n\n", args) - return nil - case hasV2DefinitionTypeAndFormat && hasV3OneOfTypes: - // generate v3 def. - g.Do("return common.EmbedOpenAPIDefinitionIntoV2Extension($.OpenAPIDefinition|raw${\n"+ - "Schema: spec.Schema{\n"+ - "SchemaProps: spec.SchemaProps{\n", args) - g.generateDescription(t.CommentLines) - g.Do("OneOf:common.GenerateOpenAPIV3OneOfSchema($.type|raw${}.OpenAPIV3OneOfTypes()),\n"+ - "Format:$.type|raw${}.OpenAPISchemaFormat(),\n"+ - "},\n"+ - "},\n"+ - "},", args) - // generate v2 def. - g.Do("$.OpenAPIDefinition|raw${\n"+ - "Schema: spec.Schema{\n"+ - "SchemaProps: spec.SchemaProps{\n", args) - g.generateDescription(t.CommentLines) - g.Do("Type:$.type|raw${}.OpenAPISchemaType(),\n"+ - "Format:$.type|raw${}.OpenAPISchemaFormat(),\n"+ - "},\n"+ - "},\n"+ - "})\n}\n\n", args) - return nil - case hasV2DefinitionTypeAndFormat: - g.Do("return $.OpenAPIDefinition|raw${\n"+ - "Schema: spec.Schema{\n"+ - "SchemaProps: spec.SchemaProps{\n", args) - g.generateDescription(t.CommentLines) - g.Do("Type:$.type|raw${}.OpenAPISchemaType(),\n"+ - "Format:$.type|raw${}.OpenAPISchemaFormat(),\n"+ - "},\n"+ - "},\n"+ - "}\n}\n\n", args) - return nil - case hasV3OneOfTypes: - // having v3 oneOf types without custom v2 type or format does not make sense. - return fmt.Errorf("type %q has v3 one of types but not v2 type or format", t.Name) - } - g.Do("return $.OpenAPIDefinition|raw${\nSchema: spec.Schema{\nSchemaProps: spec.SchemaProps{\n", args) - g.generateDescription(t.CommentLines) - g.Do("Type: []string{\"object\"},\n", nil) - - // write members into a temporary buffer, in order to postpone writing out the Properties field. We only do - // that if it is not empty. - propertiesBuf := bytes.Buffer{} - bsw := g - bsw.SnippetWriter = generator.NewSnippetWriter(&propertiesBuf, g.context, "$", "$") - required, err := bsw.generateMembers(t, []string{}) - if err != nil { - return err - } - if propertiesBuf.Len() > 0 { - g.Do("Properties: map[string]$.SpecSchemaType|raw${\n", args) - g.Do(strings.Replace(propertiesBuf.String(), "$", "$\"$\"$", -1), nil) // escape $ (used as delimiter of the templates) - g.Do("},\n", nil) - } - - if len(required) > 0 { - g.Do("Required: []string{\"$.$\"},\n", strings.Join(required, "\",\"")) - } - g.Do("},\n", nil) - if err := g.generateStructExtensions(t); err != nil { - return err - } - g.Do("},\n", nil) - - // Map order is undefined, sort them or we may get a different file generated each time. - keys := []string{} - for k := range g.refTypes { - keys = append(keys, k) - } - sort.Strings(keys) - deps := []string{} - for _, k := range keys { - v := g.refTypes[k] - if t, _ := openapi.OpenAPITypeFormat(v.String()); t != "" { - // This is a known type, we do not need a reference to it - // Will eliminate special case of time.Time - continue - } - deps = append(deps, k) - } - if len(deps) > 0 { - g.Do("Dependencies: []string{\n", args) - for _, k := range deps { - g.Do("\"$.$\",", k) - } - g.Do("},\n", nil) - } - g.Do("}\n}\n\n", nil) - } - return nil -} - -func (g openAPITypeWriter) generateStructExtensions(t *types.Type) error { - extensions, errors := parseExtensions(t.CommentLines) - // Initially, we will only log struct extension errors. - if len(errors) > 0 { - for _, e := range errors { - klog.Errorf("[%s]: %s\n", t.String(), e) - } - } - unions, errors := parseUnions(t) - if len(errors) > 0 { - for _, e := range errors { - klog.Errorf("[%s]: %s\n", t.String(), e) - } - } - - // TODO(seans3): Validate struct extensions here. - g.emitExtensions(extensions, unions) - return nil -} - -func (g openAPITypeWriter) generateMemberExtensions(m *types.Member, parent *types.Type) error { - extensions, parseErrors := parseExtensions(m.CommentLines) - validationErrors := validateMemberExtensions(extensions, m) - errors := append(parseErrors, validationErrors...) - // Initially, we will only log member extension errors. - if len(errors) > 0 { - errorPrefix := fmt.Sprintf("[%s] %s:", parent.String(), m.String()) - for _, e := range errors { - klog.V(2).Infof("%s %s\n", errorPrefix, e) - } - } - g.emitExtensions(extensions, nil) - return nil -} - -func (g openAPITypeWriter) emitExtensions(extensions []extension, unions []union) { - // If any extensions exist, then emit code to create them. - if len(extensions) == 0 && len(unions) == 0 { - return - } - g.Do("VendorExtensible: spec.VendorExtensible{\nExtensions: spec.Extensions{\n", nil) - for _, extension := range extensions { - g.Do("\"$.$\": ", extension.xName) - if extension.hasMultipleValues() || extension.isAlwaysArrayFormat() { - g.Do("[]interface{}{\n", nil) - } - for _, value := range extension.values { - g.Do("\"$.$\",\n", value) - } - if extension.hasMultipleValues() || extension.isAlwaysArrayFormat() { - g.Do("},\n", nil) - } - } - if len(unions) > 0 { - g.Do("\"x-kubernetes-unions\": []interface{}{\n", nil) - for _, u := range unions { - u.emit(g) - } - g.Do("},\n", nil) - } - g.Do("},\n},\n", nil) -} - -// TODO(#44005): Move this validation outside of this generator (probably to policy verifier) -func (g openAPITypeWriter) validatePatchTags(m *types.Member, parent *types.Type) error { - // TODO: Remove patch struct tag validation because they we are now consuming OpenAPI on server. - for _, tagKey := range tempPatchTags { - structTagValue := reflect.StructTag(m.Tags).Get(tagKey) - commentTagValue, err := getSingleTagsValue(m.CommentLines, tagKey) - if err != nil { - return err - } - if structTagValue != commentTagValue { - return fmt.Errorf("Tags in comment and struct should match for member (%s) of (%s)", - m.Name, parent.Name.String()) - } - } - return nil -} - -func defaultFromComments(comments []string, commentPath string, t *types.Type) (interface{}, *types.Name, error) { - var tag string - - for { - var err error - tag, err = getSingleTagsValue(comments, tagDefault) - if err != nil { - return nil, nil, err - } - - if t == nil || len(tag) > 0 { - break - } - - comments = t.CommentLines - commentPath = t.Name.Package - switch t.Kind { - case types.Pointer: - t = t.Elem - case types.Alias: - t = t.Underlying - default: - t = nil - } - } - - if tag == "" { - return nil, nil, nil - } - - var i interface{} - if id, ok := defaultergen.ParseSymbolReference(tag, commentPath); ok { - klog.Errorf("%v, %v", id, commentPath) - return nil, &id, nil - } else if err := json.Unmarshal([]byte(tag), &i); err != nil { - return nil, nil, fmt.Errorf("failed to unmarshal default: %v", err) - } - return i, nil, nil -} - -func implementsCustomUnmarshalling(t *types.Type) bool { - switch t.Kind { - case types.Pointer: - unmarshaller, isUnmarshaller := t.Elem.Methods["UnmarshalJSON"] - return isUnmarshaller && unmarshaller.Signature.Receiver.Kind == types.Pointer - case types.Struct: - _, isUnmarshaller := t.Methods["UnmarshalJSON"] - return isUnmarshaller - default: - return false - } -} - -func mustEnforceDefault(t *types.Type, omitEmpty bool) (interface{}, error) { - // Treat types with custom unmarshalling as a value - // (Can be alias, struct, or pointer) - if implementsCustomUnmarshalling(t) { - // Since Go JSON deserializer always feeds `null` when present - // to structs with custom UnmarshalJSON, the zero value for - // these structs is also null. - // - // In general, Kubernetes API types with custom marshalling should - // marshal their empty values to `null`. - return nil, nil - } - - switch t.Kind { - case types.Alias: - return mustEnforceDefault(t.Underlying, omitEmpty) - case types.Pointer, types.Map, types.Slice, types.Array, types.Interface: - return nil, nil - case types.Struct: - if len(t.Members) == 1 && t.Members[0].Embedded { - // Treat a struct with a single embedded member the same as an alias - return mustEnforceDefault(t.Members[0].Type, omitEmpty) - } - - return map[string]interface{}{}, nil - case types.Builtin: - if !omitEmpty { - if zero, ok := openapi.OpenAPIZeroValue(t.String()); ok { - return zero, nil - } else { - return nil, fmt.Errorf("please add type %v to getOpenAPITypeFormat function", t) - } - } - return nil, nil - default: - return nil, fmt.Errorf("not sure how to enforce default for %v", t.Kind) - } -} - -func (g openAPITypeWriter) generateDefault(comments []string, t *types.Type, omitEmpty bool, commentOwningType *types.Type) error { - def, ref, err := defaultFromComments(comments, commentOwningType.Name.Package, t) - if err != nil { - return err - } - if enforced, err := mustEnforceDefault(t, omitEmpty); err != nil { - return err - } else if enforced != nil { - if def == nil { - def = enforced - } else if !reflect.DeepEqual(def, enforced) { - enforcedJson, _ := json.Marshal(enforced) - return fmt.Errorf("invalid default value (%#v) for non-pointer/non-omitempty. If specified, must be: %v", def, string(enforcedJson)) - } - } - if def != nil { - g.Do("Default: $.$,\n", fmt.Sprintf("%#v", def)) - } else if ref != nil { - g.Do("Default: $.|raw$,\n", &types.Type{Name: *ref}) - } - return nil -} - -func (g openAPITypeWriter) generateDescription(CommentLines []string) { - var buffer bytes.Buffer - delPrevChar := func() { - if buffer.Len() > 0 { - buffer.Truncate(buffer.Len() - 1) // Delete the last " " or "\n" - } - } - - for _, line := range CommentLines { - // Ignore all lines after --- - if line == "---" { - break - } - line = strings.TrimRight(line, " ") - leading := strings.TrimLeft(line, " ") - switch { - case len(line) == 0: // Keep paragraphs - delPrevChar() - buffer.WriteString("\n\n") - case strings.HasPrefix(leading, "TODO"): // Ignore one line TODOs - case strings.HasPrefix(leading, "+"): // Ignore instructions to go2idl - default: - if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t") { - delPrevChar() - line = "\n" + line + "\n" // Replace it with newline. This is useful when we have a line with: "Example:\n\tJSON-something..." - } else { - line += " " - } - buffer.WriteString(line) - } - } - - postDoc := strings.TrimLeft(buffer.String(), "\n") - postDoc = strings.TrimRight(postDoc, "\n") - postDoc = strings.Replace(postDoc, "\\\"", "\"", -1) // replace user's \" to " - postDoc = strings.Replace(postDoc, "\"", "\\\"", -1) // Escape " - postDoc = strings.Replace(postDoc, "\n", "\\n", -1) - postDoc = strings.Replace(postDoc, "\t", "\\t", -1) - postDoc = strings.Trim(postDoc, " ") - if postDoc != "" { - g.Do("Description: \"$.$\",\n", postDoc) - } -} - -func (g openAPITypeWriter) generateProperty(m *types.Member, parent *types.Type) error { - name := getReferableName(m) - if name == "" { - return nil - } - if err := g.validatePatchTags(m, parent); err != nil { - return err - } - g.Do("\"$.$\": {\n", name) - if err := g.generateMemberExtensions(m, parent); err != nil { - return err - } - g.Do("SchemaProps: spec.SchemaProps{\n", nil) - var extraComments []string - if enumType, isEnum := g.enumContext.EnumType(m.Type); isEnum { - extraComments = enumType.DescriptionLines() - } - g.generateDescription(append(m.CommentLines, extraComments...)) - jsonTags := getJsonTags(m) - if len(jsonTags) > 1 && jsonTags[1] == "string" { - g.generateSimpleProperty("string", "") - g.Do("},\n},\n", nil) - return nil - } - omitEmpty := strings.Contains(reflect.StructTag(m.Tags).Get("json"), "omitempty") - if err := g.generateDefault(m.CommentLines, m.Type, omitEmpty, parent); err != nil { - return fmt.Errorf("failed to generate default in %v: %v: %v", parent, m.Name, err) - } - t := resolveAliasAndPtrType(m.Type) - // If we can get a openAPI type and format for this type, we consider it to be simple property - typeString, format := openapi.OpenAPITypeFormat(t.String()) - if typeString != "" { - g.generateSimpleProperty(typeString, format) - if enumType, isEnum := g.enumContext.EnumType(m.Type); isEnum { - // original type is an enum, add "Enum: " and the values - g.Do("Enum: []interface{}{$.$},\n", strings.Join(enumType.ValueStrings(), ", ")) - } - g.Do("},\n},\n", nil) - return nil - } - switch t.Kind { - case types.Builtin: - return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", t) - case types.Map: - if err := g.generateMapProperty(t); err != nil { - return fmt.Errorf("failed to generate map property in %v: %v: %v", parent, m.Name, err) - } - case types.Slice, types.Array: - if err := g.generateSliceProperty(t); err != nil { - return fmt.Errorf("failed to generate slice property in %v: %v: %v", parent, m.Name, err) - } - case types.Struct, types.Interface: - g.generateReferenceProperty(t) - default: - return fmt.Errorf("cannot generate spec for type %v", t) - } - g.Do("},\n},\n", nil) - return g.Error() -} - -func (g openAPITypeWriter) generateSimpleProperty(typeString, format string) { - g.Do("Type: []string{\"$.$\"},\n", typeString) - g.Do("Format: \"$.$\",\n", format) -} - -func (g openAPITypeWriter) generateReferenceProperty(t *types.Type) { - g.refTypes[t.Name.String()] = t - g.Do("Ref: ref(\"$.$\"),\n", t.Name.String()) -} - -func resolveAliasAndPtrType(t *types.Type) *types.Type { - var prev *types.Type - for prev != t { - prev = t - if t.Kind == types.Alias { - t = t.Underlying - } - if t.Kind == types.Pointer { - t = t.Elem - } - } - return t -} - -func (g openAPITypeWriter) generateMapProperty(t *types.Type) error { - keyType := resolveAliasAndPtrType(t.Key) - elemType := resolveAliasAndPtrType(t.Elem) - - // According to OpenAPI examples, only map from string is supported - if keyType.Name.Name != "string" { - return fmt.Errorf("map with non-string keys are not supported by OpenAPI in %v", t) - } - - g.Do("Type: []string{\"object\"},\n", nil) - g.Do("AdditionalProperties: &spec.SchemaOrBool{\nAllows: true,\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil) - if err := g.generateDefault(t.Elem.CommentLines, t.Elem, false, t.Elem); err != nil { - return err - } - typeString, format := openapi.OpenAPITypeFormat(elemType.String()) - if typeString != "" { - g.generateSimpleProperty(typeString, format) - g.Do("},\n},\n},\n", nil) - return nil - } - switch elemType.Kind { - case types.Builtin: - return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", elemType) - case types.Struct: - g.generateReferenceProperty(elemType) - case types.Slice, types.Array: - if err := g.generateSliceProperty(elemType); err != nil { - return err - } - case types.Map: - if err := g.generateMapProperty(elemType); err != nil { - return err - } - default: - return fmt.Errorf("map Element kind %v is not supported in %v", elemType.Kind, t.Name) - } - g.Do("},\n},\n},\n", nil) - return nil -} - -func (g openAPITypeWriter) generateSliceProperty(t *types.Type) error { - elemType := resolveAliasAndPtrType(t.Elem) - g.Do("Type: []string{\"array\"},\n", nil) - g.Do("Items: &spec.SchemaOrArray{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil) - if err := g.generateDefault(t.Elem.CommentLines, t.Elem, false, t.Elem); err != nil { - return err - } - typeString, format := openapi.OpenAPITypeFormat(elemType.String()) - if typeString != "" { - g.generateSimpleProperty(typeString, format) - g.Do("},\n},\n},\n", nil) - return nil - } - switch elemType.Kind { - case types.Builtin: - return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", elemType) - case types.Struct: - g.generateReferenceProperty(elemType) - case types.Slice, types.Array: - if err := g.generateSliceProperty(elemType); err != nil { - return err - } - case types.Map: - if err := g.generateMapProperty(elemType); err != nil { - return err - } - default: - return fmt.Errorf("slice Element kind %v is not supported in %v", elemType.Kind, t) - } - g.Do("},\n},\n},\n", nil) - return nil -} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/rules/OWNERS b/vendor/k8s.io/kube-openapi/pkg/generators/rules/OWNERS deleted file mode 100644 index 235bc545..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/rules/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -reviewers: -- roycaihw -approvers: -- roycaihw diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/rules/idl_tag.go b/vendor/k8s.io/kube-openapi/pkg/generators/rules/idl_tag.go deleted file mode 100644 index 474d79e8..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/rules/idl_tag.go +++ /dev/null @@ -1,53 +0,0 @@ -package rules - -import ( - "k8s.io/gengo/types" -) - -const ListTypeIDLTag = "listType" - -// ListTypeMissing implements APIRule interface. -// A list type is required for inlined list. -type ListTypeMissing struct{} - -// Name returns the name of APIRule -func (l *ListTypeMissing) Name() string { - return "list_type_missing" -} - -// Validate evaluates API rule on type t and returns a list of field names in -// the type that violate the rule. Empty field name [""] implies the entire -// type violates the rule. -func (l *ListTypeMissing) Validate(t *types.Type) ([]string, error) { - fields := make([]string, 0) - - switch t.Kind { - case types.Struct: - for _, m := range t.Members { - hasListType := types.ExtractCommentTags("+", m.CommentLines)[ListTypeIDLTag] != nil - - if m.Name == "Items" && m.Type.Kind == types.Slice && hasNamedMember(t, "ListMeta") { - if hasListType { - fields = append(fields, m.Name) - } - continue - } - - if m.Type.Kind == types.Slice && !hasListType { - fields = append(fields, m.Name) - continue - } - } - } - - return fields, nil -} - -func hasNamedMember(t *types.Type, name string) bool { - for _, m := range t.Members { - if m.Name == name { - return true - } - } - return false -} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go b/vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go deleted file mode 100644 index 58172225..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go +++ /dev/null @@ -1,178 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package rules - -import ( - "reflect" - "strings" - - "k8s.io/kube-openapi/pkg/util/sets" - - "k8s.io/gengo/types" -) - -var ( - // Blacklist of JSON tags that should skip match evaluation - jsonTagBlacklist = sets.NewString( - // Omitted field is ignored by the package - "-", - ) - - // Blacklist of JSON names that should skip match evaluation - jsonNameBlacklist = sets.NewString( - // Empty name is used for inline struct field (e.g. metav1.TypeMeta) - "", - // Special case for object and list meta - "metadata", - ) - - // List of substrings that aren't allowed in Go name and JSON name - disallowedNameSubstrings = sets.NewString( - // Underscore is not allowed in either name - "_", - // Dash is not allowed in either name. Note that since dash is a valid JSON tag, this should be checked - // after JSON tag blacklist check. - "-", - ) -) - -/* -NamesMatch implements APIRule interface. -Go field names must be CamelCase. JSON field names must be camelCase. Other than capitalization of the -initial letter, the two should almost always match. No underscores nor dashes in either. -This rule verifies the convention "Other than capitalization of the initial letter, the two should almost always match." -Examples (also in unit test): - - Go name | JSON name | match - podSpec false - PodSpec podSpec true - PodSpec PodSpec false - podSpec podSpec false - PodSpec spec false - Spec podSpec false - JSONSpec jsonSpec true - JSONSpec jsonspec false - HTTPJSONSpec httpJSONSpec true - -NOTE: this validator cannot tell two sequential all-capital words from one word, therefore the case below -is also considered matched. - - HTTPJSONSpec httpjsonSpec true - -NOTE: JSON names in jsonNameBlacklist should skip evaluation - - true - podSpec true - podSpec - true - podSpec metadata true -*/ -type NamesMatch struct{} - -// Name returns the name of APIRule -func (n *NamesMatch) Name() string { - return "names_match" -} - -// Validate evaluates API rule on type t and returns a list of field names in -// the type that violate the rule. Empty field name [""] implies the entire -// type violates the rule. -func (n *NamesMatch) Validate(t *types.Type) ([]string, error) { - fields := make([]string, 0) - - // Only validate struct type and ignore the rest - switch t.Kind { - case types.Struct: - for _, m := range t.Members { - goName := m.Name - jsonTag, ok := reflect.StructTag(m.Tags).Lookup("json") - // Distinguish empty JSON tag and missing JSON tag. Empty JSON tag / name is - // allowed (in JSON name blacklist) but missing JSON tag is invalid. - if !ok { - fields = append(fields, goName) - continue - } - if jsonTagBlacklist.Has(jsonTag) { - continue - } - jsonName := strings.Split(jsonTag, ",")[0] - if !namesMatch(goName, jsonName) { - fields = append(fields, goName) - } - } - } - return fields, nil -} - -// namesMatch evaluates if goName and jsonName match the API rule -// TODO: Use an off-the-shelf CamelCase solution instead of implementing this logic. The following existing -// -// packages have been tried out: -// github.com/markbates/inflect -// github.com/segmentio/go-camelcase -// github.com/iancoleman/strcase -// github.com/fatih/camelcase -// Please see https://github.com/kubernetes/kube-openapi/pull/83#issuecomment-400842314 for more details -// about why they don't satisfy our need. What we need can be a function that detects an acronym at the -// beginning of a string. -func namesMatch(goName, jsonName string) bool { - if jsonNameBlacklist.Has(jsonName) { - return true - } - if !isAllowedName(goName) || !isAllowedName(jsonName) { - return false - } - if strings.ToLower(goName) != strings.ToLower(jsonName) { - return false - } - // Go field names must be CamelCase. JSON field names must be camelCase. - if !isCapital(goName[0]) || isCapital(jsonName[0]) { - return false - } - for i := 0; i < len(goName); i++ { - if goName[i] == jsonName[i] { - // goName[0:i-1] is uppercase and jsonName[0:i-1] is lowercase, goName[i:] - // and jsonName[i:] should match; - // goName[i] should be lowercase if i is equal to 1, e.g.: - // goName | jsonName - // PodSpec podSpec - // or uppercase if i is greater than 1, e.g.: - // goname | jsonName - // JSONSpec jsonSpec - // This is to rule out cases like: - // goname | jsonName - // JSONSpec jsonspec - return goName[i:] == jsonName[i:] && (i == 1 || isCapital(goName[i])) - } - } - return true -} - -// isCapital returns true if one character is capital -func isCapital(b byte) bool { - return b >= 'A' && b <= 'Z' -} - -// isAllowedName checks the list of disallowedNameSubstrings and returns true if name doesn't contain -// any disallowed substring. -func isAllowedName(name string) bool { - for _, substr := range disallowedNameSubstrings.UnsortedList() { - if strings.Contains(name, substr) { - return false - } - } - return true -} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/rules/omitempty_match_case.go b/vendor/k8s.io/kube-openapi/pkg/generators/rules/omitempty_match_case.go deleted file mode 100644 index dd37ad8a..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/rules/omitempty_match_case.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package rules - -import ( - "reflect" - "strings" - - "k8s.io/gengo/types" -) - -// OmitEmptyMatchCase implements APIRule interface. -// "omitempty" must appear verbatim (no case variants). -type OmitEmptyMatchCase struct{} - -func (n *OmitEmptyMatchCase) Name() string { - return "omitempty_match_case" -} - -func (n *OmitEmptyMatchCase) Validate(t *types.Type) ([]string, error) { - fields := make([]string, 0) - - // Only validate struct type and ignore the rest - switch t.Kind { - case types.Struct: - for _, m := range t.Members { - goName := m.Name - jsonTag, ok := reflect.StructTag(m.Tags).Lookup("json") - if !ok { - continue - } - - parts := strings.Split(jsonTag, ",") - if len(parts) < 2 { - // no tags other than name - continue - } - if parts[0] == "-" { - // not serialized - continue - } - for _, part := range parts[1:] { - if strings.EqualFold(part, "omitempty") && part != "omitempty" { - fields = append(fields, goName) - } - } - } - } - return fields, nil -} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/union.go b/vendor/k8s.io/kube-openapi/pkg/generators/union.go deleted file mode 100644 index a0281fe4..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/generators/union.go +++ /dev/null @@ -1,207 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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. -*/ - -package generators - -import ( - "fmt" - "sort" - - "k8s.io/gengo/types" -) - -const tagUnionMember = "union" -const tagUnionDeprecated = "unionDeprecated" -const tagUnionDiscriminator = "unionDiscriminator" - -type union struct { - discriminator string - fieldsToDiscriminated map[string]string -} - -// emit prints the union, can be called on a nil union (emits nothing) -func (u *union) emit(g openAPITypeWriter) { - if u == nil { - return - } - g.Do("map[string]interface{}{\n", nil) - if u.discriminator != "" { - g.Do("\"discriminator\": \"$.$\",\n", u.discriminator) - } - g.Do("\"fields-to-discriminateBy\": map[string]interface{}{\n", nil) - keys := []string{} - for field := range u.fieldsToDiscriminated { - keys = append(keys, field) - } - sort.Strings(keys) - for _, field := range keys { - g.Do("\"$.$\": ", field) - g.Do("\"$.$\",\n", u.fieldsToDiscriminated[field]) - } - g.Do("},\n", nil) - g.Do("},\n", nil) -} - -// Sets the discriminator if it's not set yet, otherwise return an error -func (u *union) setDiscriminator(value string) []error { - errors := []error{} - if u.discriminator != "" { - errors = append(errors, fmt.Errorf("at least two discriminators found: %v and %v", value, u.discriminator)) - } - u.discriminator = value - return errors -} - -// Add a new member to the union -func (u *union) addMember(jsonName, variableName string) { - if _, ok := u.fieldsToDiscriminated[jsonName]; ok { - panic(fmt.Errorf("same field (%v) found multiple times", jsonName)) - } - u.fieldsToDiscriminated[jsonName] = variableName -} - -// Makes sure that the union is valid, specifically looking for re-used discriminated -func (u *union) isValid() []error { - errors := []error{} - // Case 1: discriminator but no fields - if u.discriminator != "" && len(u.fieldsToDiscriminated) == 0 { - errors = append(errors, fmt.Errorf("discriminator set with no fields in union")) - } - // Case 2: two fields have the same discriminated value - discriminated := map[string]struct{}{} - for _, d := range u.fieldsToDiscriminated { - if _, ok := discriminated[d]; ok { - errors = append(errors, fmt.Errorf("discriminated value is used twice: %v", d)) - } - discriminated[d] = struct{}{} - } - // Case 3: a field is both discriminator AND part of the union - if u.discriminator != "" { - if _, ok := u.fieldsToDiscriminated[u.discriminator]; ok { - errors = append(errors, fmt.Errorf("%v can't be both discriminator and part of the union", u.discriminator)) - } - } - return errors -} - -// Find unions either directly on the members (or inlined members, not -// going across types) or on the type itself, or on embedded types. -func parseUnions(t *types.Type) ([]union, []error) { - errors := []error{} - unions := []union{} - su, err := parseUnionStruct(t) - if su != nil { - unions = append(unions, *su) - } - errors = append(errors, err...) - eu, err := parseEmbeddedUnion(t) - unions = append(unions, eu...) - errors = append(errors, err...) - mu, err := parseUnionMembers(t) - if mu != nil { - unions = append(unions, *mu) - } - errors = append(errors, err...) - return unions, errors -} - -// Find unions in embedded types, unions shouldn't go across types. -func parseEmbeddedUnion(t *types.Type) ([]union, []error) { - errors := []error{} - unions := []union{} - for _, m := range t.Members { - if hasOpenAPITagValue(m.CommentLines, tagValueFalse) { - continue - } - if !shouldInlineMembers(&m) { - continue - } - u, err := parseUnions(m.Type) - unions = append(unions, u...) - errors = append(errors, err...) - } - return unions, errors -} - -// Look for union tag on a struct, and then include all the fields -// (except the discriminator if there is one). The struct shouldn't have -// embedded types. -func parseUnionStruct(t *types.Type) (*union, []error) { - errors := []error{} - if types.ExtractCommentTags("+", t.CommentLines)[tagUnionMember] == nil { - return nil, nil - } - - u := &union{fieldsToDiscriminated: map[string]string{}} - - for _, m := range t.Members { - jsonName := getReferableName(&m) - if jsonName == "" { - continue - } - if shouldInlineMembers(&m) { - errors = append(errors, fmt.Errorf("union structures can't have embedded fields: %v.%v", t.Name, m.Name)) - continue - } - if types.ExtractCommentTags("+", m.CommentLines)[tagUnionDeprecated] != nil { - errors = append(errors, fmt.Errorf("union struct can't have unionDeprecated members: %v.%v", t.Name, m.Name)) - continue - } - if types.ExtractCommentTags("+", m.CommentLines)[tagUnionDiscriminator] != nil { - errors = append(errors, u.setDiscriminator(jsonName)...) - } else { - if !hasOptionalTag(&m) { - errors = append(errors, fmt.Errorf("union members must be optional: %v.%v", t.Name, m.Name)) - } - u.addMember(jsonName, m.Name) - } - } - - return u, errors -} - -// Find unions specifically on members. -func parseUnionMembers(t *types.Type) (*union, []error) { - errors := []error{} - u := &union{fieldsToDiscriminated: map[string]string{}} - - for _, m := range t.Members { - jsonName := getReferableName(&m) - if jsonName == "" { - continue - } - if shouldInlineMembers(&m) { - continue - } - if types.ExtractCommentTags("+", m.CommentLines)[tagUnionDiscriminator] != nil { - errors = append(errors, u.setDiscriminator(jsonName)...) - } - if types.ExtractCommentTags("+", m.CommentLines)[tagUnionMember] != nil { - errors = append(errors, fmt.Errorf("union tag is not accepted on struct members: %v.%v", t.Name, m.Name)) - continue - } - if types.ExtractCommentTags("+", m.CommentLines)[tagUnionDeprecated] != nil { - if !hasOptionalTag(&m) { - errors = append(errors, fmt.Errorf("union members must be optional: %v.%v", t.Name, m.Name)) - } - u.addMember(jsonName, m.Name) - } - } - if len(u.fieldsToDiscriminated) == 0 { - return nil, nil - } - return u, append(errors, u.isValid()...) -} diff --git a/vendor/k8s.io/kube-openapi/pkg/util/sets/empty.go b/vendor/k8s.io/kube-openapi/pkg/util/sets/empty.go deleted file mode 100644 index 13303ea8..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/util/sets/empty.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -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. -*/ - -// Code generated by set-gen. DO NOT EDIT. - -// NOTE: This file is copied from k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/sets/empty.go -// because in Kubernetes we don't allowed vendor code to import staging code. See -// https://github.com/kubernetes/kube-openapi/pull/90 for more details. - -package sets - -// Empty is public since it is used by some internal API objects for conversions between external -// string arrays and internal sets, and conversion logic requires public types today. -type Empty struct{} diff --git a/vendor/k8s.io/kube-openapi/pkg/util/sets/string.go b/vendor/k8s.io/kube-openapi/pkg/util/sets/string.go deleted file mode 100644 index 53f2bc12..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/util/sets/string.go +++ /dev/null @@ -1,207 +0,0 @@ -/* -Copyright The Kubernetes Authors. - -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. -*/ - -// Code generated by set-gen. DO NOT EDIT. - -// NOTE: This file is copied from k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/sets/string.go -// because in Kubernetes we don't allowed vendor code to import staging code. See -// https://github.com/kubernetes/kube-openapi/pull/90 for more details. - -package sets - -import ( - "reflect" - "sort" -) - -// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption. -type String map[string]Empty - -// NewString creates a String from a list of values. -func NewString(items ...string) String { - ss := String{} - ss.Insert(items...) - return ss -} - -// StringKeySet creates a String from a keys of a map[string](? extends interface{}). -// If the value passed in is not actually a map, this will panic. -func StringKeySet(theMap interface{}) String { - v := reflect.ValueOf(theMap) - ret := String{} - - for _, keyValue := range v.MapKeys() { - ret.Insert(keyValue.Interface().(string)) - } - return ret -} - -// Insert adds items to the set. -func (s String) Insert(items ...string) { - for _, item := range items { - s[item] = Empty{} - } -} - -// Delete removes all items from the set. -func (s String) Delete(items ...string) { - for _, item := range items { - delete(s, item) - } -} - -// Has returns true if and only if item is contained in the set. -func (s String) Has(item string) bool { - _, contained := s[item] - return contained -} - -// HasAll returns true if and only if all items are contained in the set. -func (s String) HasAll(items ...string) bool { - for _, item := range items { - if !s.Has(item) { - return false - } - } - return true -} - -// HasAny returns true if any items are contained in the set. -func (s String) HasAny(items ...string) bool { - for _, item := range items { - if s.Has(item) { - return true - } - } - return false -} - -// Difference returns a set of objects that are not in s2 -// For example: -// s1 = {a1, a2, a3} -// s2 = {a1, a2, a4, a5} -// s1.Difference(s2) = {a3} -// s2.Difference(s1) = {a4, a5} -func (s String) Difference(s2 String) String { - result := NewString() - for key := range s { - if !s2.Has(key) { - result.Insert(key) - } - } - return result -} - -// Union returns a new set which includes items in either s1 or s2. -// For example: -// s1 = {a1, a2} -// s2 = {a3, a4} -// s1.Union(s2) = {a1, a2, a3, a4} -// s2.Union(s1) = {a1, a2, a3, a4} -func (s1 String) Union(s2 String) String { - result := NewString() - for key := range s1 { - result.Insert(key) - } - for key := range s2 { - result.Insert(key) - } - return result -} - -// Intersection returns a new set which includes the item in BOTH s1 and s2 -// For example: -// s1 = {a1, a2} -// s2 = {a2, a3} -// s1.Intersection(s2) = {a2} -func (s1 String) Intersection(s2 String) String { - var walk, other String - result := NewString() - if s1.Len() < s2.Len() { - walk = s1 - other = s2 - } else { - walk = s2 - other = s1 - } - for key := range walk { - if other.Has(key) { - result.Insert(key) - } - } - return result -} - -// IsSuperset returns true if and only if s1 is a superset of s2. -func (s1 String) IsSuperset(s2 String) bool { - for item := range s2 { - if !s1.Has(item) { - return false - } - } - return true -} - -// Equal returns true if and only if s1 is equal (as a set) to s2. -// Two sets are equal if their membership is identical. -// (In practice, this means same elements, order doesn't matter) -func (s1 String) Equal(s2 String) bool { - return len(s1) == len(s2) && s1.IsSuperset(s2) -} - -type sortableSliceOfString []string - -func (s sortableSliceOfString) Len() int { return len(s) } -func (s sortableSliceOfString) Less(i, j int) bool { return lessString(s[i], s[j]) } -func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// List returns the contents as a sorted string slice. -func (s String) List() []string { - res := make(sortableSliceOfString, 0, len(s)) - for key := range s { - res = append(res, key) - } - sort.Sort(res) - return []string(res) -} - -// UnsortedList returns the slice with contents in random order. -func (s String) UnsortedList() []string { - res := make([]string, 0, len(s)) - for key := range s { - res = append(res, key) - } - return res -} - -// Returns a single element from the set. -func (s String) PopAny() (string, bool) { - for key := range s { - s.Delete(key) - return key, true - } - var zeroValue string - return zeroValue, false -} - -// Len returns the size of the set. -func (s String) Len() int { - return len(s) -} - -func lessString(lhs, rhs string) bool { - return lhs < rhs -} diff --git a/vendor/kmodules.xyz/client-go/apiextensions/controller.go b/vendor/kmodules.xyz/client-go/apiextensions/controller.go new file mode 100644 index 00000000..94425010 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/apiextensions/controller.go @@ -0,0 +1,87 @@ +/* +Copyright AppsCode Inc. and Contributors + +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. +*/ + +package apiextensions + +import ( + "context" + "sync" + + apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +type SetupFn func(ctx context.Context, mgr ctrl.Manager) + +var setupFns = map[schema.GroupKind]SetupFn{ + // schema.GroupKind{"compute.gcp.kubedb.com", "Firewall"}: firewall.Setup, +} + +var ( + setupDone = map[schema.GroupKind]bool{} + mu sync.Mutex +) + +type Reconciler struct { + ctx context.Context + mgr ctrl.Manager +} + +func NewReconciler(ctx context.Context, mgr ctrl.Manager) *Reconciler { + return &Reconciler{ctx: ctx, mgr: mgr} +} + +func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + log := log.FromContext(ctx) + var crd apiextensions.CustomResourceDefinition + if err := r.mgr.GetClient().Get(ctx, req.NamespacedName, &crd); err != nil { + log.Error(err, "unable to fetch CustomResourceDefinition") + return ctrl.Result{}, client.IgnoreNotFound(err) + } + + gk := schema.GroupKind{ + Group: crd.Spec.Group, + Kind: crd.Spec.Names.Kind, + } + mu.Lock() + defer mu.Unlock() + _, found := setupDone[gk] + if found { + return ctrl.Result{}, nil + } + setup, found := setupFns[gk] + if found { + setup(r.ctx, r.mgr) + setupDone[gk] = true + } + return ctrl.Result{}, nil +} + +func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&apiextensions.CustomResourceDefinition{}). + Complete(r) +} + +func RegisterSetup(gk schema.GroupKind, fn SetupFn) { + mu.Lock() + defer mu.Unlock() + + setupFns[gk] = fn +} diff --git a/vendor/kmodules.xyz/client-go/apiextensions/kubernetes.go b/vendor/kmodules.xyz/client-go/apiextensions/kubernetes.go new file mode 100644 index 00000000..63052359 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/apiextensions/kubernetes.go @@ -0,0 +1,131 @@ +/* +Copyright AppsCode Inc. and Contributors + +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. +*/ + +package apiextensions + +import ( + "context" + "fmt" + "time" + + v1 "kmodules.xyz/client-go/apiextensions/v1" + meta_util "kmodules.xyz/client-go/meta" + + "github.com/pkg/errors" + crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + crd_cs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + kerr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" +) + +func RegisterCRDs(client crd_cs.Interface, crds []*CustomResourceDefinition) error { + for _, crd := range crds { + // Use crd v1 for k8s >= 1.16, if available + // ref: https://github.com/kubernetes/kubernetes/issues/91395 + if crd.V1 == nil { + gvr := schema.GroupVersionResource{ + Group: crd.V1beta1.Spec.Group, + Version: crd.V1beta1.Spec.Versions[0].Name, + Resource: crd.V1beta1.Spec.Names.Plural, + } + return fmt.Errorf("missing V1 definition for %s", gvr) + } + _, _, err := v1.CreateOrUpdateCustomResourceDefinition( + context.TODO(), + client, + crd.V1.Name, + func(in *crdv1.CustomResourceDefinition) *crdv1.CustomResourceDefinition { + in.Labels = meta_util.OverwriteKeys(in.Labels, crd.V1.Labels) + in.Annotations = meta_util.OverwriteKeys(in.Annotations, crd.V1.Annotations) + + in.Spec = crd.V1.Spec + return in + }, + metav1.UpdateOptions{}, + ) + if err != nil && !kerr.IsAlreadyExists(err) { + return err + } + } + return WaitForCRDReady(client, crds) +} + +func WaitForCRDReady(client crd_cs.Interface, crds []*CustomResourceDefinition) error { + err := wait.PollUntilContextTimeout(context.Background(), 3*time.Second, 5*time.Minute, false, func(ctx context.Context) (bool, error) { + for _, crd := range crds { + var gvr schema.GroupVersionResource + if crd.V1 != nil { + gvr = schema.GroupVersionResource{ + Group: crd.V1.Spec.Group, + Version: crd.V1.Spec.Versions[0].Name, + Resource: crd.V1.Spec.Names.Plural, + } + } else if crd.V1beta1 != nil { + gvr = schema.GroupVersionResource{ + Group: crd.V1beta1.Spec.Group, + Version: crd.V1beta1.Spec.Versions[0].Name, + Resource: crd.V1beta1.Spec.Names.Plural, + } + } + + objc, err := client.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), gvr.GroupResource().String(), metav1.GetOptions{}) + if err != nil { + if kerr.IsNotFound(err) { + return false, nil + } + return false, err + } + + for _, c := range objc.Status.Conditions { + if c.Type == "NamesAccepted" && c.Status == crdv1.ConditionFalse { + return false, fmt.Errorf("CRD %s %s: %s", gvr.GroupResource(), c.Reason, c.Message) + } + if c.Type == "Established" { + if c.Status == crdv1.ConditionFalse && c.Reason != "Installing" { + return false, fmt.Errorf("CRD %s %s: %s", gvr.GroupResource(), c.Reason, c.Message) + } + if c.Status == crdv1.ConditionTrue { + break + } + } + } + } + return true, nil + }) + return errors.Wrap(err, "timed out waiting for CRD") +} + +func RemoveCRDs(client crd_cs.Interface, crds []*CustomResourceDefinition) error { + for _, crd := range crds { + // Use crd v1 for k8s >= 1.16, if available + // ref: https://github.com/kubernetes/kubernetes/issues/91395 + if crd.V1 == nil { + gvr := schema.GroupVersionResource{ + Group: crd.V1beta1.Spec.Group, + Version: crd.V1beta1.Spec.Versions[0].Name, + Resource: crd.V1beta1.Spec.Names.Plural, + } + return fmt.Errorf("missing V1 definition for %s", gvr) + } + err := client.ApiextensionsV1().CustomResourceDefinitions().Delete(context.TODO(), crd.V1.Name, metav1.DeleteOptions{}) + if err != nil && !kerr.IsNotFound(err) { + return err + } + } + return nil +} diff --git a/vendor/k8s.io/gengo/examples/set-gen/sets/empty.go b/vendor/kmodules.xyz/client-go/apiextensions/types.go similarity index 60% rename from vendor/k8s.io/gengo/examples/set-gen/sets/empty.go rename to vendor/kmodules.xyz/client-go/apiextensions/types.go index e11e622c..062262bb 100644 --- a/vendor/k8s.io/gengo/examples/set-gen/sets/empty.go +++ b/vendor/kmodules.xyz/client-go/apiextensions/types.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright AppsCode Inc. and Contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,10 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by set-gen. DO NOT EDIT. +package apiextensions -package sets +import ( + crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + crdv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" +) -// Empty is public since it is used by some internal API objects for conversions between external -// string arrays and internal sets, and conversion logic requires public types today. -type Empty struct{} +type CustomResourceDefinition struct { + V1beta1 *crdv1beta1.CustomResourceDefinition + V1 *crdv1.CustomResourceDefinition +} diff --git a/vendor/kmodules.xyz/client-go/apiextensions/v1/crd.go b/vendor/kmodules.xyz/client-go/apiextensions/v1/crd.go new file mode 100644 index 00000000..28156ee2 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/apiextensions/v1/crd.go @@ -0,0 +1,95 @@ +/* +Copyright AppsCode Inc. and Contributors + +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. +*/ + +package v1 + +import ( + "context" + "time" + + "github.com/pkg/errors" + api "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + cs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + kerr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/klog/v2" + kutil "kmodules.xyz/client-go" +) + +const ( + RetryTimeout = 10 * time.Minute +) + +func CreateOrUpdateCustomResourceDefinition( + ctx context.Context, + c cs.Interface, + name string, + transform func(in *api.CustomResourceDefinition) *api.CustomResourceDefinition, + opts metav1.UpdateOptions, +) (*api.CustomResourceDefinition, kutil.VerbType, error) { + _, err := c.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, name, metav1.GetOptions{}) + if kerr.IsNotFound(err) { + klog.V(3).Infof("Creating CustomResourceDefinition %s.", name) + out, err := c.ApiextensionsV1().CustomResourceDefinitions().Create(ctx, transform(&api.CustomResourceDefinition{ + TypeMeta: metav1.TypeMeta{ + APIVersion: api.SchemeGroupVersion.String(), + Kind: "CustomResourceDefinition", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }), metav1.CreateOptions{ + DryRun: opts.DryRun, + FieldManager: opts.FieldManager, + }) + return out, kutil.VerbCreated, err + } else if err != nil { + return nil, kutil.VerbUnchanged, err + } + cur, err := TryUpdateCustomResourceDefinition(ctx, c, name, transform, opts) + if err != nil { + return nil, kutil.VerbUnchanged, err + } + return cur, kutil.VerbUpdated, nil +} + +func TryUpdateCustomResourceDefinition( + ctx context.Context, + c cs.Interface, + name string, + transform func(*api.CustomResourceDefinition) *api.CustomResourceDefinition, + opts metav1.UpdateOptions, +) (result *api.CustomResourceDefinition, err error) { + attempt := 0 + err = wait.PollUntilContextTimeout(ctx, kutil.RetryInterval, RetryTimeout, true, func(ctx context.Context) (bool, error) { + attempt++ + cur, e2 := c.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, name, metav1.GetOptions{}) + if kerr.IsNotFound(e2) { + return false, e2 + } else if e2 == nil { + result, e2 = c.ApiextensionsV1().CustomResourceDefinitions().Update(ctx, transform(cur.DeepCopy()), opts) + return e2 == nil, nil + } + klog.Errorf("Attempt %d failed to update CustomResourceDefinition %s due to %v.", attempt, cur.Name, e2) + return false, nil + }) + + if err != nil { + err = errors.Errorf("failed to update CustomResourceDefinition %s after %d attempts due to %v", name, attempt, err) + } + return +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 1a74a11e..9232cd6c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -65,7 +65,7 @@ github.com/fatih/structs # github.com/felixge/httpsnoop v1.0.4 ## explicit; go 1.13 github.com/felixge/httpsnoop -# github.com/frankban/quicktest v1.14.3 +# github.com/frankban/quicktest v1.14.6 ## explicit; go 1.13 # github.com/fsnotify/fsnotify v1.7.0 ## explicit; go 1.17 @@ -94,9 +94,6 @@ github.com/go-openapi/jsonreference/internal # github.com/go-openapi/swag v0.22.3 ## explicit; go 1.18 github.com/go-openapi/swag -# github.com/gobuffalo/flect v0.2.5 -## explicit; go 1.13 -github.com/gobuffalo/flect # github.com/gogo/protobuf v1.3.2 ## explicit; go 1.15 github.com/gogo/protobuf/gogoproto @@ -168,8 +165,8 @@ github.com/google/shlex # github.com/google/uuid v1.3.1 ## explicit github.com/google/uuid -# github.com/gorilla/mux v1.8.0 -## explicit; go 1.12 +# github.com/gorilla/mux v1.8.1 +## explicit; go 1.20 github.com/gorilla/mux # github.com/gorilla/securecookie v1.1.1 ## explicit @@ -262,6 +259,8 @@ github.com/monochromegane/go-gitignore # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg +# github.com/nxadm/tail v1.4.8 +## explicit; go 1.13 # github.com/onsi/gomega v1.30.0 ## explicit; go 1.18 github.com/onsi/gomega @@ -332,7 +331,7 @@ github.com/stoewer/go-strcase ## explicit; go 1.20 github.com/stretchr/testify/assert github.com/stretchr/testify/require -# github.com/vmihailenco/msgpack/v4 v4.3.12 +# github.com/vmihailenco/msgpack/v4 v4.3.13 ## explicit; go 1.11 github.com/vmihailenco/msgpack/v4 github.com/vmihailenco/msgpack/v4/codes @@ -463,12 +462,8 @@ golang.org/x/crypto/pbkdf2 # golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 ## explicit; go 1.18 golang.org/x/exp/constraints +golang.org/x/exp/maps golang.org/x/exp/slices -# golang.org/x/mod v0.14.0 -## explicit; go 1.18 -golang.org/x/mod/internal/lazyregexp -golang.org/x/mod/module -golang.org/x/mod/semver # golang.org/x/net v0.19.0 ## explicit; go 1.18 golang.org/x/net/context @@ -533,29 +528,6 @@ golang.org/x/text/width # golang.org/x/time v0.3.0 ## explicit golang.org/x/time/rate -# golang.org/x/tools v0.16.1 -## explicit; go 1.18 -golang.org/x/tools/go/ast/astutil -golang.org/x/tools/go/gcexportdata -golang.org/x/tools/go/internal/packagesdriver -golang.org/x/tools/go/packages -golang.org/x/tools/go/types/objectpath -golang.org/x/tools/imports -golang.org/x/tools/internal/event -golang.org/x/tools/internal/event/core -golang.org/x/tools/internal/event/keys -golang.org/x/tools/internal/event/label -golang.org/x/tools/internal/event/tag -golang.org/x/tools/internal/gcimporter -golang.org/x/tools/internal/gocommand -golang.org/x/tools/internal/gopathwalk -golang.org/x/tools/internal/imports -golang.org/x/tools/internal/packagesinternal -golang.org/x/tools/internal/pkgbits -golang.org/x/tools/internal/tokeninternal -golang.org/x/tools/internal/typeparams -golang.org/x/tools/internal/typesinternal -golang.org/x/tools/internal/versions # gomodules.xyz/jsonpatch/v2 v2.4.0 ## explicit; go 1.20 gomodules.xyz/jsonpatch/v2 @@ -1268,48 +1240,12 @@ k8s.io/client-go/util/jsonpath k8s.io/client-go/util/keyutil k8s.io/client-go/util/retry k8s.io/client-go/util/workqueue -# k8s.io/code-generator v0.29.0 -## explicit; go 1.21 -k8s.io/code-generator -k8s.io/code-generator/cmd/applyconfiguration-gen -k8s.io/code-generator/cmd/applyconfiguration-gen/args -k8s.io/code-generator/cmd/applyconfiguration-gen/generators -k8s.io/code-generator/cmd/client-gen -k8s.io/code-generator/cmd/client-gen/args -k8s.io/code-generator/cmd/client-gen/generators -k8s.io/code-generator/cmd/client-gen/generators/fake -k8s.io/code-generator/cmd/client-gen/generators/scheme -k8s.io/code-generator/cmd/client-gen/generators/util -k8s.io/code-generator/cmd/client-gen/path -k8s.io/code-generator/cmd/client-gen/types -k8s.io/code-generator/cmd/conversion-gen -k8s.io/code-generator/cmd/conversion-gen/args -k8s.io/code-generator/cmd/conversion-gen/generators -k8s.io/code-generator/cmd/deepcopy-gen -k8s.io/code-generator/cmd/deepcopy-gen/args -k8s.io/code-generator/cmd/defaulter-gen -k8s.io/code-generator/cmd/defaulter-gen/args -k8s.io/code-generator/cmd/go-to-protobuf -k8s.io/code-generator/cmd/go-to-protobuf/protobuf -k8s.io/code-generator/cmd/import-boss -k8s.io/code-generator/cmd/informer-gen -k8s.io/code-generator/cmd/informer-gen/args -k8s.io/code-generator/cmd/informer-gen/generators -k8s.io/code-generator/cmd/lister-gen -k8s.io/code-generator/cmd/lister-gen/args -k8s.io/code-generator/cmd/lister-gen/generators -k8s.io/code-generator/cmd/openapi-gen -k8s.io/code-generator/cmd/register-gen -k8s.io/code-generator/cmd/register-gen/args -k8s.io/code-generator/cmd/register-gen/generators -k8s.io/code-generator/cmd/set-gen -k8s.io/code-generator/pkg/namer -k8s.io/code-generator/pkg/util -k8s.io/code-generator/third_party/forked/golang/reflect # k8s.io/component-base v0.29.0 ## explicit; go 1.21 k8s.io/component-base/cli k8s.io/component-base/cli/flag +k8s.io/component-base/config +k8s.io/component-base/config/v1alpha1 k8s.io/component-base/featuregate k8s.io/component-base/logs k8s.io/component-base/logs/api/v1 @@ -1328,18 +1264,6 @@ k8s.io/component-base/metrics/testutil k8s.io/component-base/tracing k8s.io/component-base/tracing/api/v1 k8s.io/component-base/version -# k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 -## explicit; go 1.13 -k8s.io/gengo/args -k8s.io/gengo/examples/deepcopy-gen/generators -k8s.io/gengo/examples/defaulter-gen/generators -k8s.io/gengo/examples/import-boss/generators -k8s.io/gengo/examples/set-gen/generators -k8s.io/gengo/examples/set-gen/sets -k8s.io/gengo/generator -k8s.io/gengo/namer -k8s.io/gengo/parser -k8s.io/gengo/types # k8s.io/klog/v2 v2.110.1 ## explicit; go 1.13 k8s.io/klog/v2 @@ -1351,7 +1275,6 @@ k8s.io/klog/v2/internal/severity k8s.io/klog/v2/internal/sloghandler # k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 ## explicit; go 1.19 -k8s.io/kube-openapi/cmd/openapi-gen/args k8s.io/kube-openapi/pkg/aggregator k8s.io/kube-openapi/pkg/builder k8s.io/kube-openapi/pkg/builder3 @@ -1359,8 +1282,6 @@ k8s.io/kube-openapi/pkg/builder3/util k8s.io/kube-openapi/pkg/cached k8s.io/kube-openapi/pkg/common k8s.io/kube-openapi/pkg/common/restfuladapter -k8s.io/kube-openapi/pkg/generators -k8s.io/kube-openapi/pkg/generators/rules k8s.io/kube-openapi/pkg/handler k8s.io/kube-openapi/pkg/handler3 k8s.io/kube-openapi/pkg/internal @@ -1370,7 +1291,6 @@ k8s.io/kube-openapi/pkg/schemamutation k8s.io/kube-openapi/pkg/spec3 k8s.io/kube-openapi/pkg/util k8s.io/kube-openapi/pkg/util/proto -k8s.io/kube-openapi/pkg/util/sets k8s.io/kube-openapi/pkg/validation/errors k8s.io/kube-openapi/pkg/validation/spec k8s.io/kube-openapi/pkg/validation/strfmt @@ -1395,6 +1315,8 @@ k8s.io/utils/trace ## explicit; go 1.21.5 kmodules.xyz/client-go kmodules.xyz/client-go/api/v1 +kmodules.xyz/client-go/apiextensions +kmodules.xyz/client-go/apiextensions/v1 kmodules.xyz/client-go/client kmodules.xyz/client-go/client/apiutil kmodules.xyz/client-go/conditions @@ -1413,25 +1335,48 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client # sigs.k8s.io/controller-runtime v0.17.0 ## explicit; go 1.21 +sigs.k8s.io/controller-runtime +sigs.k8s.io/controller-runtime/pkg/builder +sigs.k8s.io/controller-runtime/pkg/cache +sigs.k8s.io/controller-runtime/pkg/cache/internal +sigs.k8s.io/controller-runtime/pkg/certwatcher +sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics sigs.k8s.io/controller-runtime/pkg/client sigs.k8s.io/controller-runtime/pkg/client/apiutil +sigs.k8s.io/controller-runtime/pkg/client/config +sigs.k8s.io/controller-runtime/pkg/cluster +sigs.k8s.io/controller-runtime/pkg/config +sigs.k8s.io/controller-runtime/pkg/config/v1alpha1 +sigs.k8s.io/controller-runtime/pkg/controller +sigs.k8s.io/controller-runtime/pkg/controller/controllerutil +sigs.k8s.io/controller-runtime/pkg/conversion +sigs.k8s.io/controller-runtime/pkg/event +sigs.k8s.io/controller-runtime/pkg/handler +sigs.k8s.io/controller-runtime/pkg/healthz +sigs.k8s.io/controller-runtime/pkg/internal/controller +sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics +sigs.k8s.io/controller-runtime/pkg/internal/field/selector +sigs.k8s.io/controller-runtime/pkg/internal/httpserver +sigs.k8s.io/controller-runtime/pkg/internal/log +sigs.k8s.io/controller-runtime/pkg/internal/recorder +sigs.k8s.io/controller-runtime/pkg/internal/source +sigs.k8s.io/controller-runtime/pkg/internal/syncs +sigs.k8s.io/controller-runtime/pkg/leaderelection sigs.k8s.io/controller-runtime/pkg/log -# sigs.k8s.io/controller-tools v0.10.0 -## explicit; go 1.19 -sigs.k8s.io/controller-tools/cmd/controller-gen -sigs.k8s.io/controller-tools/pkg/crd -sigs.k8s.io/controller-tools/pkg/crd/markers -sigs.k8s.io/controller-tools/pkg/deepcopy -sigs.k8s.io/controller-tools/pkg/genall -sigs.k8s.io/controller-tools/pkg/genall/help -sigs.k8s.io/controller-tools/pkg/genall/help/pretty -sigs.k8s.io/controller-tools/pkg/loader -sigs.k8s.io/controller-tools/pkg/markers -sigs.k8s.io/controller-tools/pkg/rbac -sigs.k8s.io/controller-tools/pkg/schemapatcher -sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml -sigs.k8s.io/controller-tools/pkg/version -sigs.k8s.io/controller-tools/pkg/webhook +sigs.k8s.io/controller-runtime/pkg/manager +sigs.k8s.io/controller-runtime/pkg/manager/signals +sigs.k8s.io/controller-runtime/pkg/metrics +sigs.k8s.io/controller-runtime/pkg/metrics/server +sigs.k8s.io/controller-runtime/pkg/predicate +sigs.k8s.io/controller-runtime/pkg/ratelimiter +sigs.k8s.io/controller-runtime/pkg/reconcile +sigs.k8s.io/controller-runtime/pkg/recorder +sigs.k8s.io/controller-runtime/pkg/scheme +sigs.k8s.io/controller-runtime/pkg/source +sigs.k8s.io/controller-runtime/pkg/webhook +sigs.k8s.io/controller-runtime/pkg/webhook/admission +sigs.k8s.io/controller-runtime/pkg/webhook/conversion +sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics # sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd ## explicit; go 1.18 sigs.k8s.io/json diff --git a/vendor/sigs.k8s.io/controller-runtime/.gitignore b/vendor/sigs.k8s.io/controller-runtime/.gitignore new file mode 100644 index 00000000..29468595 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/.gitignore @@ -0,0 +1,27 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# editor and IDE paraphernalia +.idea +*.swp +*.swo +*~ + +# Vscode files +.vscode + +# Tools binaries. +hack/tools/bin + +junit-report.xml +/artifacts \ No newline at end of file diff --git a/vendor/sigs.k8s.io/controller-runtime/.golangci.yml b/vendor/sigs.k8s.io/controller-runtime/.golangci.yml new file mode 100644 index 00000000..a95c15b2 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/.golangci.yml @@ -0,0 +1,170 @@ +linters: + disable-all: true + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - dogsled + - dupl + - errcheck + - errchkjson + - errorlint + - exhaustive + - exportloopref + - ginkgolinter + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - goprintffuncname + - gosec + - gosimple + - govet + - importas + - ineffassign + - makezero + - misspell + - nakedret + - nilerr + - nolintlint + - prealloc + - revive + - staticcheck + - stylecheck + - tagliatelle + - typecheck + - unconvert + - unparam + - unused + - whitespace + +linters-settings: + importas: + no-unaliased: true + alias: + # Kubernetes + - pkg: k8s.io/api/core/v1 + alias: corev1 + - pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 + alias: apiextensionsv1 + - pkg: k8s.io/apimachinery/pkg/apis/meta/v1 + alias: metav1 + - pkg: k8s.io/apimachinery/pkg/api/errors + alias: apierrors + - pkg: k8s.io/apimachinery/pkg/util/errors + alias: kerrors + # Controller Runtime + - pkg: sigs.k8s.io/controller-runtime + alias: ctrl + staticcheck: + go: "1.21" + stylecheck: + go: "1.21" + revive: + rules: + # The following rules are recommended https://github.com/mgechev/revive#recommended-configuration + - name: blank-imports + - name: context-as-argument + - name: context-keys-type + - name: dot-imports + - name: error-return + - name: error-strings + - name: error-naming + - name: exported + - name: if-return + - name: increment-decrement + - name: var-naming + - name: var-declaration + - name: range + - name: receiver-naming + - name: time-naming + - name: unexported-return + - name: indent-error-flow + - name: errorf + - name: superfluous-else + - name: unreachable-code + - name: redefines-builtin-id + # + # Rules in addition to the recommended configuration above. + # + - name: bool-literal-in-expr + - name: constant-logical-expr + +issues: + max-same-issues: 0 + max-issues-per-linter: 0 + # We are disabling default golangci exclusions because we want to help reviewers to focus on reviewing the most relevant + # changes in PRs and avoid nitpicking. + exclude-use-default: false + # List of regexps of issue texts to exclude, empty list by default. + exclude: + # The following are being worked on to remove their exclusion. This list should be reduced or go away all together over time. + # If it is decided they will not be addressed they should be moved above this comment. + - Subprocess launch(ed with variable|ing should be audited) + - (G204|G104|G307) + - "ST1000: at least one file in a package should have a package comment" + exclude-rules: + - linters: + - gosec + text: "G108: Profiling endpoint is automatically exposed on /debug/pprof" + - linters: + - revive + text: "exported: exported method .*\\.(Reconcile|SetupWithManager|SetupWebhookWithManager) should have comment or be unexported" + - linters: + - errcheck + text: Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked + - linters: + - staticcheck + text: "SA1019: .*The component config package has been deprecated and will be removed in a future release." + # With Go 1.16, the new embed directive can be used with an un-named import, + # revive (previously, golint) only allows these to be imported in a main.go, which wouldn't work for us. + # This directive allows the embed package to be imported with an underscore everywhere. + - linters: + - revive + source: _ "embed" + # Exclude some packages or code to require comments, for example test code, or fake clients. + - linters: + - revive + text: exported (method|function|type|const) (.+) should have comment or be unexported + source: (func|type).*Fake.* + - linters: + - revive + text: exported (method|function|type|const) (.+) should have comment or be unexported + path: fake_\.go + # Disable unparam "always receives" which might not be really + # useful when building libraries. + - linters: + - unparam + text: always receives + # Dot imports for gomega and ginkgo are allowed + # within test files. + - path: _test\.go + text: should not use dot imports + - path: _test\.go + text: cyclomatic complexity + - path: _test\.go + text: "G107: Potential HTTP request made with variable url" + # Append should be able to assign to a different var/slice. + - linters: + - gocritic + text: "appendAssign: append result not assigned to the same slice" + - linters: + - gocritic + text: "singleCaseSwitch: should rewrite switch statement to if statement" + # It considers all file access to a filename that comes from a variable problematic, + # which is naiv at best. + - linters: + - gosec + text: "G304: Potential file inclusion via variable" + - linters: + - dupl + path: _test\.go + +run: + timeout: 10m + skip-files: + - "zz_generated.*\\.go$" + - ".*conversion.*\\.go$" + allow-parallel-runners: true diff --git a/vendor/sigs.k8s.io/controller-runtime/CONTRIBUTING.md b/vendor/sigs.k8s.io/controller-runtime/CONTRIBUTING.md new file mode 100644 index 00000000..2c0ea1f6 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/CONTRIBUTING.md @@ -0,0 +1,19 @@ +# Contributing guidelines + +## Sign the CLA + +Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests. + +Please see https://git.k8s.io/community/CLA.md for more info + +## Contributing steps + +1. Submit an issue describing your proposed change to the repo in question. +1. The [repo owners](OWNERS) will respond to your issue promptly. +1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above). +1. Fork the desired repo, develop and test your code changes. +1. Submit a pull request. + +## Test locally + +Run the command `make test` to test the changes locally. diff --git a/vendor/sigs.k8s.io/controller-runtime/FAQ.md b/vendor/sigs.k8s.io/controller-runtime/FAQ.md new file mode 100644 index 00000000..c21b29e2 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/FAQ.md @@ -0,0 +1,81 @@ +# FAQ + +### Q: How do I know which type of object a controller references? + +**A**: Each controller should only reconcile one object type. Other +affected objects should be mapped to a single type of root object, using +the `EnqueueRequestForOwner` or `EnqueueRequestsFromMapFunc` event +handlers, and potentially indices. Then, your Reconcile method should +attempt to reconcile *all* state for that given root objects. + +### Q: How do I have different logic in my reconciler for different types of events (e.g. create, update, delete)? + +**A**: You should not. Reconcile functions should be idempotent, and +should always reconcile state by reading all the state it needs, then +writing updates. This allows your reconciler to correctly respond to +generic events, adjust to skipped or coalesced events, and easily deal +with application startup. The controller will enqueue reconcile requests +for both old and new objects if a mapping changes, but it's your +responsibility to make sure you have enough information to be able clean +up state that's no longer referenced. + +### Q: My cache might be stale if I read from a cache! How should I deal with that? + +**A**: There are several different approaches that can be taken, depending +on your situation. + +- When you can, take advantage of optimistic locking: use deterministic + names for objects you create, so that the Kubernetes API server will + warn you if the object already exists. Many controllers in Kubernetes + take this approach: the StatefulSet controller appends a specific number + to each pod that it creates, while the Deployment controller hashes the + pod template spec and appends that. + +- In the few cases when you cannot take advantage of deterministic names + (e.g. when using generateName), it may be useful in to track which + actions you took, and assume that they need to be repeated if they don't + occur after a given time (e.g. using a requeue result). This is what + the ReplicaSet controller does. + +In general, write your controller with the assumption that information +will eventually be correct, but may be slightly out of date. Make sure +that your reconcile function enforces the entire state of the world each +time it runs. If none of this works for you, you can always construct +a client that reads directly from the API server, but this is generally +considered to be a last resort, and the two approaches above should +generally cover most circumstances. + +### Q: Where's the fake client? How do I use it? + +**A**: The fake client +[exists](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client/fake), +but we generally recommend using +[envtest.Environment](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest#Environment) +to test against a real API server. In our experience, tests using fake +clients gradually re-implement poorly-written impressions of a real API +server, which leads to hard-to-maintain, complex test code. + +### Q: How should I write tests? Any suggestions for getting started? + +- Use the aforementioned + [envtest.Environment](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest#Environment) + to spin up a real API server instead of trying to mock one out. + +- Structure your tests to check that the state of the world is as you + expect it, *not* that a particular set of API calls were made, when + working with Kubernetes APIs. This will allow you to more easily + refactor and improve the internals of your controllers without changing + your tests. + +- Remember that any time you're interacting with the API server, changes + may have some delay between write time and reconcile time. + +### Q: What are these errors about no Kind being registered for a type? + +**A**: You're probably missing a fully-set-up Scheme. Schemes record the +mapping between Go types and group-version-kinds in Kubernetes. In +general, your application should have its own Scheme containing the types +from the API groups that it needs (be they Kubernetes types or your own). +See the [scheme builder +docs](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/scheme) for +more information. diff --git a/vendor/sigs.k8s.io/controller-runtime/Makefile b/vendor/sigs.k8s.io/controller-runtime/Makefile new file mode 100644 index 00000000..007889c5 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/Makefile @@ -0,0 +1,134 @@ +#!/usr/bin/env bash + +# Copyright 2020 The Kubernetes Authors. +# +# 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. + +# If you update this file, please follow +# https://suva.sh/posts/well-documented-makefiles + +## -------------------------------------- +## General +## -------------------------------------- + +SHELL:=/usr/bin/env bash +.DEFAULT_GOAL:=help + +# Use GOPROXY environment variable if set +GOPROXY := $(shell go env GOPROXY) +ifeq ($(GOPROXY),) +GOPROXY := https://proxy.golang.org +endif +export GOPROXY + +# Active module mode, as we use go modules to manage dependencies +export GO111MODULE=on + +# Tools. +TOOLS_DIR := hack/tools +TOOLS_BIN_DIR := $(TOOLS_DIR)/bin +GOLANGCI_LINT := $(abspath $(TOOLS_BIN_DIR)/golangci-lint) +GO_APIDIFF := $(TOOLS_BIN_DIR)/go-apidiff +CONTROLLER_GEN := $(TOOLS_BIN_DIR)/controller-gen +ENVTEST_DIR := $(abspath tools/setup-envtest) +SCRATCH_ENV_DIR := $(abspath examples/scratch-env) + +# The help will print out all targets with their descriptions organized bellow their categories. The categories are represented by `##@` and the target descriptions by `##`. +# The awk commands is responsible to read the entire set of makefiles included in this invocation, looking for lines of the file as xyz: ## something, and then pretty-format the target and help. Then, if there's a line with ##@ something, that gets pretty-printed as a category. +# More info over the usage of ANSI control characters for terminal formatting: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info over awk command: http://linuxcommand.org/lc3_adv_awk.php +.PHONY: help +help: ## Display this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +## -------------------------------------- +## Testing +## -------------------------------------- + +.PHONY: test +test: test-tools ## Run the script check-everything.sh which will check all. + TRACE=1 ./hack/check-everything.sh + +.PHONY: test-tools +test-tools: ## tests the tools codebase (setup-envtest) + cd tools/setup-envtest && go test ./... + +## -------------------------------------- +## Binaries +## -------------------------------------- + +$(GO_APIDIFF): $(TOOLS_DIR)/go.mod # Build go-apidiff from tools folder. + cd $(TOOLS_DIR) && go build -tags=tools -o bin/go-apidiff github.com/joelanford/go-apidiff + +$(CONTROLLER_GEN): $(TOOLS_DIR)/go.mod # Build controller-gen from tools folder. + cd $(TOOLS_DIR) && go build -tags=tools -o bin/controller-gen sigs.k8s.io/controller-tools/cmd/controller-gen + +$(GOLANGCI_LINT): .github/workflows/golangci-lint.yml # Download golanci-lint using hack script into tools folder. + hack/ensure-golangci-lint.sh \ + -b $(TOOLS_BIN_DIR) \ + $(shell cat .github/workflows/golangci-lint.yml | grep "version: v" | sed 's/.*version: //') + +## -------------------------------------- +## Linting +## -------------------------------------- + +.PHONY: lint +lint: $(GOLANGCI_LINT) ## Lint codebase + $(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS) + cd tools/setup-envtest; $(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS) + +.PHONY: lint-fix +lint-fix: $(GOLANGCI_LINT) ## Lint the codebase and run auto-fixers if supported by the linter. + GOLANGCI_LINT_EXTRA_ARGS=--fix $(MAKE) lint + +## -------------------------------------- +## Generate +## -------------------------------------- + +.PHONY: modules +modules: ## Runs go mod to ensure modules are up to date. + go mod tidy + cd $(TOOLS_DIR); go mod tidy + cd $(ENVTEST_DIR); go mod tidy + cd $(SCRATCH_ENV_DIR); go mod tidy + +.PHONY: generate +generate: $(CONTROLLER_GEN) ## Runs controller-gen for internal types for config file + $(CONTROLLER_GEN) object paths="./pkg/config/v1alpha1/...;./examples/configfile/custom/v1alpha1/..." + +## -------------------------------------- +## Cleanup / Verification +## -------------------------------------- + +.PHONY: clean +clean: ## Cleanup. + $(GOLANGCI_LINT) cache clean + $(MAKE) clean-bin + +.PHONY: clean-bin +clean-bin: ## Remove all generated binaries. + rm -rf hack/tools/bin + +.PHONY: verify-modules +verify-modules: modules ## Verify go modules are up to date + @if !(git diff --quiet HEAD -- go.sum go.mod $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/go.sum $(ENVTEST_DIR)/go.mod $(ENVTEST_DIR)/go.sum $(SCRATCH_ENV_DIR)/go.sum); then \ + git diff; \ + echo "go module files are out of date, please run 'make modules'"; exit 1; \ + fi + +.PHONY: verify-generate +verify-generate: generate ## Verify generated files are up to date + @if !(git diff --quiet HEAD); then \ + git diff; \ + echo "generated files are out of date, run make generate"; exit 1; \ + fi diff --git a/vendor/sigs.k8s.io/controller-runtime/OWNERS b/vendor/sigs.k8s.io/controller-runtime/OWNERS new file mode 100644 index 00000000..4b1fa044 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +approvers: + - controller-runtime-admins + - controller-runtime-maintainers + - controller-runtime-approvers +reviewers: + - controller-runtime-admins + - controller-runtime-reviewers + - controller-runtime-approvers diff --git a/vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES b/vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES new file mode 100644 index 00000000..7848941d --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES @@ -0,0 +1,41 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +aliases: + # active folks who can be contacted to perform admin-related + # tasks on the repo, or otherwise approve any PRS. + controller-runtime-admins: + - vincepri + - joelanford + + # non-admin folks who have write-access and can approve any PRs in the repo + controller-runtime-maintainers: + - alvaroaleman + - joelanford + - sbueringer + - vincepri + + # non-admin folks who can approve any PRs in the repo + controller-runtime-approvers: + - fillzpp + + # folks who can review and LGTM any PRs in the repo (doesn't + # include approvers & admins -- those count too via the OWNERS + # file) + controller-runtime-reviewers: + - varshaprasad96 + - inteon + + # folks to can approve things in the directly-ported + # testing_frameworks portions of the codebase + testing-integration-approvers: + - apelisse + - hoegaarden + + # folks who may have context on ancient history, + # but are no longer directly involved + controller-runtime-emeritus-maintainers: + - directxman12 + controller-runtime-emeritus-admins: + - droot + - mengqiy + - pwittrock diff --git a/vendor/sigs.k8s.io/controller-runtime/README.md b/vendor/sigs.k8s.io/controller-runtime/README.md new file mode 100644 index 00000000..e785abdd --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/README.md @@ -0,0 +1,66 @@ +[![Go Report Card](https://goreportcard.com/badge/sigs.k8s.io/controller-runtime)](https://goreportcard.com/report/sigs.k8s.io/controller-runtime) +[![godoc](https://pkg.go.dev/badge/sigs.k8s.io/controller-runtime)](https://pkg.go.dev/sigs.k8s.io/controller-runtime) + +# Kubernetes controller-runtime Project + +The Kubernetes controller-runtime Project is a set of go libraries for building +Controllers. It is leveraged by [Kubebuilder](https://book.kubebuilder.io/) and +[Operator SDK](https://github.com/operator-framework/operator-sdk). Both are +a great place to start for new projects. See +[Kubebuilder's Quick Start](https://book.kubebuilder.io/quick-start.html) to +see how it can be used. + +Documentation: + +- [Package overview](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg) +- [Basic controller using builder](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/builder#example-Builder) +- [Creating a manager](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/manager#example-New) +- [Creating a controller](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller#example-New) +- [Examples](https://github.com/kubernetes-sigs/controller-runtime/blob/main/examples) +- [Designs](https://github.com/kubernetes-sigs/controller-runtime/blob/main/designs) + +# Versioning, Maintenance, and Compatibility + +The full documentation can be found at [VERSIONING.md](VERSIONING.md), but TL;DR: + +Users: + +- We follow [Semantic Versioning (semver)](https://semver.org) +- Use releases with your dependency management to ensure that you get compatible code +- The main branch contains all the latest code, some of which may break compatibility (so "normal" `go get` is not recommended) + +Contributors: + +- All code PR must be labeled with :bug: (patch fixes), :sparkles: (backwards-compatible features), or :warning: (breaking changes) +- Breaking changes will find their way into the next major release, other changes will go into an semi-immediate patch or minor release +- For a quick PR template suggesting the right information, use one of these PR templates: + * [Breaking Changes/Features](/.github/PULL_REQUEST_TEMPLATE/breaking_change.md) + * [Backwards-Compatible Features](/.github/PULL_REQUEST_TEMPLATE/compat_feature.md) + * [Bug fixes](/.github/PULL_REQUEST_TEMPLATE/bug_fix.md) + * [Documentation Changes](/.github/PULL_REQUEST_TEMPLATE/docs.md) + * [Test/Build/Other Changes](/.github/PULL_REQUEST_TEMPLATE/other.md) + +## FAQ + +See [FAQ.md](FAQ.md) + +## Community, discussion, contribution, and support + +Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/). + +controller-runtime is a subproject of the [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) project +in sig apimachinery. + +You can reach the maintainers of this project at: + +- Slack channel: [#controller-runtime](https://kubernetes.slack.com/archives/C02MRBMN00Z) +- Google Group: [kubebuilder@googlegroups.com](https://groups.google.com/forum/#!forum/kubebuilder) + +## Contributing +Contributions are greatly appreciated. The maintainers actively manage the issues list, and try to highlight issues suitable for newcomers. +The project follows the typical GitHub pull request model. See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. +Before starting any work, please either comment on an existing issue, or file a new one. + +## Code of conduct + +Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). diff --git a/vendor/sigs.k8s.io/controller-runtime/RELEASE.md b/vendor/sigs.k8s.io/controller-runtime/RELEASE.md new file mode 100644 index 00000000..2a857b97 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/RELEASE.md @@ -0,0 +1,51 @@ +# Release Process + +The Kubernetes controller-runtime Project is released on an as-needed basis. The process is as follows: + +**Note:** Releases are done from the `release-MAJOR.MINOR` branches. For PATCH releases is not required +to create a new branch you will just need to ensure that all big fixes are cherry-picked into the respective +`release-MAJOR.MINOR` branch. To know more about versioning check https://semver.org/. + +## How to do a release + +### Create the new branch and the release tag + +1. Create a new branch `git checkout -b release-` from main +2. Push the new branch to the remote repository + +### Now, let's generate the changelog + +1. Create the changelog from the new branch `release-` (`git checkout release-`). +You will need to use the [kubebuilder-release-tools][kubebuilder-release-tools] to generate the notes. See [here][release-notes-generation] + +> **Note** +> - You will need to have checkout locally from the remote repository the previous branch +> - Also, ensure that you fetch all tags from the remote `git fetch --all --tags` + +### Draft a new release from GitHub + +1. Create a new tag with the correct version from the new `release-` branch +2. Add the changelog on it and publish. Now, the code source is released ! + +### Add a new Prow test the for the new branch release + +1. Create a new prow test under [github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime](https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime) +for the new `release-` branch. (i.e. for the `0.11.0` release see the PR: https://github.com/kubernetes/test-infra/pull/25205) +2. Ping the infra PR in the controller-runtime slack channel for reviews. + +### Announce the new release: + +1. Publish on the Slack channel the new release, i.e: + +```` +:announce: Controller-Runtime v0.12.0 has been released! +This release includes a Kubernetes dependency bump to v1.24. +For more info, see the release page: https://github.com/kubernetes-sigs/controller-runtime/releases. + :tada: Thanks to all our contributors! +```` + +2. An announcement email is sent to `kubebuilder@googlegroups.com` with the subject `[ANNOUNCE] Controller-Runtime $VERSION is released` + +[kubebuilder-release-tools]: https://github.com/kubernetes-sigs/kubebuilder-release-tools +[release-notes-generation]: https://github.com/kubernetes-sigs/kubebuilder-release-tools/blob/master/README.md#release-notes-generation +[release-process]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/VERSIONING.md#releasing diff --git a/vendor/k8s.io/code-generator/SECURITY_CONTACTS b/vendor/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS similarity index 57% rename from vendor/k8s.io/code-generator/SECURITY_CONTACTS rename to vendor/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS index f6003980..9c5241c6 100644 --- a/vendor/k8s.io/code-generator/SECURITY_CONTACTS +++ b/vendor/sigs.k8s.io/controller-runtime/SECURITY_CONTACTS @@ -1,16 +1,15 @@ # Defined below are the security contacts for this repo. # -# They are the contact point for the Product Security Committee to reach out +# They are the contact point for the Product Security Team to reach out # to for triaging and handling of incoming issues. # # The below names agree to abide by the -# [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy) +# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy) # and will be removed and replaced if they violate that agreement. # # DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE # INSTRUCTIONS AT https://kubernetes.io/security/ -cheftako -deads2k -lavalamp -sttts +alvaroaleman +sbueringer +vincepri diff --git a/vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md b/vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md new file mode 100644 index 00000000..97e091fd --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md @@ -0,0 +1,169 @@ +Logging Guidelines +================== + +controller-runtime uses a kind of logging called *structured logging*. If +you've used a library like Zap or logrus before, you'll be familiar with +the concepts we use. If you've only used a logging library like the "log" +package (in the Go standard library) or "glog" (in Kubernetes), you'll +need to adjust how you think about logging a bit. + +### Getting Started With Structured Logging + +With structured logging, we associate a *constant* log message with some +variable key-value pairs. For instance, suppose we wanted to log that we +were starting reconciliation on a pod. In the Go standard library logger, +we might write: + +```go +log.Printf("starting reconciliation for pod %s/%s", podNamespace, podName) +``` + +In controller-runtime, we'd instead write: + +```go +logger.Info("starting reconciliation", "pod", req.NamespacedName) +``` + +or even write + +```go +func (r *Reconciler) Reconcile(req reconcile.Request) (reconcile.Response, error) { + logger := logger.WithValues("pod", req.NamespacedName) + // do some stuff + logger.Info("starting reconciliation") +} +``` + +Notice how we've broken out the information that we want to convey into +a constant message (`"starting reconciliation"`) and some key-value pairs +that convey variable information (`"pod", req.NamespacedName`). We've +there-by added "structure" to our logs, which makes them easier to save +and search later, as well as correlate with metrics and events. + +All of controller-runtime's logging is done via +[logr](https://github.com/go-logr/logr), a generic interface for +structured logging. You can use whichever logging library you want to +implement the actual mechanics of the logging. controller-runtime +provides some helpers to make it easy to use +[Zap](https://go.uber.org/zap) as the implementation. + +You can configure the logging implementation using +`"sigs.k8s.io/controller-runtime/pkg/log".SetLogger`. That +package also contains the convenience functions for setting up Zap. + +You can get a handle to the "root" logger using +`"sigs.k8s.io/controller-runtime/pkg/log".Log`, and can then call +`WithName` to create individual named loggers. You can call `WithName` +repeatedly to chain names together: + +```go +logger := log.Log.WithName("controller").WithName("replicaset") +// in reconcile... +logger = logger.WithValues("replicaset", req.NamespacedName) +// later on in reconcile... +logger.Info("doing things with pods", "pod", newPod) +``` + +As seen above, you can also call `WithValue` to create a new sub-logger +that always attaches some key-value pairs to a logger. + +Finally, you can use `V(1)` to mark a particular log line as "debug" logs: + +```go +logger.V(1).Info("this is particularly verbose!", "state of the world", +allKubernetesObjectsEverywhere) +``` + +While it's possible to use higher log levels, it's recommended that you +stick with `V(1)` or `V(0)` (which is equivalent to not specifying `V`), +and then filter later based on key-value pairs or messages; different +numbers tend to lose meaning easily over time, and you'll be left +wondering why particular logs lines are at `V(5)` instead of `V(7)`. + +## Logging errors + +Errors should *always* be logged with `log.Error`, which allows logr +implementations to provide special handling of errors (for instance, +providing stack traces in debug mode). + +It's acceptable to log call `log.Error` with a nil error object. This +conveys that an error occurred in some capacity, but that no actual +`error` object was involved. + +Errors returned by the `Reconcile` implementation of the `Reconciler` interface are commonly logged as a `Reconciler error`. +It's a developer choice to create an additional error log in the `Reconcile` implementation so a more specific file name and line for the error are returned. + +## Logging messages + +- Don't put variable content in your messages -- use key-value pairs for + that. Never use `fmt.Sprintf` in your message. + +- Try to match the terminology in your messages with your key-value pairs + -- for instance, if you have a key-value pairs `api version`, use the + term `APIVersion` instead of `GroupVersion` in your message. + +## Logging Kubernetes Objects + +Kubernetes objects should be logged directly, like `log.Info("this is +a Kubernetes object", "pod", somePod)`. controller-runtime provides +a special encoder for Zap that will transform Kubernetes objects into +`name, namespace, apiVersion, kind` objects, when available and not in +development mode. Other logr implementations should implement similar +logic. + +## Logging Structured Values (Key-Value pairs) + +- Use lower-case, space separated keys. For example `object` for objects, + `api version` for `APIVersion` + +- Be consistent across your application, and with controller-runtime when + possible. + +- Try to be brief but descriptive. + +- Match terminology in keys with terminology in the message. + +- Be careful logging non-Kubernetes objects verbatim if they're very + large. + +### Groups, Versions, and Kinds + +- Kinds should not be logged alone (they're meaningless alone). Use + a `GroupKind` object to log them instead, or a `GroupVersionKind` when + version is relevant. + +- If you need to log an API version string, use `api version` as the key + (formatted as with a `GroupVersion`, or as received directly from API + discovery). + +### Objects and Types + +- If code works with a generic Kubernetes `runtime.Object`, use the + `object` key. For specific objects, prefer the resource name as the key + (e.g. `pod` for `v1.Pod` objects). + +- For non-Kubernetes objects, the `object` key may also be used, if you + accept a generic interface. + +- When logging a raw type, log it using the `type` key, with a value of + `fmt.Sprintf("%T", typ)` + +- If there's specific context around a type, the key may be more specific, + but should end with `type` -- for instance, `OwnerType` should be logged + as `owner` in the context of `log.Error(err, "Could not get ObjectKinds + for OwnerType", `owner type`, fmt.Sprintf("%T"))`. When possible, favor + communicating kind instead. + +### Multiple things + +- When logging multiple things, simply pluralize the key. + +### controller-runtime Specifics + +- Reconcile requests should be logged as `request`, although normal code + should favor logging the key. + +- Reconcile keys should be logged as with the same key as if you were + logging the object directly (e.g. `log.Info("reconciling pod", "pod", + req.NamespacedName)`). This ends up having a similar effect to logging + the object directly. diff --git a/vendor/sigs.k8s.io/controller-runtime/VERSIONING.md b/vendor/sigs.k8s.io/controller-runtime/VERSIONING.md new file mode 100644 index 00000000..2c0f2f9b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/VERSIONING.md @@ -0,0 +1,30 @@ +# Versioning and Branching in controller-runtime + +We follow the [common KubeBuilder versioning guidelines][guidelines], and +use the corresponding tooling. + +For the purposes of the aforementioned guidelines, controller-runtime +counts as a "library project", but otherwise follows the guidelines +exactly. + +[guidelines]: https://sigs.k8s.io/kubebuilder-release-tools/VERSIONING.md + +## Compatibility and Release Support + +For release branches, we generally tend to support backporting one (1) +major release (`release-{X-1}` or `release-0.{Y-1}`), but may go back +further if the need arises and is very pressing (e.g. security updates). + +### Dependency Support + +Note the [guidelines on dependency versions][dep-versions]. Particularly: + +- We **DO** guarantee Kubernetes REST API compatibility -- if a given + version of controller-runtime stops working with what should be + a supported version of Kubernetes, this is almost certainly a bug. + +- We **DO NOT** guarantee any particular compatibility matrix between + kubernetes library dependencies (client-go, apimachinery, etc); Such + compatibility is infeasible due to the way those libraries are versioned. + +[dep-versions]: https://sigs.k8s.io/kubebuilder-release-tools/VERSIONING.md#kubernetes-version-compatibility diff --git a/vendor/sigs.k8s.io/controller-runtime/alias.go b/vendor/sigs.k8s.io/controller-runtime/alias.go new file mode 100644 index 00000000..1f8092f4 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/alias.go @@ -0,0 +1,159 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package controllerruntime + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client/config" + cfg "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +// Builder builds an Application ControllerManagedBy (e.g. Operator) and returns a manager.Manager to start it. +type Builder = builder.Builder + +// Request contains the information necessary to reconcile a Kubernetes object. This includes the +// information to uniquely identify the object - its Name and Namespace. It does NOT contain information about +// any specific Event or the object contents itself. +type Request = reconcile.Request + +// Result contains the result of a Reconciler invocation. +type Result = reconcile.Result + +// Manager initializes shared dependencies such as Caches and Clients, and provides them to Runnables. +// A Manager is required to create Controllers. +type Manager = manager.Manager + +// Options are the arguments for creating a new Manager. +type Options = manager.Options + +// SchemeBuilder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds. +type SchemeBuilder = scheme.Builder + +// GroupVersion contains the "group" and the "version", which uniquely identifies the API. +type GroupVersion = schema.GroupVersion + +// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying +// concepts during lookup stages without having partially valid types. +type GroupResource = schema.GroupResource + +// TypeMeta describes an individual object in an API response or request +// with strings representing the type of the object and its API schema version. +// Structures that are versioned or persisted should inline TypeMeta. +// +// +k8s:deepcopy-gen=false +type TypeMeta = metav1.TypeMeta + +// ObjectMeta is metadata that all persisted resources must have, which includes all objects +// users must create. +type ObjectMeta = metav1.ObjectMeta + +var ( + // RegisterFlags registers flag variables to the given FlagSet if not already registered. + // It uses the default command line FlagSet, if none is provided. Currently, it only registers the kubeconfig flag. + RegisterFlags = config.RegisterFlags + + // GetConfigOrDie creates a *rest.Config for talking to a Kubernetes apiserver. + // If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running + // in cluster and use the cluster provided kubeconfig. + // + // Will log an error and exit if there is an error creating the rest.Config. + GetConfigOrDie = config.GetConfigOrDie + + // GetConfig creates a *rest.Config for talking to a Kubernetes apiserver. + // If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running + // in cluster and use the cluster provided kubeconfig. + // + // Config precedence + // + // * --kubeconfig flag pointing at a file + // + // * KUBECONFIG environment variable pointing at a file + // + // * In-cluster config if running in cluster + // + // * $HOME/.kube/config if exists. + GetConfig = config.GetConfig + + // ConfigFile returns the cfg.File function for deferred config file loading, + // this is passed into Options{}.From() to populate the Options fields for + // the manager. + // + // Deprecated: This is deprecated in favor of using Options directly. + ConfigFile = cfg.File + + // NewControllerManagedBy returns a new controller builder that will be started by the provided Manager. + NewControllerManagedBy = builder.ControllerManagedBy + + // NewWebhookManagedBy returns a new webhook builder that will be started by the provided Manager. + NewWebhookManagedBy = builder.WebhookManagedBy + + // NewManager returns a new Manager for creating Controllers. + // Note that if ContentType in the given config is not set, "application/vnd.kubernetes.protobuf" + // will be used for all built-in resources of Kubernetes, and "application/json" is for other types + // including all CRD resources. + NewManager = manager.New + + // CreateOrUpdate creates or updates the given object obj in the Kubernetes + // cluster. The object's desired state should be reconciled with the existing + // state using the passed in ReconcileFn. obj must be a struct pointer so that + // obj can be updated with the content returned by the Server. + // + // It returns the executed operation and an error. + CreateOrUpdate = controllerutil.CreateOrUpdate + + // SetControllerReference sets owner as a Controller OwnerReference on owned. + // This is used for garbage collection of the owned object and for + // reconciling the owner object on changes to owned (with a Watch + EnqueueRequestForOwner). + // Since only one OwnerReference can be a controller, it returns an error if + // there is another OwnerReference with Controller flag set. + SetControllerReference = controllerutil.SetControllerReference + + // SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned + // which is closed on one of these signals. If a second signal is caught, the program + // is terminated with exit code 1. + SetupSignalHandler = signals.SetupSignalHandler + + // Log is the base logger used by controller-runtime. It delegates + // to another logr.Logger. You *must* call SetLogger to + // get any actual logging. + Log = log.Log + + // LoggerFrom returns a logger with predefined values from a context.Context. + // The logger, when used with controllers, can be expected to contain basic information about the object + // that's being reconciled like: + // - `reconciler group` and `reconciler kind` coming from the For(...) object passed in when building a controller. + // - `name` and `namespace` from the reconciliation request. + // + // This is meant to be used with the context supplied in a struct that satisfies the Reconciler interface. + LoggerFrom = log.FromContext + + // LoggerInto takes a context and sets the logger as one of its keys. + // + // This is meant to be used in reconcilers to enrich the logger within a context with additional values. + LoggerInto = log.IntoContext + + // SetLogger sets a concrete logging implementation for all deferred Loggers. + SetLogger = log.SetLogger +) diff --git a/vendor/k8s.io/code-generator/code-of-conduct.md b/vendor/sigs.k8s.io/controller-runtime/code-of-conduct.md similarity index 100% rename from vendor/k8s.io/code-generator/code-of-conduct.md rename to vendor/sigs.k8s.io/controller-runtime/code-of-conduct.md diff --git a/vendor/sigs.k8s.io/controller-runtime/doc.go b/vendor/sigs.k8s.io/controller-runtime/doc.go new file mode 100644 index 00000000..0319bc3f --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/doc.go @@ -0,0 +1,128 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +// Package controllerruntime provides tools to construct Kubernetes-style +// controllers that manipulate both Kubernetes CRDs and aggregated/built-in +// Kubernetes APIs. +// +// It defines easy helpers for the common use cases when building CRDs, built +// on top of customizable layers of abstraction. Common cases should be easy, +// and uncommon cases should be possible. In general, controller-runtime tries +// to guide users towards Kubernetes controller best-practices. +// +// # Getting Started +// +// The main entrypoint for controller-runtime is this root package, which +// contains all of the common types needed to get started building controllers: +// +// import ( +// ctrl "sigs.k8s.io/controller-runtime" +// ) +// +// The examples in this package walk through a basic controller setup. The +// kubebuilder book (https://book.kubebuilder.io) has some more in-depth +// walkthroughs. +// +// controller-runtime favors structs with sane defaults over constructors, so +// it's fairly common to see structs being used directly in controller-runtime. +// +// # Organization +// +// A brief-ish walkthrough of the layout of this library can be found below. Each +// package contains more information about how to use it. +// +// Frequently asked questions about using controller-runtime and designing +// controllers can be found at +// https://github.com/kubernetes-sigs/controller-runtime/blob/main/FAQ.md. +// +// # Managers +// +// Every controller and webhook is ultimately run by a Manager (pkg/manager). A +// manager is responsible for running controllers and webhooks, and setting up +// common dependencies, like shared caches and clients, as +// well as managing leader election (pkg/leaderelection). Managers are +// generally configured to gracefully shut down controllers on pod termination +// by wiring up a signal handler (pkg/manager/signals). +// +// # Controllers +// +// Controllers (pkg/controller) use events (pkg/event) to eventually trigger +// reconcile requests. They may be constructed manually, but are often +// constructed with a Builder (pkg/builder), which eases the wiring of event +// sources (pkg/source), like Kubernetes API object changes, to event handlers +// (pkg/handler), like "enqueue a reconcile request for the object owner". +// Predicates (pkg/predicate) can be used to filter which events actually +// trigger reconciles. There are pre-written utilities for the common cases, and +// interfaces and helpers for advanced cases. +// +// # Reconcilers +// +// Controller logic is implemented in terms of Reconcilers (pkg/reconcile). A +// Reconciler implements a function which takes a reconcile Request containing +// the name and namespace of the object to reconcile, reconciles the object, +// and returns a Response or an error indicating whether to requeue for a +// second round of processing. +// +// # Clients and Caches +// +// Reconcilers use Clients (pkg/client) to access API objects. The default +// client provided by the manager reads from a local shared cache (pkg/cache) +// and writes directly to the API server, but clients can be constructed that +// only talk to the API server, without a cache. The Cache will auto-populate +// with watched objects, as well as when other structured objects are +// requested. The default split client does not promise to invalidate the cache +// during writes (nor does it promise sequential create/get coherence), and code +// should not assume a get immediately following a create/update will return +// the updated resource. Caches may also have indexes, which can be created via +// a FieldIndexer (pkg/client) obtained from the manager. Indexes can used to +// quickly and easily look up all objects with certain fields set. Reconcilers +// may retrieve event recorders (pkg/recorder) to emit events using the +// manager. +// +// # Schemes +// +// Clients, Caches, and many other things in Kubernetes use Schemes +// (pkg/scheme) to associate Go types to Kubernetes API Kinds +// (Group-Version-Kinds, to be specific). +// +// # Webhooks +// +// Similarly, webhooks (pkg/webhook/admission) may be implemented directly, but +// are often constructed using a builder (pkg/webhook/admission/builder). They +// are run via a server (pkg/webhook) which is managed by a Manager. +// +// # Logging and Metrics +// +// Logging (pkg/log) in controller-runtime is done via structured logs, using a +// log set of interfaces called logr +// (https://pkg.go.dev/github.com/go-logr/logr). While controller-runtime +// provides easy setup for using Zap (https://go.uber.org/zap, pkg/log/zap), +// you can provide any implementation of logr as the base logger for +// controller-runtime. +// +// Metrics (pkg/metrics) provided by controller-runtime are registered into a +// controller-runtime-specific Prometheus metrics registry. The manager can +// serve these by an HTTP endpoint, and additional metrics may be registered to +// this Registry as normal. +// +// # Testing +// +// You can easily build integration and unit tests for your controllers and +// webhooks using the test Environment (pkg/envtest). This will automatically +// stand up a copy of etcd and kube-apiserver, and provide the correct options +// to connect to the API server. It's designed to work well with the Ginkgo +// testing framework, but should work with any testing setup. +package controllerruntime diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go new file mode 100644 index 00000000..1a115f2f --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go @@ -0,0 +1,413 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package builder + +import ( + "errors" + "fmt" + "strings" + + "github.com/go-logr/logr" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/klog/v2" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + internalsource "sigs.k8s.io/controller-runtime/pkg/internal/source" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +// Supporting mocking out functions for testing. +var newController = controller.New +var getGvk = apiutil.GVKForObject + +// project represents other forms that we can use to +// send/receive a given resource (metadata-only, unstructured, etc). +type objectProjection int + +const ( + // projectAsNormal doesn't change the object from the form given. + projectAsNormal objectProjection = iota + // projectAsMetadata turns this into a metadata-only watch. + projectAsMetadata +) + +// Builder builds a Controller. +type Builder struct { + forInput ForInput + ownsInput []OwnsInput + watchesInput []WatchesInput + mgr manager.Manager + globalPredicates []predicate.Predicate + ctrl controller.Controller + ctrlOptions controller.Options + name string +} + +// ControllerManagedBy returns a new controller builder that will be started by the provided Manager. +func ControllerManagedBy(m manager.Manager) *Builder { + return &Builder{mgr: m} +} + +// ForInput represents the information set by the For method. +type ForInput struct { + object client.Object + predicates []predicate.Predicate + objectProjection objectProjection + err error +} + +// For defines the type of Object being *reconciled*, and configures the ControllerManagedBy to respond to create / delete / +// update events by *reconciling the object*. +// This is the equivalent of calling +// Watches(&source.Kind{Type: apiType}, &handler.EnqueueRequestForObject{}). +func (blder *Builder) For(object client.Object, opts ...ForOption) *Builder { + if blder.forInput.object != nil { + blder.forInput.err = fmt.Errorf("For(...) should only be called once, could not assign multiple objects for reconciliation") + return blder + } + input := ForInput{object: object} + for _, opt := range opts { + opt.ApplyToFor(&input) + } + + blder.forInput = input + return blder +} + +// OwnsInput represents the information set by Owns method. +type OwnsInput struct { + matchEveryOwner bool + object client.Object + predicates []predicate.Predicate + objectProjection objectProjection +} + +// Owns defines types of Objects being *generated* by the ControllerManagedBy, and configures the ControllerManagedBy to respond to +// create / delete / update events by *reconciling the owner object*. +// +// The default behavior reconciles only the first controller-type OwnerReference of the given type. +// Use Owns(object, builder.MatchEveryOwner) to reconcile all owners. +// +// By default, this is the equivalent of calling +// Watches(object, handler.EnqueueRequestForOwner([...], ownerType, OnlyControllerOwner())). +func (blder *Builder) Owns(object client.Object, opts ...OwnsOption) *Builder { + input := OwnsInput{object: object} + for _, opt := range opts { + opt.ApplyToOwns(&input) + } + + blder.ownsInput = append(blder.ownsInput, input) + return blder +} + +// WatchesInput represents the information set by Watches method. +type WatchesInput struct { + src source.Source + eventHandler handler.EventHandler + predicates []predicate.Predicate + objectProjection objectProjection +} + +// Watches defines the type of Object to watch, and configures the ControllerManagedBy to respond to create / delete / +// update events by *reconciling the object* with the given EventHandler. +// +// This is the equivalent of calling +// WatchesRawSource(source.Kind(cache, object), eventHandler, opts...). +func (blder *Builder) Watches(object client.Object, eventHandler handler.EventHandler, opts ...WatchesOption) *Builder { + src := source.Kind(blder.mgr.GetCache(), object) + return blder.WatchesRawSource(src, eventHandler, opts...) +} + +// WatchesMetadata is the same as Watches, but forces the internal cache to only watch PartialObjectMetadata. +// +// This is useful when watching lots of objects, really big objects, or objects for which you only know +// the GVK, but not the structure. You'll need to pass metav1.PartialObjectMetadata to the client +// when fetching objects in your reconciler, otherwise you'll end up with a duplicate structured or unstructured cache. +// +// When watching a resource with metadata only, for example the v1.Pod, you should not Get and List using the v1.Pod type. +// Instead, you should use the special metav1.PartialObjectMetadata type. +// +// ❌ Incorrect: +// +// pod := &v1.Pod{} +// mgr.GetClient().Get(ctx, nsAndName, pod) +// +// ✅ Correct: +// +// pod := &metav1.PartialObjectMetadata{} +// pod.SetGroupVersionKind(schema.GroupVersionKind{ +// Group: "", +// Version: "v1", +// Kind: "Pod", +// }) +// mgr.GetClient().Get(ctx, nsAndName, pod) +// +// In the first case, controller-runtime will create another cache for the +// concrete type on top of the metadata cache; this increases memory +// consumption and leads to race conditions as caches are not in sync. +func (blder *Builder) WatchesMetadata(object client.Object, eventHandler handler.EventHandler, opts ...WatchesOption) *Builder { + opts = append(opts, OnlyMetadata) + return blder.Watches(object, eventHandler, opts...) +} + +// WatchesRawSource exposes the lower-level ControllerManagedBy Watches functions through the builder. +// Specified predicates are registered only for given source. +// +// STOP! Consider using For(...), Owns(...), Watches(...), WatchesMetadata(...) instead. +// This method is only exposed for more advanced use cases, most users should use one of the higher level functions. +func (blder *Builder) WatchesRawSource(src source.Source, eventHandler handler.EventHandler, opts ...WatchesOption) *Builder { + input := WatchesInput{src: src, eventHandler: eventHandler} + for _, opt := range opts { + opt.ApplyToWatches(&input) + } + + blder.watchesInput = append(blder.watchesInput, input) + return blder +} + +// WithEventFilter sets the event filters, to filter which create/update/delete/generic events eventually +// trigger reconciliations. For example, filtering on whether the resource version has changed. +// Given predicate is added for all watched objects. +// Defaults to the empty list. +func (blder *Builder) WithEventFilter(p predicate.Predicate) *Builder { + blder.globalPredicates = append(blder.globalPredicates, p) + return blder +} + +// WithOptions overrides the controller options used in doController. Defaults to empty. +func (blder *Builder) WithOptions(options controller.Options) *Builder { + blder.ctrlOptions = options + return blder +} + +// WithLogConstructor overrides the controller options's LogConstructor. +func (blder *Builder) WithLogConstructor(logConstructor func(*reconcile.Request) logr.Logger) *Builder { + blder.ctrlOptions.LogConstructor = logConstructor + return blder +} + +// Named sets the name of the controller to the given name. The name shows up +// in metrics, among other things, and thus should be a prometheus compatible name +// (underscores and alphanumeric characters only). +// +// By default, controllers are named using the lowercase version of their kind. +func (blder *Builder) Named(name string) *Builder { + blder.name = name + return blder +} + +// Complete builds the Application Controller. +func (blder *Builder) Complete(r reconcile.Reconciler) error { + _, err := blder.Build(r) + return err +} + +// Build builds the Application Controller and returns the Controller it created. +func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, error) { + if r == nil { + return nil, fmt.Errorf("must provide a non-nil Reconciler") + } + if blder.mgr == nil { + return nil, fmt.Errorf("must provide a non-nil Manager") + } + if blder.forInput.err != nil { + return nil, blder.forInput.err + } + + // Set the ControllerManagedBy + if err := blder.doController(r); err != nil { + return nil, err + } + + // Set the Watch + if err := blder.doWatch(); err != nil { + return nil, err + } + + return blder.ctrl, nil +} + +func (blder *Builder) project(obj client.Object, proj objectProjection) (client.Object, error) { + switch proj { + case projectAsNormal: + return obj, nil + case projectAsMetadata: + metaObj := &metav1.PartialObjectMetadata{} + gvk, err := getGvk(obj, blder.mgr.GetScheme()) + if err != nil { + return nil, fmt.Errorf("unable to determine GVK of %T for a metadata-only watch: %w", obj, err) + } + metaObj.SetGroupVersionKind(gvk) + return metaObj, nil + default: + panic(fmt.Sprintf("unexpected projection type %v on type %T, should not be possible since this is an internal field", proj, obj)) + } +} + +func (blder *Builder) doWatch() error { + // Reconcile type + if blder.forInput.object != nil { + obj, err := blder.project(blder.forInput.object, blder.forInput.objectProjection) + if err != nil { + return err + } + src := source.Kind(blder.mgr.GetCache(), obj) + hdler := &handler.EnqueueRequestForObject{} + allPredicates := append([]predicate.Predicate(nil), blder.globalPredicates...) + allPredicates = append(allPredicates, blder.forInput.predicates...) + if err := blder.ctrl.Watch(src, hdler, allPredicates...); err != nil { + return err + } + } + + // Watches the managed types + if len(blder.ownsInput) > 0 && blder.forInput.object == nil { + return errors.New("Owns() can only be used together with For()") + } + for _, own := range blder.ownsInput { + obj, err := blder.project(own.object, own.objectProjection) + if err != nil { + return err + } + src := source.Kind(blder.mgr.GetCache(), obj) + opts := []handler.OwnerOption{} + if !own.matchEveryOwner { + opts = append(opts, handler.OnlyControllerOwner()) + } + hdler := handler.EnqueueRequestForOwner( + blder.mgr.GetScheme(), blder.mgr.GetRESTMapper(), + blder.forInput.object, + opts..., + ) + allPredicates := append([]predicate.Predicate(nil), blder.globalPredicates...) + allPredicates = append(allPredicates, own.predicates...) + if err := blder.ctrl.Watch(src, hdler, allPredicates...); err != nil { + return err + } + } + + // Do the watch requests + if len(blder.watchesInput) == 0 && blder.forInput.object == nil { + return errors.New("there are no watches configured, controller will never get triggered. Use For(), Owns() or Watches() to set them up") + } + for _, w := range blder.watchesInput { + // If the source of this watch is of type Kind, project it. + if srcKind, ok := w.src.(*internalsource.Kind); ok { + typeForSrc, err := blder.project(srcKind.Type, w.objectProjection) + if err != nil { + return err + } + srcKind.Type = typeForSrc + } + allPredicates := append([]predicate.Predicate(nil), blder.globalPredicates...) + allPredicates = append(allPredicates, w.predicates...) + if err := blder.ctrl.Watch(w.src, w.eventHandler, allPredicates...); err != nil { + return err + } + } + return nil +} + +func (blder *Builder) getControllerName(gvk schema.GroupVersionKind, hasGVK bool) (string, error) { + if blder.name != "" { + return blder.name, nil + } + if !hasGVK { + return "", errors.New("one of For() or Named() must be called") + } + return strings.ToLower(gvk.Kind), nil +} + +func (blder *Builder) doController(r reconcile.Reconciler) error { + globalOpts := blder.mgr.GetControllerOptions() + + ctrlOptions := blder.ctrlOptions + if ctrlOptions.Reconciler != nil && r != nil { + return errors.New("reconciler was set via WithOptions() and via Build() or Complete()") + } + if ctrlOptions.Reconciler == nil { + ctrlOptions.Reconciler = r + } + + // Retrieve the GVK from the object we're reconciling + // to pre-populate logger information, and to optionally generate a default name. + var gvk schema.GroupVersionKind + hasGVK := blder.forInput.object != nil + if hasGVK { + var err error + gvk, err = getGvk(blder.forInput.object, blder.mgr.GetScheme()) + if err != nil { + return err + } + } + + // Setup concurrency. + if ctrlOptions.MaxConcurrentReconciles == 0 && hasGVK { + groupKind := gvk.GroupKind().String() + + if concurrency, ok := globalOpts.GroupKindConcurrency[groupKind]; ok && concurrency > 0 { + ctrlOptions.MaxConcurrentReconciles = concurrency + } + } + + // Setup cache sync timeout. + if ctrlOptions.CacheSyncTimeout == 0 && globalOpts.CacheSyncTimeout > 0 { + ctrlOptions.CacheSyncTimeout = globalOpts.CacheSyncTimeout + } + + controllerName, err := blder.getControllerName(gvk, hasGVK) + if err != nil { + return err + } + + // Setup the logger. + if ctrlOptions.LogConstructor == nil { + log := blder.mgr.GetLogger().WithValues( + "controller", controllerName, + ) + if hasGVK { + log = log.WithValues( + "controllerGroup", gvk.Group, + "controllerKind", gvk.Kind, + ) + } + + ctrlOptions.LogConstructor = func(req *reconcile.Request) logr.Logger { + log := log + if req != nil { + if hasGVK { + log = log.WithValues(gvk.Kind, klog.KRef(req.Namespace, req.Name)) + } + log = log.WithValues( + "namespace", req.Namespace, "name", req.Name, + ) + } + return log + } + } + + // Build the controller and return. + blder.ctrl, err = newController(controllerName, blder.mgr, ctrlOptions) + return err +} diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/rules/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/doc.go similarity index 57% rename from vendor/k8s.io/kube-openapi/pkg/generators/rules/doc.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/builder/doc.go index 384a44dc..e4df1b70 100644 --- a/vendor/k8s.io/kube-openapi/pkg/generators/rules/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/doc.go @@ -14,10 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package rules contains API rules that are enforced in OpenAPI spec generation -// as part of the machinery. Files under this package implement APIRule interface -// which evaluates Go type and produces list of API rule violations. +// Package builder wraps other controller-runtime libraries and exposes simple +// patterns for building common Controllers. // -// Implementations of APIRule should be added to API linter under openAPIGen code- -// generator to get integrated in the generation process. -package rules +// Projects built with the builder package can trivially be rebased on top of the underlying +// packages if the project requires more customized behavior in the future. +package builder + +import ( + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("builder") diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go new file mode 100644 index 00000000..15f66b2a --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go @@ -0,0 +1,156 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package builder + +import ( + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// {{{ "Functional" Option Interfaces + +// ForOption is some configuration that modifies options for a For request. +type ForOption interface { + // ApplyToFor applies this configuration to the given for input. + ApplyToFor(*ForInput) +} + +// OwnsOption is some configuration that modifies options for an owns request. +type OwnsOption interface { + // ApplyToOwns applies this configuration to the given owns input. + ApplyToOwns(*OwnsInput) +} + +// WatchesOption is some configuration that modifies options for a watches request. +type WatchesOption interface { + // ApplyToWatches applies this configuration to the given watches options. + ApplyToWatches(*WatchesInput) +} + +// }}} + +// {{{ Multi-Type Options + +// WithPredicates sets the given predicates list. +func WithPredicates(predicates ...predicate.Predicate) Predicates { + return Predicates{ + predicates: predicates, + } +} + +// Predicates filters events before enqueuing the keys. +type Predicates struct { + predicates []predicate.Predicate +} + +// ApplyToFor applies this configuration to the given ForInput options. +func (w Predicates) ApplyToFor(opts *ForInput) { + opts.predicates = w.predicates +} + +// ApplyToOwns applies this configuration to the given OwnsInput options. +func (w Predicates) ApplyToOwns(opts *OwnsInput) { + opts.predicates = w.predicates +} + +// ApplyToWatches applies this configuration to the given WatchesInput options. +func (w Predicates) ApplyToWatches(opts *WatchesInput) { + opts.predicates = w.predicates +} + +var _ ForOption = &Predicates{} +var _ OwnsOption = &Predicates{} +var _ WatchesOption = &Predicates{} + +// }}} + +// {{{ For & Owns Dual-Type options + +// projectAs configures the projection on the input. +// Currently only OnlyMetadata is supported. We might want to expand +// this to arbitrary non-special local projections in the future. +type projectAs objectProjection + +// ApplyToFor applies this configuration to the given ForInput options. +func (p projectAs) ApplyToFor(opts *ForInput) { + opts.objectProjection = objectProjection(p) +} + +// ApplyToOwns applies this configuration to the given OwnsInput options. +func (p projectAs) ApplyToOwns(opts *OwnsInput) { + opts.objectProjection = objectProjection(p) +} + +// ApplyToWatches applies this configuration to the given WatchesInput options. +func (p projectAs) ApplyToWatches(opts *WatchesInput) { + opts.objectProjection = objectProjection(p) +} + +var ( + // OnlyMetadata tells the controller to *only* cache metadata, and to watch + // the API server in metadata-only form. This is useful when watching + // lots of objects, really big objects, or objects for which you only know + // the GVK, but not the structure. You'll need to pass + // metav1.PartialObjectMetadata to the client when fetching objects in your + // reconciler, otherwise you'll end up with a duplicate structured or + // unstructured cache. + // + // When watching a resource with OnlyMetadata, for example the v1.Pod, you + // should not Get and List using the v1.Pod type. Instead, you should use + // the special metav1.PartialObjectMetadata type. + // + // ❌ Incorrect: + // + // pod := &v1.Pod{} + // mgr.GetClient().Get(ctx, nsAndName, pod) + // + // ✅ Correct: + // + // pod := &metav1.PartialObjectMetadata{} + // pod.SetGroupVersionKind(schema.GroupVersionKind{ + // Group: "", + // Version: "v1", + // Kind: "Pod", + // }) + // mgr.GetClient().Get(ctx, nsAndName, pod) + // + // In the first case, controller-runtime will create another cache for the + // concrete type on top of the metadata cache; this increases memory + // consumption and leads to race conditions as caches are not in sync. + OnlyMetadata = projectAs(projectAsMetadata) + + _ ForOption = OnlyMetadata + _ OwnsOption = OnlyMetadata + _ WatchesOption = OnlyMetadata +) + +// }}} + +// MatchEveryOwner determines whether the watch should be filtered based on +// controller ownership. As in, when the OwnerReference.Controller field is set. +// +// If passed as an option, +// the handler receives notification for every owner of the object with the given type. +// If unset (default), the handler receives notification only for the first +// OwnerReference with `Controller: true`. +var MatchEveryOwner = &matchEveryOwner{} + +type matchEveryOwner struct{} + +// ApplyToOwns applies this configuration to the given OwnsInput options. +func (o matchEveryOwner) ApplyToOwns(opts *OwnsInput) { + opts.matchEveryOwner = true +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go new file mode 100644 index 00000000..1a3712ef --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go @@ -0,0 +1,252 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package builder + +import ( + "errors" + "net/http" + "net/url" + "strings" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" + + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "sigs.k8s.io/controller-runtime/pkg/webhook/conversion" +) + +// WebhookBuilder builds a Webhook. +type WebhookBuilder struct { + apiType runtime.Object + customDefaulter admission.CustomDefaulter + customValidator admission.CustomValidator + gvk schema.GroupVersionKind + mgr manager.Manager + config *rest.Config + recoverPanic bool + logConstructor func(base logr.Logger, req *admission.Request) logr.Logger +} + +// WebhookManagedBy returns a new webhook builder. +func WebhookManagedBy(m manager.Manager) *WebhookBuilder { + return &WebhookBuilder{mgr: m} +} + +// TODO(droot): update the GoDoc for conversion. + +// For takes a runtime.Object which should be a CR. +// If the given object implements the admission.Defaulter interface, a MutatingWebhook will be wired for this type. +// If the given object implements the admission.Validator interface, a ValidatingWebhook will be wired for this type. +func (blder *WebhookBuilder) For(apiType runtime.Object) *WebhookBuilder { + blder.apiType = apiType + return blder +} + +// WithDefaulter takes an admission.CustomDefaulter interface, a MutatingWebhook will be wired for this type. +func (blder *WebhookBuilder) WithDefaulter(defaulter admission.CustomDefaulter) *WebhookBuilder { + blder.customDefaulter = defaulter + return blder +} + +// WithValidator takes a admission.CustomValidator interface, a ValidatingWebhook will be wired for this type. +func (blder *WebhookBuilder) WithValidator(validator admission.CustomValidator) *WebhookBuilder { + blder.customValidator = validator + return blder +} + +// WithLogConstructor overrides the webhook's LogConstructor. +func (blder *WebhookBuilder) WithLogConstructor(logConstructor func(base logr.Logger, req *admission.Request) logr.Logger) *WebhookBuilder { + blder.logConstructor = logConstructor + return blder +} + +// RecoverPanic indicates whether panics caused by the webhook should be recovered. +func (blder *WebhookBuilder) RecoverPanic() *WebhookBuilder { + blder.recoverPanic = true + return blder +} + +// Complete builds the webhook. +func (blder *WebhookBuilder) Complete() error { + // Set the Config + blder.loadRestConfig() + + // Configure the default LogConstructor + blder.setLogConstructor() + + // Set the Webhook if needed + return blder.registerWebhooks() +} + +func (blder *WebhookBuilder) loadRestConfig() { + if blder.config == nil { + blder.config = blder.mgr.GetConfig() + } +} + +func (blder *WebhookBuilder) setLogConstructor() { + if blder.logConstructor == nil { + blder.logConstructor = func(base logr.Logger, req *admission.Request) logr.Logger { + log := base.WithValues( + "webhookGroup", blder.gvk.Group, + "webhookKind", blder.gvk.Kind, + ) + if req != nil { + return log.WithValues( + blder.gvk.Kind, klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + "resource", req.Resource, "user", req.UserInfo.Username, + "requestID", req.UID, + ) + } + return log + } + } +} + +func (blder *WebhookBuilder) registerWebhooks() error { + typ, err := blder.getType() + if err != nil { + return err + } + + blder.gvk, err = apiutil.GVKForObject(typ, blder.mgr.GetScheme()) + if err != nil { + return err + } + + // Register webhook(s) for type + blder.registerDefaultingWebhook() + blder.registerValidatingWebhook() + + err = blder.registerConversionWebhook() + if err != nil { + return err + } + return nil +} + +// registerDefaultingWebhook registers a defaulting webhook if necessary. +func (blder *WebhookBuilder) registerDefaultingWebhook() { + mwh := blder.getDefaultingWebhook() + if mwh != nil { + mwh.LogConstructor = blder.logConstructor + path := generateMutatePath(blder.gvk) + + // Checking if the path is already registered. + // If so, just skip it. + if !blder.isAlreadyHandled(path) { + log.Info("Registering a mutating webhook", + "GVK", blder.gvk, + "path", path) + blder.mgr.GetWebhookServer().Register(path, mwh) + } + } +} + +func (blder *WebhookBuilder) getDefaultingWebhook() *admission.Webhook { + if defaulter := blder.customDefaulter; defaulter != nil { + return admission.WithCustomDefaulter(blder.mgr.GetScheme(), blder.apiType, defaulter).WithRecoverPanic(blder.recoverPanic) + } + if defaulter, ok := blder.apiType.(admission.Defaulter); ok { + return admission.DefaultingWebhookFor(blder.mgr.GetScheme(), defaulter).WithRecoverPanic(blder.recoverPanic) + } + log.Info( + "skip registering a mutating webhook, object does not implement admission.Defaulter or WithDefaulter wasn't called", + "GVK", blder.gvk) + return nil +} + +// registerValidatingWebhook registers a validating webhook if necessary. +func (blder *WebhookBuilder) registerValidatingWebhook() { + vwh := blder.getValidatingWebhook() + if vwh != nil { + vwh.LogConstructor = blder.logConstructor + path := generateValidatePath(blder.gvk) + + // Checking if the path is already registered. + // If so, just skip it. + if !blder.isAlreadyHandled(path) { + log.Info("Registering a validating webhook", + "GVK", blder.gvk, + "path", path) + blder.mgr.GetWebhookServer().Register(path, vwh) + } + } +} + +func (blder *WebhookBuilder) getValidatingWebhook() *admission.Webhook { + if validator := blder.customValidator; validator != nil { + return admission.WithCustomValidator(blder.mgr.GetScheme(), blder.apiType, validator).WithRecoverPanic(blder.recoverPanic) + } + if validator, ok := blder.apiType.(admission.Validator); ok { + return admission.ValidatingWebhookFor(blder.mgr.GetScheme(), validator).WithRecoverPanic(blder.recoverPanic) + } + log.Info( + "skip registering a validating webhook, object does not implement admission.Validator or WithValidator wasn't called", + "GVK", blder.gvk) + return nil +} + +func (blder *WebhookBuilder) registerConversionWebhook() error { + ok, err := conversion.IsConvertible(blder.mgr.GetScheme(), blder.apiType) + if err != nil { + log.Error(err, "conversion check failed", "GVK", blder.gvk) + return err + } + if ok { + if !blder.isAlreadyHandled("/convert") { + blder.mgr.GetWebhookServer().Register("/convert", conversion.NewWebhookHandler(blder.mgr.GetScheme())) + } + log.Info("Conversion webhook enabled", "GVK", blder.gvk) + } + + return nil +} + +func (blder *WebhookBuilder) getType() (runtime.Object, error) { + if blder.apiType != nil { + return blder.apiType, nil + } + return nil, errors.New("For() must be called with a valid object") +} + +func (blder *WebhookBuilder) isAlreadyHandled(path string) bool { + if blder.mgr.GetWebhookServer().WebhookMux() == nil { + return false + } + h, p := blder.mgr.GetWebhookServer().WebhookMux().Handler(&http.Request{URL: &url.URL{Path: path}}) + if p == path && h != nil { + return true + } + return false +} + +func generateMutatePath(gvk schema.GroupVersionKind) string { + return "/mutate-" + strings.ReplaceAll(gvk.Group, ".", "-") + "-" + + gvk.Version + "-" + strings.ToLower(gvk.Kind) +} + +func generateValidatePath(gvk schema.GroupVersionKind) string { + return "/validate-" + strings.ReplaceAll(gvk.Group, ".", "-") + "-" + + gvk.Version + "-" + strings.ToLower(gvk.Kind) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go new file mode 100644 index 00000000..1cecf88e --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go @@ -0,0 +1,517 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package cache + +import ( + "context" + "fmt" + "net/http" + "time" + + "golang.org/x/exp/maps" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + toolscache "k8s.io/client-go/tools/cache" + "k8s.io/utils/ptr" + + "sigs.k8s.io/controller-runtime/pkg/cache/internal" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var ( + log = logf.RuntimeLog.WithName("object-cache") + defaultSyncPeriod = 10 * time.Hour +) + +// InformerGetOptions defines the behavior of how informers are retrieved. +type InformerGetOptions internal.GetOptions + +// InformerGetOption defines an option that alters the behavior of how informers are retrieved. +type InformerGetOption func(*InformerGetOptions) + +// BlockUntilSynced determines whether a get request for an informer should block +// until the informer's cache has synced. +func BlockUntilSynced(shouldBlock bool) InformerGetOption { + return func(opts *InformerGetOptions) { + opts.BlockUntilSynced = &shouldBlock + } +} + +// Cache knows how to load Kubernetes objects, fetch informers to request +// to receive events for Kubernetes objects (at a low-level), +// and add indices to fields on the objects stored in the cache. +type Cache interface { + // Reader acts as a client to objects stored in the cache. + client.Reader + + // Informers loads informers and adds field indices. + Informers +} + +// Informers knows how to create or fetch informers for different +// group-version-kinds, and add indices to those informers. It's safe to call +// GetInformer from multiple threads. +type Informers interface { + // GetInformer fetches or constructs an informer for the given object that corresponds to a single + // API kind and resource. + GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) + + // GetInformerForKind is similar to GetInformer, except that it takes a group-version-kind, instead + // of the underlying object. + GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) + + // RemoveInformer removes an informer entry and stops it if it was running. + RemoveInformer(ctx context.Context, obj client.Object) error + + // Start runs all the informers known to this cache until the context is closed. + // It blocks. + Start(ctx context.Context) error + + // WaitForCacheSync waits for all the caches to sync. Returns false if it could not sync a cache. + WaitForCacheSync(ctx context.Context) bool + + // FieldIndexer adds indices to the managed informers. + client.FieldIndexer +} + +// Informer allows you to interact with the underlying informer. +type Informer interface { + // AddEventHandler adds an event handler to the shared informer using the shared informer's resync + // period. Events to a single handler are delivered sequentially, but there is no coordination + // between different handlers. + // It returns a registration handle for the handler that can be used to remove + // the handler again and an error if the handler cannot be added. + AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error) + + // AddEventHandlerWithResyncPeriod adds an event handler to the shared informer using the + // specified resync period. Events to a single handler are delivered sequentially, but there is + // no coordination between different handlers. + // It returns a registration handle for the handler that can be used to remove + // the handler again and an error if the handler cannot be added. + AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error) + + // RemoveEventHandler removes a previously added event handler given by + // its registration handle. + // This function is guaranteed to be idempotent and thread-safe. + RemoveEventHandler(handle toolscache.ResourceEventHandlerRegistration) error + + // AddIndexers adds indexers to this store. If this is called after there is already data + // in the store, the results are undefined. + AddIndexers(indexers toolscache.Indexers) error + + // HasSynced return true if the informers underlying store has synced. + HasSynced() bool + // IsStopped returns true if the informer has been stopped. + IsStopped() bool +} + +// AllNamespaces should be used as the map key to deliminate namespace settings +// that apply to all namespaces that themselves do not have explicit settings. +const AllNamespaces = metav1.NamespaceAll + +// Options are the optional arguments for creating a new Cache object. +type Options struct { + // HTTPClient is the http client to use for the REST client + HTTPClient *http.Client + + // Scheme is the scheme to use for mapping objects to GroupVersionKinds + Scheme *runtime.Scheme + + // Mapper is the RESTMapper to use for mapping GroupVersionKinds to Resources + Mapper meta.RESTMapper + + // SyncPeriod determines the minimum frequency at which watched resources are + // reconciled. A lower period will correct entropy more quickly, but reduce + // responsiveness to change if there are many watched resources. Change this + // value only if you know what you are doing. Defaults to 10 hours if unset. + // there will a 10 percent jitter between the SyncPeriod of all controllers + // so that all controllers will not send list requests simultaneously. + // + // This applies to all controllers. + // + // A period sync happens for two reasons: + // 1. To insure against a bug in the controller that causes an object to not + // be requeued, when it otherwise should be requeued. + // 2. To insure against an unknown bug in controller-runtime, or its dependencies, + // that causes an object to not be requeued, when it otherwise should be + // requeued, or to be removed from the queue, when it otherwise should not + // be removed. + // + // If you want + // 1. to insure against missed watch events, or + // 2. to poll services that cannot be watched, + // then we recommend that, instead of changing the default period, the + // controller requeue, with a constant duration `t`, whenever the controller + // is "done" with an object, and would otherwise not requeue it, i.e., we + // recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`, + // instead of `reconcile.Result{}`. + SyncPeriod *time.Duration + + // ReaderFailOnMissingInformer configures the cache to return a ErrResourceNotCached error when a user + // requests, using Get() and List(), a resource the cache does not already have an informer for. + // + // This error is distinct from an errors.NotFound. + // + // Defaults to false, which means that the cache will start a new informer + // for every new requested resource. + ReaderFailOnMissingInformer bool + + // DefaultNamespaces maps namespace names to cache configs. If set, only + // the namespaces in here will be watched and it will by used to default + // ByObject.Namespaces for all objects if that is nil. + // + // It is possible to have specific Config for just some namespaces + // but cache all namespaces by using the AllNamespaces const as the map key. + // This will then include all namespaces that do not have a more specific + // setting. + // + // The options in the Config that are nil will be defaulted from + // the respective Default* settings. + DefaultNamespaces map[string]Config + + // DefaultLabelSelector will be used as a label selector for all objects + // unless there is already one set in ByObject or DefaultNamespaces. + DefaultLabelSelector labels.Selector + + // DefaultFieldSelector will be used as a field selector for all object types + // unless there is already one set in ByObject or DefaultNamespaces. + DefaultFieldSelector fields.Selector + + // DefaultTransform will be used as transform for all object types + // unless there is already one set in ByObject or DefaultNamespaces. + DefaultTransform toolscache.TransformFunc + + // DefaultWatchErrorHandler will be used to the WatchErrorHandler which is called + // whenever ListAndWatch drops the connection with an error. + // + // After calling this handler, the informer will backoff and retry. + DefaultWatchErrorHandler toolscache.WatchErrorHandler + + // DefaultUnsafeDisableDeepCopy is the default for UnsafeDisableDeepCopy + // for everything that doesn't specify this. + // + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + // + // This will be used for all object types, unless it is set in ByObject or + // DefaultNamespaces. + DefaultUnsafeDisableDeepCopy *bool + + // ByObject restricts the cache's ListWatch to the desired fields per GVK at the specified object. + // object, this will fall through to Default* settings. + ByObject map[client.Object]ByObject + + // newInformer allows overriding of NewSharedIndexInformer for testing. + newInformer *func(toolscache.ListerWatcher, runtime.Object, time.Duration, toolscache.Indexers) toolscache.SharedIndexInformer +} + +// ByObject offers more fine-grained control over the cache's ListWatch by object. +type ByObject struct { + // Namespaces maps a namespace name to cache configs. If set, only the + // namespaces in this map will be cached. + // + // Settings in the map value that are unset will be defaulted. + // Use an empty value for the specific setting to prevent that. + // + // It is possible to have specific Config for just some namespaces + // but cache all namespaces by using the AllNamespaces const as the map key. + // This will then include all namespaces that do not have a more specific + // setting. + // + // A nil map allows to default this to the cache's DefaultNamespaces setting. + // An empty map prevents this and means that all namespaces will be cached. + // + // The defaulting follows the following precedence order: + // 1. ByObject + // 2. DefaultNamespaces[namespace] + // 3. Default* + // + // This must be unset for cluster-scoped objects. + Namespaces map[string]Config + + // Label represents a label selector for the object. + Label labels.Selector + + // Field represents a field selector for the object. + Field fields.Selector + + // Transform is a transformer function for the object which gets applied + // when objects of the transformation are about to be committed to the cache. + // + // This function is called both for new objects to enter the cache, + // and for updated objects. + Transform toolscache.TransformFunc + + // UnsafeDisableDeepCopy indicates not to deep copy objects during get or + // list objects per GVK at the specified object. + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + UnsafeDisableDeepCopy *bool +} + +// Config describes all potential options for a given watch. +type Config struct { + // LabelSelector specifies a label selector. A nil value allows to + // default this. + // + // Set to labels.Everything() if you don't want this defaulted. + LabelSelector labels.Selector + + // FieldSelector specifics a field selector. A nil value allows to + // default this. + // + // Set to fields.Everything() if you don't want this defaulted. + FieldSelector fields.Selector + + // Transform specifies a transform func. A nil value allows to default + // this. + // + // Set to an empty func to prevent this: + // func(in interface{}) (interface{}, error) { return in, nil } + Transform toolscache.TransformFunc + + // UnsafeDisableDeepCopy specifies if List and Get requests against the + // cache should not DeepCopy. A nil value allows to default this. + UnsafeDisableDeepCopy *bool +} + +// NewCacheFunc - Function for creating a new cache from the options and a rest config. +type NewCacheFunc func(config *rest.Config, opts Options) (Cache, error) + +// New initializes and returns a new Cache. +func New(cfg *rest.Config, opts Options) (Cache, error) { + opts, err := defaultOpts(cfg, opts) + if err != nil { + return nil, err + } + + newCacheFunc := newCache(cfg, opts) + + var defaultCache Cache + if len(opts.DefaultNamespaces) > 0 { + defaultConfig := optionDefaultsToConfig(&opts) + defaultCache = newMultiNamespaceCache(newCacheFunc, opts.Scheme, opts.Mapper, opts.DefaultNamespaces, &defaultConfig) + } else { + defaultCache = newCacheFunc(optionDefaultsToConfig(&opts), corev1.NamespaceAll) + } + + if len(opts.ByObject) == 0 { + return defaultCache, nil + } + + delegating := &delegatingByGVKCache{ + scheme: opts.Scheme, + caches: make(map[schema.GroupVersionKind]Cache, len(opts.ByObject)), + defaultCache: defaultCache, + } + + for obj, config := range opts.ByObject { + gvk, err := apiutil.GVKForObject(obj, opts.Scheme) + if err != nil { + return nil, fmt.Errorf("failed to get GVK for type %T: %w", obj, err) + } + var cache Cache + if len(config.Namespaces) > 0 { + cache = newMultiNamespaceCache(newCacheFunc, opts.Scheme, opts.Mapper, config.Namespaces, nil) + } else { + cache = newCacheFunc(byObjectToConfig(config), corev1.NamespaceAll) + } + delegating.caches[gvk] = cache + } + + return delegating, nil +} + +func optionDefaultsToConfig(opts *Options) Config { + return Config{ + LabelSelector: opts.DefaultLabelSelector, + FieldSelector: opts.DefaultFieldSelector, + Transform: opts.DefaultTransform, + UnsafeDisableDeepCopy: opts.DefaultUnsafeDisableDeepCopy, + } +} + +func byObjectToConfig(byObject ByObject) Config { + return Config{ + LabelSelector: byObject.Label, + FieldSelector: byObject.Field, + Transform: byObject.Transform, + UnsafeDisableDeepCopy: byObject.UnsafeDisableDeepCopy, + } +} + +type newCacheFunc func(config Config, namespace string) Cache + +func newCache(restConfig *rest.Config, opts Options) newCacheFunc { + return func(config Config, namespace string) Cache { + return &informerCache{ + scheme: opts.Scheme, + Informers: internal.NewInformers(restConfig, &internal.InformersOpts{ + HTTPClient: opts.HTTPClient, + Scheme: opts.Scheme, + Mapper: opts.Mapper, + ResyncPeriod: *opts.SyncPeriod, + Namespace: namespace, + Selector: internal.Selector{ + Label: config.LabelSelector, + Field: config.FieldSelector, + }, + Transform: config.Transform, + WatchErrorHandler: opts.DefaultWatchErrorHandler, + UnsafeDisableDeepCopy: ptr.Deref(config.UnsafeDisableDeepCopy, false), + NewInformer: opts.newInformer, + }), + readerFailOnMissingInformer: opts.ReaderFailOnMissingInformer, + } + } +} + +func defaultOpts(config *rest.Config, opts Options) (Options, error) { + config = rest.CopyConfig(config) + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + // Use the rest HTTP client for the provided config if unset + if opts.HTTPClient == nil { + var err error + opts.HTTPClient, err = rest.HTTPClientFor(config) + if err != nil { + return Options{}, fmt.Errorf("could not create HTTP client from config: %w", err) + } + } + + // Use the default Kubernetes Scheme if unset + if opts.Scheme == nil { + opts.Scheme = scheme.Scheme + } + + // Construct a new Mapper if unset + if opts.Mapper == nil { + var err error + opts.Mapper, err = apiutil.NewDynamicRESTMapper(config, opts.HTTPClient) + if err != nil { + return Options{}, fmt.Errorf("could not create RESTMapper from config: %w", err) + } + } + + for namespace, cfg := range opts.DefaultNamespaces { + cfg = defaultConfig(cfg, optionDefaultsToConfig(&opts)) + if namespace == metav1.NamespaceAll { + cfg.FieldSelector = fields.AndSelectors(appendIfNotNil(namespaceAllSelector(maps.Keys(opts.DefaultNamespaces)), cfg.FieldSelector)...) + } + opts.DefaultNamespaces[namespace] = cfg + } + + for obj, byObject := range opts.ByObject { + isNamespaced, err := apiutil.IsObjectNamespaced(obj, opts.Scheme, opts.Mapper) + if err != nil { + return opts, fmt.Errorf("failed to determine if %T is namespaced: %w", obj, err) + } + if !isNamespaced && byObject.Namespaces != nil { + return opts, fmt.Errorf("type %T is not namespaced, but its ByObject.Namespaces setting is not nil", obj) + } + + // Default the namespace-level configs first, because they need to use the undefaulted type-level config. + for namespace, config := range byObject.Namespaces { + // 1. Default from the undefaulted type-level config + config = defaultConfig(config, byObjectToConfig(byObject)) + + // 2. Default from the namespace-level config. This was defaulted from the global default config earlier, but + // might not have an entry for the current namespace. + if defaultNamespaceSettings, hasDefaultNamespace := opts.DefaultNamespaces[namespace]; hasDefaultNamespace { + config = defaultConfig(config, defaultNamespaceSettings) + } + + // 3. Default from the global defaults + config = defaultConfig(config, optionDefaultsToConfig(&opts)) + + if namespace == metav1.NamespaceAll { + config.FieldSelector = fields.AndSelectors( + appendIfNotNil( + namespaceAllSelector(maps.Keys(byObject.Namespaces)), + config.FieldSelector, + )..., + ) + } + + byObject.Namespaces[namespace] = config + } + + defaultedConfig := defaultConfig(byObjectToConfig(byObject), optionDefaultsToConfig(&opts)) + byObject.Label = defaultedConfig.LabelSelector + byObject.Field = defaultedConfig.FieldSelector + byObject.Transform = defaultedConfig.Transform + byObject.UnsafeDisableDeepCopy = defaultedConfig.UnsafeDisableDeepCopy + + if isNamespaced && byObject.Namespaces == nil { + byObject.Namespaces = opts.DefaultNamespaces + } + + opts.ByObject[obj] = byObject + } + + // Default the resync period to 10 hours if unset + if opts.SyncPeriod == nil { + opts.SyncPeriod = &defaultSyncPeriod + } + return opts, nil +} + +func defaultConfig(toDefault, defaultFrom Config) Config { + if toDefault.LabelSelector == nil { + toDefault.LabelSelector = defaultFrom.LabelSelector + } + if toDefault.FieldSelector == nil { + toDefault.FieldSelector = defaultFrom.FieldSelector + } + if toDefault.Transform == nil { + toDefault.Transform = defaultFrom.Transform + } + if toDefault.UnsafeDisableDeepCopy == nil { + toDefault.UnsafeDisableDeepCopy = defaultFrom.UnsafeDisableDeepCopy + } + + return toDefault +} + +func namespaceAllSelector(namespaces []string) fields.Selector { + selectors := make([]fields.Selector, 0, len(namespaces)-1) + for _, namespace := range namespaces { + if namespace != metav1.NamespaceAll { + selectors = append(selectors, fields.OneTermNotEqualSelector("metadata.namespace", namespace)) + } + } + + return fields.AndSelectors(selectors...) +} + +func appendIfNotNil[T comparable](a, b T) []T { + if b != *new(T) { + return []T{a, b} + } + return []T{a} +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go new file mode 100644 index 00000000..4db8208a --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/delegating_by_gvk_cache.go @@ -0,0 +1,135 @@ +/* +Copyright 2023 The Kubernetes Authors. + +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. +*/ + +package cache + +import ( + "context" + "strings" + "sync" + + "golang.org/x/exp/maps" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// delegatingByGVKCache delegates to a type-specific cache if present +// and uses the defaultCache otherwise. +type delegatingByGVKCache struct { + scheme *runtime.Scheme + caches map[schema.GroupVersionKind]Cache + defaultCache Cache +} + +func (dbt *delegatingByGVKCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + cache, err := dbt.cacheForObject(obj) + if err != nil { + return err + } + return cache.Get(ctx, key, obj, opts...) +} + +func (dbt *delegatingByGVKCache) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + cache, err := dbt.cacheForObject(list) + if err != nil { + return err + } + return cache.List(ctx, list, opts...) +} + +func (dbt *delegatingByGVKCache) RemoveInformer(ctx context.Context, obj client.Object) error { + cache, err := dbt.cacheForObject(obj) + if err != nil { + return err + } + return cache.RemoveInformer(ctx, obj) +} + +func (dbt *delegatingByGVKCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) { + cache, err := dbt.cacheForObject(obj) + if err != nil { + return nil, err + } + return cache.GetInformer(ctx, obj, opts...) +} + +func (dbt *delegatingByGVKCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) { + return dbt.cacheForGVK(gvk).GetInformerForKind(ctx, gvk, opts...) +} + +func (dbt *delegatingByGVKCache) Start(ctx context.Context) error { + allCaches := maps.Values(dbt.caches) + allCaches = append(allCaches, dbt.defaultCache) + + wg := &sync.WaitGroup{} + errs := make(chan error) + for idx := range allCaches { + cache := allCaches[idx] + wg.Add(1) + go func() { + defer wg.Done() + if err := cache.Start(ctx); err != nil { + errs <- err + } + }() + } + + select { + case err := <-errs: + return err + case <-ctx.Done(): + wg.Wait() + return nil + } +} + +func (dbt *delegatingByGVKCache) WaitForCacheSync(ctx context.Context) bool { + synced := true + for _, cache := range append(maps.Values(dbt.caches), dbt.defaultCache) { + if !cache.WaitForCacheSync(ctx) { + synced = false + } + } + + return synced +} + +func (dbt *delegatingByGVKCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { + cache, err := dbt.cacheForObject(obj) + if err != nil { + return err + } + return cache.IndexField(ctx, obj, field, extractValue) +} + +func (dbt *delegatingByGVKCache) cacheForObject(o runtime.Object) (Cache, error) { + gvk, err := apiutil.GVKForObject(o, dbt.scheme) + if err != nil { + return nil, err + } + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + return dbt.cacheForGVK(gvk), nil +} + +func (dbt *delegatingByGVKCache) cacheForGVK(gvk schema.GroupVersionKind) Cache { + if specific, hasSpecific := dbt.caches[gvk]; hasSpecific { + return specific + } + + return dbt.defaultCache +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/doc.go new file mode 100644 index 00000000..e1742ac0 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package cache provides object caches that act as caching client.Reader +// instances and help drive Kubernetes-object-based event handlers. +package cache diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go new file mode 100644 index 00000000..091667b7 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go @@ -0,0 +1,260 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package cache + +import ( + "context" + "fmt" + "strings" + + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/controller-runtime/pkg/cache/internal" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +var ( + _ Informers = &informerCache{} + _ client.Reader = &informerCache{} + _ Cache = &informerCache{} +) + +// ErrCacheNotStarted is returned when trying to read from the cache that wasn't started. +type ErrCacheNotStarted struct{} + +func (*ErrCacheNotStarted) Error() string { + return "the cache is not started, can not read objects" +} + +var _ error = (*ErrCacheNotStarted)(nil) + +// ErrResourceNotCached indicates that the resource type +// the client asked the cache for is not cached, i.e. the +// corresponding informer does not exist yet. +type ErrResourceNotCached struct { + GVK schema.GroupVersionKind +} + +// Error returns the error +func (r ErrResourceNotCached) Error() string { + return fmt.Sprintf("%s is not cached", r.GVK.String()) +} + +var _ error = (*ErrResourceNotCached)(nil) + +// informerCache is a Kubernetes Object cache populated from internal.Informers. +// informerCache wraps internal.Informers. +type informerCache struct { + scheme *runtime.Scheme + *internal.Informers + readerFailOnMissingInformer bool +} + +// Get implements Reader. +func (ic *informerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error { + gvk, err := apiutil.GVKForObject(out, ic.scheme) + if err != nil { + return err + } + + started, cache, err := ic.getInformerForKind(ctx, gvk, out) + if err != nil { + return err + } + + if !started { + return &ErrCacheNotStarted{} + } + return cache.Reader.Get(ctx, key, out, opts...) +} + +// List implements Reader. +func (ic *informerCache) List(ctx context.Context, out client.ObjectList, opts ...client.ListOption) error { + gvk, cacheTypeObj, err := ic.objectTypeForListObject(out) + if err != nil { + return err + } + + started, cache, err := ic.getInformerForKind(ctx, *gvk, cacheTypeObj) + if err != nil { + return err + } + + if !started { + return &ErrCacheNotStarted{} + } + + return cache.Reader.List(ctx, out, opts...) +} + +// objectTypeForListObject tries to find the runtime.Object and associated GVK +// for a single object corresponding to the passed-in list type. We need them +// because they are used as cache map key. +func (ic *informerCache) objectTypeForListObject(list client.ObjectList) (*schema.GroupVersionKind, runtime.Object, error) { + gvk, err := apiutil.GVKForObject(list, ic.scheme) + if err != nil { + return nil, nil, err + } + + // We need the non-list GVK, so chop off the "List" from the end of the kind. + gvk.Kind = strings.TrimSuffix(gvk.Kind, "List") + + // Handle unstructured.UnstructuredList. + if _, isUnstructured := list.(runtime.Unstructured); isUnstructured { + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(gvk) + return &gvk, u, nil + } + // Handle metav1.PartialObjectMetadataList. + if _, isPartialObjectMetadata := list.(*metav1.PartialObjectMetadataList); isPartialObjectMetadata { + pom := &metav1.PartialObjectMetadata{} + pom.SetGroupVersionKind(gvk) + return &gvk, pom, nil + } + + // Any other list type should have a corresponding non-list type registered + // in the scheme. Use that to create a new instance of the non-list type. + cacheTypeObj, err := ic.scheme.New(gvk) + if err != nil { + return nil, nil, err + } + return &gvk, cacheTypeObj, nil +} + +func applyGetOptions(opts ...InformerGetOption) *internal.GetOptions { + cfg := &InformerGetOptions{} + for _, opt := range opts { + opt(cfg) + } + return (*internal.GetOptions)(cfg) +} + +// GetInformerForKind returns the informer for the GroupVersionKind. If no informer exists, one will be started. +func (ic *informerCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) { + // Map the gvk to an object + obj, err := ic.scheme.New(gvk) + if err != nil { + return nil, err + } + + _, i, err := ic.Informers.Get(ctx, gvk, obj, applyGetOptions(opts...)) + if err != nil { + return nil, err + } + return i.Informer, nil +} + +// GetInformer returns the informer for the obj. If no informer exists, one will be started. +func (ic *informerCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) { + gvk, err := apiutil.GVKForObject(obj, ic.scheme) + if err != nil { + return nil, err + } + + _, i, err := ic.Informers.Get(ctx, gvk, obj, applyGetOptions(opts...)) + if err != nil { + return nil, err + } + return i.Informer, nil +} + +func (ic *informerCache) getInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object) (bool, *internal.Cache, error) { + if ic.readerFailOnMissingInformer { + cache, started, ok := ic.Informers.Peek(gvk, obj) + if !ok { + return false, nil, &ErrResourceNotCached{GVK: gvk} + } + return started, cache, nil + } + + return ic.Informers.Get(ctx, gvk, obj, &internal.GetOptions{}) +} + +// RemoveInformer deactivates and removes the informer from the cache. +func (ic *informerCache) RemoveInformer(_ context.Context, obj client.Object) error { + gvk, err := apiutil.GVKForObject(obj, ic.scheme) + if err != nil { + return err + } + + ic.Informers.Remove(gvk, obj) + return nil +} + +// NeedLeaderElection implements the LeaderElectionRunnable interface +// to indicate that this can be started without requiring the leader lock. +func (ic *informerCache) NeedLeaderElection() bool { + return false +} + +// IndexField adds an indexer to the underlying informer, using extractValue function to get +// value(s) from the given field. This index can then be used by passing a field selector +// to List. For one-to-one compatibility with "normal" field selectors, only return one value. +// The values may be anything. They will automatically be prefixed with the namespace of the +// given object, if present. The objects passed are guaranteed to be objects of the correct type. +func (ic *informerCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { + informer, err := ic.GetInformer(ctx, obj) + if err != nil { + return err + } + return indexByField(informer, field, extractValue) +} + +func indexByField(informer Informer, field string, extractValue client.IndexerFunc) error { + indexFunc := func(objRaw interface{}) ([]string, error) { + // TODO(directxman12): check if this is the correct type? + obj, isObj := objRaw.(client.Object) + if !isObj { + return nil, fmt.Errorf("object of type %T is not an Object", objRaw) + } + meta, err := apimeta.Accessor(obj) + if err != nil { + return nil, err + } + ns := meta.GetNamespace() + + rawVals := extractValue(obj) + var vals []string + if ns == "" { + // if we're not doubling the keys for the namespaced case, just create a new slice with same length + vals = make([]string, len(rawVals)) + } else { + // if we need to add non-namespaced versions too, double the length + vals = make([]string, len(rawVals)*2) + } + for i, rawVal := range rawVals { + // save a namespaced variant, so that we can ask + // "what are all the object matching a given index *in a given namespace*" + vals[i] = internal.KeyToNamespacedKey(ns, rawVal) + if ns != "" { + // if we have a namespace, also inject a special index key for listing + // regardless of the object namespace + vals[i+len(rawVals)] = internal.KeyToNamespacedKey("", rawVal) + } + } + + return vals, nil + } + + return informer.AddIndexers(cache.Indexers{internal.FieldIndexName(field): indexFunc}) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go new file mode 100644 index 00000000..2e4f5ce5 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go @@ -0,0 +1,255 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package internal + +import ( + "context" + "fmt" + "reflect" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + apimeta "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/internal/field/selector" +) + +// CacheReader is a client.Reader. +var _ client.Reader = &CacheReader{} + +// CacheReader wraps a cache.Index to implement the client.CacheReader interface for a single type. +type CacheReader struct { + // indexer is the underlying indexer wrapped by this cache. + indexer cache.Indexer + + // groupVersionKind is the group-version-kind of the resource. + groupVersionKind schema.GroupVersionKind + + // scopeName is the scope of the resource (namespaced or cluster-scoped). + scopeName apimeta.RESTScopeName + + // disableDeepCopy indicates not to deep copy objects during get or list objects. + // Be very careful with this, when enabled you must DeepCopy any object before mutating it, + // otherwise you will mutate the object in the cache. + disableDeepCopy bool +} + +// Get checks the indexer for the object and writes a copy of it if found. +func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object, _ ...client.GetOption) error { + if c.scopeName == apimeta.RESTScopeNameRoot { + key.Namespace = "" + } + storeKey := objectKeyToStoreKey(key) + + // Lookup the object from the indexer cache + obj, exists, err := c.indexer.GetByKey(storeKey) + if err != nil { + return err + } + + // Not found, return an error + if !exists { + return apierrors.NewNotFound(schema.GroupResource{ + Group: c.groupVersionKind.Group, + // Resource gets set as Kind in the error so this is fine + Resource: c.groupVersionKind.Kind, + }, key.Name) + } + + // Verify the result is a runtime.Object + if _, isObj := obj.(runtime.Object); !isObj { + // This should never happen + return fmt.Errorf("cache contained %T, which is not an Object", obj) + } + + if c.disableDeepCopy { + // skip deep copy which might be unsafe + // you must DeepCopy any object before mutating it outside + } else { + // deep copy to avoid mutating cache + obj = obj.(runtime.Object).DeepCopyObject() + } + + // Copy the value of the item in the cache to the returned value + // TODO(directxman12): this is a terrible hack, pls fix (we should have deepcopyinto) + outVal := reflect.ValueOf(out) + objVal := reflect.ValueOf(obj) + if !objVal.Type().AssignableTo(outVal.Type()) { + return fmt.Errorf("cache had type %s, but %s was asked for", objVal.Type(), outVal.Type()) + } + reflect.Indirect(outVal).Set(reflect.Indirect(objVal)) + if !c.disableDeepCopy { + out.GetObjectKind().SetGroupVersionKind(c.groupVersionKind) + } + + return nil +} + +// List lists items out of the indexer and writes them to out. +func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...client.ListOption) error { + var objs []interface{} + var err error + + listOpts := client.ListOptions{} + listOpts.ApplyOptions(opts) + + if listOpts.Continue != "" { + return fmt.Errorf("continue list option is not supported by the cache") + } + + switch { + case listOpts.FieldSelector != nil: + requiresExact := selector.RequiresExactMatch(listOpts.FieldSelector) + if !requiresExact { + return fmt.Errorf("non-exact field matches are not supported by the cache") + } + // list all objects by the field selector. If this is namespaced and we have one, ask for the + // namespaced index key. Otherwise, ask for the non-namespaced variant by using the fake "all namespaces" + // namespace. + objs, err = byIndexes(c.indexer, listOpts.FieldSelector.Requirements(), listOpts.Namespace) + case listOpts.Namespace != "": + objs, err = c.indexer.ByIndex(cache.NamespaceIndex, listOpts.Namespace) + default: + objs = c.indexer.List() + } + if err != nil { + return err + } + var labelSel labels.Selector + if listOpts.LabelSelector != nil { + labelSel = listOpts.LabelSelector + } + + limitSet := listOpts.Limit > 0 + + runtimeObjs := make([]runtime.Object, 0, len(objs)) + for _, item := range objs { + // if the Limit option is set and the number of items + // listed exceeds this limit, then stop reading. + if limitSet && int64(len(runtimeObjs)) >= listOpts.Limit { + break + } + obj, isObj := item.(runtime.Object) + if !isObj { + return fmt.Errorf("cache contained %T, which is not an Object", item) + } + meta, err := apimeta.Accessor(obj) + if err != nil { + return err + } + if labelSel != nil { + lbls := labels.Set(meta.GetLabels()) + if !labelSel.Matches(lbls) { + continue + } + } + + var outObj runtime.Object + if c.disableDeepCopy || (listOpts.UnsafeDisableDeepCopy != nil && *listOpts.UnsafeDisableDeepCopy) { + // skip deep copy which might be unsafe + // you must DeepCopy any object before mutating it outside + outObj = obj + } else { + outObj = obj.DeepCopyObject() + outObj.GetObjectKind().SetGroupVersionKind(c.groupVersionKind) + } + runtimeObjs = append(runtimeObjs, outObj) + } + return apimeta.SetList(out, runtimeObjs) +} + +func byIndexes(indexer cache.Indexer, requires fields.Requirements, namespace string) ([]interface{}, error) { + var ( + err error + objs []interface{} + vals []string + ) + indexers := indexer.GetIndexers() + for idx, req := range requires { + indexName := FieldIndexName(req.Field) + indexedValue := KeyToNamespacedKey(namespace, req.Value) + if idx == 0 { + // we use first require to get snapshot data + // TODO(halfcrazy): use complicated index when client-go provides byIndexes + // https://github.com/kubernetes/kubernetes/issues/109329 + objs, err = indexer.ByIndex(indexName, indexedValue) + if err != nil { + return nil, err + } + if len(objs) == 0 { + return nil, nil + } + continue + } + fn, exist := indexers[indexName] + if !exist { + return nil, fmt.Errorf("index with name %s does not exist", indexName) + } + filteredObjects := make([]interface{}, 0, len(objs)) + for _, obj := range objs { + vals, err = fn(obj) + if err != nil { + return nil, err + } + for _, val := range vals { + if val == indexedValue { + filteredObjects = append(filteredObjects, obj) + break + } + } + } + if len(filteredObjects) == 0 { + return nil, nil + } + objs = filteredObjects + } + return objs, nil +} + +// objectKeyToStorageKey converts an object key to store key. +// It's akin to MetaNamespaceKeyFunc. It's separate from +// String to allow keeping the key format easily in sync with +// MetaNamespaceKeyFunc. +func objectKeyToStoreKey(k client.ObjectKey) string { + if k.Namespace == "" { + return k.Name + } + return k.Namespace + "/" + k.Name +} + +// FieldIndexName constructs the name of the index over the given field, +// for use with an indexer. +func FieldIndexName(field string) string { + return "field:" + field +} + +// allNamespacesNamespace is used as the "namespace" when we want to list across all namespaces. +const allNamespacesNamespace = "__all_namespaces" + +// KeyToNamespacedKey prefixes the given index key with a namespace +// for use in field selector indexes. +func KeyToNamespacedKey(ns string, baseKey string) string { + if ns != "" { + return ns + "/" + baseKey + } + return allNamespacesNamespace + "/" + baseKey +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go new file mode 100644 index 00000000..c270e809 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/informers.go @@ -0,0 +1,587 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package internal + +import ( + "context" + "fmt" + "math/rand" + "net/http" + "sync" + "time" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/metadata" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/internal/syncs" +) + +// InformersOpts configures an InformerMap. +type InformersOpts struct { + HTTPClient *http.Client + Scheme *runtime.Scheme + Mapper meta.RESTMapper + ResyncPeriod time.Duration + Namespace string + NewInformer *func(cache.ListerWatcher, runtime.Object, time.Duration, cache.Indexers) cache.SharedIndexInformer + Selector Selector + Transform cache.TransformFunc + UnsafeDisableDeepCopy bool + WatchErrorHandler cache.WatchErrorHandler +} + +// NewInformers creates a new InformersMap that can create informers under the hood. +func NewInformers(config *rest.Config, options *InformersOpts) *Informers { + newInformer := cache.NewSharedIndexInformer + if options.NewInformer != nil { + newInformer = *options.NewInformer + } + return &Informers{ + config: config, + httpClient: options.HTTPClient, + scheme: options.Scheme, + mapper: options.Mapper, + tracker: tracker{ + Structured: make(map[schema.GroupVersionKind]*Cache), + Unstructured: make(map[schema.GroupVersionKind]*Cache), + Metadata: make(map[schema.GroupVersionKind]*Cache), + }, + codecs: serializer.NewCodecFactory(options.Scheme), + paramCodec: runtime.NewParameterCodec(options.Scheme), + resync: options.ResyncPeriod, + startWait: make(chan struct{}), + namespace: options.Namespace, + selector: options.Selector, + transform: options.Transform, + unsafeDisableDeepCopy: options.UnsafeDisableDeepCopy, + newInformer: newInformer, + watchErrorHandler: options.WatchErrorHandler, + } +} + +// Cache contains the cached data for an Cache. +type Cache struct { + // Informer is the cached informer + Informer cache.SharedIndexInformer + + // CacheReader wraps Informer and implements the CacheReader interface for a single type + Reader CacheReader + + // Stop can be used to stop this individual informer. + stop chan struct{} +} + +// Start starts the informer managed by a MapEntry. +// Blocks until the informer stops. The informer can be stopped +// either individually (via the entry's stop channel) or globally +// via the provided stop argument. +func (c *Cache) Start(stop <-chan struct{}) { + // Stop on either the whole map stopping or just this informer being removed. + internalStop, cancel := syncs.MergeChans(stop, c.stop) + defer cancel() + c.Informer.Run(internalStop) +} + +type tracker struct { + Structured map[schema.GroupVersionKind]*Cache + Unstructured map[schema.GroupVersionKind]*Cache + Metadata map[schema.GroupVersionKind]*Cache +} + +// GetOptions provides configuration to customize the behavior when +// getting an informer. +type GetOptions struct { + // BlockUntilSynced controls if the informer retrieval will block until the informer is synced. Defaults to `true`. + BlockUntilSynced *bool +} + +// Informers create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs. +// It uses a standard parameter codec constructed based on the given generated Scheme. +type Informers struct { + // httpClient is used to create a new REST client + httpClient *http.Client + + // scheme maps runtime.Objects to GroupVersionKinds + scheme *runtime.Scheme + + // config is used to talk to the apiserver + config *rest.Config + + // mapper maps GroupVersionKinds to Resources + mapper meta.RESTMapper + + // tracker tracks informers keyed by their type and groupVersionKind + tracker tracker + + // codecs is used to create a new REST client + codecs serializer.CodecFactory + + // paramCodec is used by list and watch + paramCodec runtime.ParameterCodec + + // resync is the base frequency the informers are resynced + // a 10 percent jitter will be added to the resync period between informers + // so that all informers will not send list requests simultaneously. + resync time.Duration + + // mu guards access to the map + mu sync.RWMutex + + // started is true if the informers have been started + started bool + + // startWait is a channel that is closed after the + // informer has been started. + startWait chan struct{} + + // waitGroup is the wait group that is used to wait for all informers to stop + waitGroup sync.WaitGroup + + // stopped is true if the informers have been stopped + stopped bool + + // ctx is the context to stop informers + ctx context.Context + + // namespace is the namespace that all ListWatches are restricted to + // default or empty string means all namespaces + namespace string + + selector Selector + transform cache.TransformFunc + unsafeDisableDeepCopy bool + + // NewInformer allows overriding of the shared index informer constructor for testing. + newInformer func(cache.ListerWatcher, runtime.Object, time.Duration, cache.Indexers) cache.SharedIndexInformer + + // WatchErrorHandler allows the shared index informer's + // watchErrorHandler to be set by overriding the options + // or to use the default watchErrorHandler + watchErrorHandler cache.WatchErrorHandler +} + +// Start calls Run on each of the informers and sets started to true. Blocks on the context. +// It doesn't return start because it can't return an error, and it's not a runnable directly. +func (ip *Informers) Start(ctx context.Context) error { + func() { + ip.mu.Lock() + defer ip.mu.Unlock() + + // Set the context so it can be passed to informers that are added later + ip.ctx = ctx + + // Start each informer + for _, i := range ip.tracker.Structured { + ip.startInformerLocked(i) + } + for _, i := range ip.tracker.Unstructured { + ip.startInformerLocked(i) + } + for _, i := range ip.tracker.Metadata { + ip.startInformerLocked(i) + } + + // Set started to true so we immediately start any informers added later. + ip.started = true + close(ip.startWait) + }() + <-ctx.Done() // Block until the context is done + ip.mu.Lock() + ip.stopped = true // Set stopped to true so we don't start any new informers + ip.mu.Unlock() + ip.waitGroup.Wait() // Block until all informers have stopped + return nil +} + +func (ip *Informers) startInformerLocked(cacheEntry *Cache) { + // Don't start the informer in case we are already waiting for the items in + // the waitGroup to finish, since waitGroups don't support waiting and adding + // at the same time. + if ip.stopped { + return + } + + ip.waitGroup.Add(1) + go func() { + defer ip.waitGroup.Done() + cacheEntry.Start(ip.ctx.Done()) + }() +} + +func (ip *Informers) waitForStarted(ctx context.Context) bool { + select { + case <-ip.startWait: + return true + case <-ctx.Done(): + return false + } +} + +// getHasSyncedFuncs returns all the HasSynced functions for the informers in this map. +func (ip *Informers) getHasSyncedFuncs() []cache.InformerSynced { + ip.mu.RLock() + defer ip.mu.RUnlock() + + res := make([]cache.InformerSynced, 0, + len(ip.tracker.Structured)+len(ip.tracker.Unstructured)+len(ip.tracker.Metadata), + ) + for _, i := range ip.tracker.Structured { + res = append(res, i.Informer.HasSynced) + } + for _, i := range ip.tracker.Unstructured { + res = append(res, i.Informer.HasSynced) + } + for _, i := range ip.tracker.Metadata { + res = append(res, i.Informer.HasSynced) + } + return res +} + +// WaitForCacheSync waits until all the caches have been started and synced. +func (ip *Informers) WaitForCacheSync(ctx context.Context) bool { + if !ip.waitForStarted(ctx) { + return false + } + return cache.WaitForCacheSync(ctx.Done(), ip.getHasSyncedFuncs()...) +} + +// Peek attempts to get the informer for the GVK, but does not start one if one does not exist. +func (ip *Informers) Peek(gvk schema.GroupVersionKind, obj runtime.Object) (res *Cache, started bool, ok bool) { + ip.mu.RLock() + defer ip.mu.RUnlock() + i, ok := ip.informersByType(obj)[gvk] + return i, ip.started, ok +} + +// Get will create a new Informer and add it to the map of specificInformersMap if none exists. Returns +// the Informer from the map. +func (ip *Informers) Get(ctx context.Context, gvk schema.GroupVersionKind, obj runtime.Object, opts *GetOptions) (bool, *Cache, error) { + // Return the informer if it is found + i, started, ok := ip.Peek(gvk, obj) + if !ok { + var err error + if i, started, err = ip.addInformerToMap(gvk, obj); err != nil { + return started, nil, err + } + } + + shouldBlock := true + if opts.BlockUntilSynced != nil { + shouldBlock = *opts.BlockUntilSynced + } + + if shouldBlock && started && !i.Informer.HasSynced() { + // Wait for it to sync before returning the Informer so that folks don't read from a stale cache. + if !cache.WaitForCacheSync(ctx.Done(), i.Informer.HasSynced) { + return started, nil, apierrors.NewTimeoutError(fmt.Sprintf("failed waiting for %T Informer to sync", obj), 0) + } + } + + return started, i, nil +} + +// Remove removes an informer entry and stops it if it was running. +func (ip *Informers) Remove(gvk schema.GroupVersionKind, obj runtime.Object) { + ip.mu.Lock() + defer ip.mu.Unlock() + + informerMap := ip.informersByType(obj) + + entry, ok := informerMap[gvk] + if !ok { + return + } + close(entry.stop) + delete(informerMap, gvk) +} + +func (ip *Informers) informersByType(obj runtime.Object) map[schema.GroupVersionKind]*Cache { + switch obj.(type) { + case runtime.Unstructured: + return ip.tracker.Unstructured + case *metav1.PartialObjectMetadata, *metav1.PartialObjectMetadataList: + return ip.tracker.Metadata + default: + return ip.tracker.Structured + } +} + +// addInformerToMap either returns an existing informer or creates a new informer, adds it to the map and returns it. +func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.Object) (*Cache, bool, error) { + ip.mu.Lock() + defer ip.mu.Unlock() + + // Check the cache to see if we already have an Informer. If we do, return the Informer. + // This is for the case where 2 routines tried to get the informer when it wasn't in the map + // so neither returned early, but the first one created it. + if i, ok := ip.informersByType(obj)[gvk]; ok { + return i, ip.started, nil + } + + // Create a NewSharedIndexInformer and add it to the map. + listWatcher, err := ip.makeListWatcher(gvk, obj) + if err != nil { + return nil, false, err + } + sharedIndexInformer := ip.newInformer(&cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + ip.selector.ApplyToList(&opts) + return listWatcher.ListFunc(opts) + }, + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + ip.selector.ApplyToList(&opts) + opts.Watch = true // Watch needs to be set to true separately + return listWatcher.WatchFunc(opts) + }, + }, obj, calculateResyncPeriod(ip.resync), cache.Indexers{ + cache.NamespaceIndex: cache.MetaNamespaceIndexFunc, + }) + + // Set WatchErrorHandler on SharedIndexInformer if set + if ip.watchErrorHandler != nil { + if err := sharedIndexInformer.SetWatchErrorHandler(ip.watchErrorHandler); err != nil { + return nil, false, err + } + } + + // Check to see if there is a transformer for this gvk + if err := sharedIndexInformer.SetTransform(ip.transform); err != nil { + return nil, false, err + } + + mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, false, err + } + + // Create the new entry and set it in the map. + i := &Cache{ + Informer: sharedIndexInformer, + Reader: CacheReader{ + indexer: sharedIndexInformer.GetIndexer(), + groupVersionKind: gvk, + scopeName: mapping.Scope.Name(), + disableDeepCopy: ip.unsafeDisableDeepCopy, + }, + stop: make(chan struct{}), + } + ip.informersByType(obj)[gvk] = i + + // Start the informer in case the InformersMap has started, otherwise it will be + // started when the InformersMap starts. + if ip.started { + ip.startInformerLocked(i) + } + return i, ip.started, nil +} + +func (ip *Informers) makeListWatcher(gvk schema.GroupVersionKind, obj runtime.Object) (*cache.ListWatch, error) { + // Kubernetes APIs work against Resources, not GroupVersionKinds. Map the + // groupVersionKind to the Resource API we will use. + mapping, err := ip.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, err + } + + // Figure out if the GVK we're dealing with is global, or namespace scoped. + var namespace string + if mapping.Scope.Name() == meta.RESTScopeNameNamespace { + namespace = restrictNamespaceBySelector(ip.namespace, ip.selector) + } + + switch obj.(type) { + // + // Unstructured + // + case runtime.Unstructured: + // If the rest configuration has a negotiated serializer passed in, + // we should remove it and use the one that the dynamic client sets for us. + cfg := rest.CopyConfig(ip.config) + cfg.NegotiatedSerializer = nil + dynamicClient, err := dynamic.NewForConfigAndClient(cfg, ip.httpClient) + if err != nil { + return nil, err + } + resources := dynamicClient.Resource(mapping.Resource) + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + if namespace != "" { + return resources.Namespace(namespace).List(ip.ctx, opts) + } + return resources.List(ip.ctx, opts) + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + if namespace != "" { + return resources.Namespace(namespace).Watch(ip.ctx, opts) + } + return resources.Watch(ip.ctx, opts) + }, + }, nil + // + // Metadata + // + case *metav1.PartialObjectMetadata, *metav1.PartialObjectMetadataList: + // Always clear the negotiated serializer and use the one + // set from the metadata client. + cfg := rest.CopyConfig(ip.config) + cfg.NegotiatedSerializer = nil + + // Grab the metadata metadataClient. + metadataClient, err := metadata.NewForConfigAndClient(cfg, ip.httpClient) + if err != nil { + return nil, err + } + resources := metadataClient.Resource(mapping.Resource) + + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + var ( + list *metav1.PartialObjectMetadataList + err error + ) + if namespace != "" { + list, err = resources.Namespace(namespace).List(ip.ctx, opts) + } else { + list, err = resources.List(ip.ctx, opts) + } + if list != nil { + for i := range list.Items { + list.Items[i].SetGroupVersionKind(gvk) + } + } + return list, err + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watcher watch.Interface, err error) { + if namespace != "" { + watcher, err = resources.Namespace(namespace).Watch(ip.ctx, opts) + } else { + watcher, err = resources.Watch(ip.ctx, opts) + } + if err != nil { + return nil, err + } + return newGVKFixupWatcher(gvk, watcher), nil + }, + }, nil + // + // Structured. + // + default: + client, err := apiutil.RESTClientForGVK(gvk, false, ip.config, ip.codecs, ip.httpClient) + if err != nil { + return nil, err + } + listGVK := gvk.GroupVersion().WithKind(gvk.Kind + "List") + listObj, err := ip.scheme.New(listGVK) + if err != nil { + return nil, err + } + return &cache.ListWatch{ + ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { + // Build the request. + req := client.Get().Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec) + if namespace != "" { + req.Namespace(namespace) + } + + // Create the resulting object, and execute the request. + res := listObj.DeepCopyObject() + if err := req.Do(ip.ctx).Into(res); err != nil { + return nil, err + } + return res, nil + }, + // Setup the watch function + WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { + // Build the request. + req := client.Get().Resource(mapping.Resource.Resource).VersionedParams(&opts, ip.paramCodec) + if namespace != "" { + req.Namespace(namespace) + } + // Call the watch. + return req.Watch(ip.ctx) + }, + }, nil + } +} + +// newGVKFixupWatcher adds a wrapper that preserves the GVK information when +// events come in. +// +// This works around a bug where GVK information is not passed into mapping +// functions when using the OnlyMetadata option in the builder. +// This issue is most likely caused by kubernetes/kubernetes#80609. +// See kubernetes-sigs/controller-runtime#1484. +// +// This was originally implemented as a cache.ResourceEventHandler wrapper but +// that contained a data race which was resolved by setting the GVK in a watch +// wrapper, before the objects are written to the cache. +// See kubernetes-sigs/controller-runtime#1650. +// +// The original watch wrapper was found to be incompatible with +// k8s.io/client-go/tools/cache.Reflector so it has been re-implemented as a +// watch.Filter which is compatible. +// See kubernetes-sigs/controller-runtime#1789. +func newGVKFixupWatcher(gvk schema.GroupVersionKind, watcher watch.Interface) watch.Interface { + return watch.Filter( + watcher, + func(in watch.Event) (watch.Event, bool) { + in.Object.GetObjectKind().SetGroupVersionKind(gvk) + return in, true + }, + ) +} + +// calculateResyncPeriod returns a duration based on the desired input +// this is so that multiple controllers don't get into lock-step and all +// hammer the apiserver with list requests simultaneously. +func calculateResyncPeriod(resync time.Duration) time.Duration { + // the factor will fall into [0.9, 1.1) + factor := rand.Float64()/5.0 + 0.9 //nolint:gosec + return time.Duration(float64(resync.Nanoseconds()) * factor) +} + +// restrictNamespaceBySelector returns either a global restriction for all ListWatches +// if not default/empty, or the namespace that a ListWatch for the specific resource +// is restricted to, based on a specified field selector for metadata.namespace field. +func restrictNamespaceBySelector(namespaceOpt string, s Selector) string { + if namespaceOpt != "" { + // namespace is already restricted + return namespaceOpt + } + fieldSelector := s.Field + if fieldSelector == nil || fieldSelector.Empty() { + return "" + } + // check whether a selector includes the namespace field + value, found := fieldSelector.RequiresExactMatch("metadata.namespace") + if found { + return value + } + return "" +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go new file mode 100644 index 00000000..c674379b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/selector.go @@ -0,0 +1,39 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package internal + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" +) + +// Selector specify the label/field selector to fill in ListOptions. +type Selector struct { + Label labels.Selector + Field fields.Selector +} + +// ApplyToList fill in ListOptions LabelSelector and FieldSelector if needed. +func (s Selector) ApplyToList(listOpts *metav1.ListOptions) { + if s.Label != nil { + listOpts.LabelSelector = s.Label.String() + } + if s.Field != nil { + listOpts.FieldSelector = s.Field.String() + } +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go new file mode 100644 index 00000000..e38da145 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go @@ -0,0 +1,424 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package cache + +import ( + "context" + "fmt" + "time" + + corev1 "k8s.io/api/core/v1" + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + toolscache "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// a new global namespaced cache to handle cluster scoped resources. +const globalCache = "_cluster-scope" + +func newMultiNamespaceCache( + newCache newCacheFunc, + scheme *runtime.Scheme, + restMapper apimeta.RESTMapper, + namespaces map[string]Config, + globalConfig *Config, // may be nil in which case no cache for cluster-scoped objects will be created +) Cache { + // Create every namespace cache. + caches := map[string]Cache{} + for namespace, config := range namespaces { + caches[namespace] = newCache(config, namespace) + } + + // Create a cache for cluster scoped resources if requested + var clusterCache Cache + if globalConfig != nil { + clusterCache = newCache(*globalConfig, corev1.NamespaceAll) + } + + return &multiNamespaceCache{ + namespaceToCache: caches, + Scheme: scheme, + RESTMapper: restMapper, + clusterCache: clusterCache, + } +} + +// multiNamespaceCache knows how to handle multiple namespaced caches +// Use this feature when scoping permissions for your +// operator to a list of namespaces instead of watching every namespace +// in the cluster. +type multiNamespaceCache struct { + Scheme *runtime.Scheme + RESTMapper apimeta.RESTMapper + namespaceToCache map[string]Cache + clusterCache Cache +} + +var _ Cache = &multiNamespaceCache{} + +// Methods for multiNamespaceCache to conform to the Informers interface. + +func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object, opts ...InformerGetOption) (Informer, error) { + // If the object is cluster scoped, get the informer from clusterCache, + // if not use the namespaced caches. + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) + if err != nil { + return nil, err + } + if !isNamespaced { + clusterCacheInformer, err := c.clusterCache.GetInformer(ctx, obj, opts...) + if err != nil { + return nil, err + } + + return &multiNamespaceInformer{ + namespaceToInformer: map[string]Informer{ + globalCache: clusterCacheInformer, + }, + }, nil + } + + namespaceToInformer := map[string]Informer{} + for ns, cache := range c.namespaceToCache { + informer, err := cache.GetInformer(ctx, obj, opts...) + if err != nil { + return nil, err + } + namespaceToInformer[ns] = informer + } + + return &multiNamespaceInformer{namespaceToInformer: namespaceToInformer}, nil +} + +func (c *multiNamespaceCache) RemoveInformer(ctx context.Context, obj client.Object) error { + // If the object is clusterscoped, get the informer from clusterCache, + // if not use the namespaced caches. + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) + if err != nil { + return err + } + if !isNamespaced { + return c.clusterCache.RemoveInformer(ctx, obj) + } + + for _, cache := range c.namespaceToCache { + err := cache.RemoveInformer(ctx, obj) + if err != nil { + return err + } + } + + return nil +} + +func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema.GroupVersionKind, opts ...InformerGetOption) (Informer, error) { + // If the object is cluster scoped, get the informer from clusterCache, + // if not use the namespaced caches. + isNamespaced, err := apiutil.IsGVKNamespaced(gvk, c.RESTMapper) + if err != nil { + return nil, err + } + if !isNamespaced { + clusterCacheInformer, err := c.clusterCache.GetInformerForKind(ctx, gvk, opts...) + if err != nil { + return nil, err + } + + return &multiNamespaceInformer{ + namespaceToInformer: map[string]Informer{ + globalCache: clusterCacheInformer, + }, + }, nil + } + + namespaceToInformer := map[string]Informer{} + for ns, cache := range c.namespaceToCache { + informer, err := cache.GetInformerForKind(ctx, gvk, opts...) + if err != nil { + return nil, err + } + namespaceToInformer[ns] = informer + } + + return &multiNamespaceInformer{namespaceToInformer: namespaceToInformer}, nil +} + +func (c *multiNamespaceCache) Start(ctx context.Context) error { + // start global cache + if c.clusterCache != nil { + go func() { + err := c.clusterCache.Start(ctx) + if err != nil { + log.Error(err, "cluster scoped cache failed to start") + } + }() + } + + // start namespaced caches + for ns, cache := range c.namespaceToCache { + go func(ns string, cache Cache) { + if err := cache.Start(ctx); err != nil { + log.Error(err, "multi-namespace cache failed to start namespaced informer", "namespace", ns) + } + }(ns, cache) + } + + <-ctx.Done() + return nil +} + +func (c *multiNamespaceCache) WaitForCacheSync(ctx context.Context) bool { + synced := true + for _, cache := range c.namespaceToCache { + if !cache.WaitForCacheSync(ctx) { + synced = false + } + } + + // check if cluster scoped cache has synced + if c.clusterCache != nil && !c.clusterCache.WaitForCacheSync(ctx) { + synced = false + } + return synced +} + +func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error { + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) + if err != nil { + return err + } + + if !isNamespaced { + return c.clusterCache.IndexField(ctx, obj, field, extractValue) + } + + for _, cache := range c.namespaceToCache { + if err := cache.IndexField(ctx, obj, field, extractValue); err != nil { + return err + } + } + return nil +} + +func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { + isNamespaced, err := apiutil.IsObjectNamespaced(obj, c.Scheme, c.RESTMapper) + if err != nil { + return err + } + + if !isNamespaced { + // Look into the global cache to fetch the object + return c.clusterCache.Get(ctx, key, obj) + } + + cache, ok := c.namespaceToCache[key.Namespace] + if !ok { + if global, hasGlobal := c.namespaceToCache[metav1.NamespaceAll]; hasGlobal { + return global.Get(ctx, key, obj, opts...) + } + return fmt.Errorf("unable to get: %v because of unknown namespace for the cache", key) + } + return cache.Get(ctx, key, obj, opts...) +} + +// List multi namespace cache will get all the objects in the namespaces that the cache is watching if asked for all namespaces. +func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + listOpts := client.ListOptions{} + listOpts.ApplyOptions(opts) + + isNamespaced, err := apiutil.IsObjectNamespaced(list, c.Scheme, c.RESTMapper) + if err != nil { + return err + } + + if !isNamespaced { + // Look at the global cache to get the objects with the specified GVK + return c.clusterCache.List(ctx, list, opts...) + } + + if listOpts.Namespace != corev1.NamespaceAll { + cache, ok := c.namespaceToCache[listOpts.Namespace] + if !ok { + return fmt.Errorf("unable to list: %v because of unknown namespace for the cache", listOpts.Namespace) + } + return cache.List(ctx, list, opts...) + } + + listAccessor, err := apimeta.ListAccessor(list) + if err != nil { + return err + } + + allItems, err := apimeta.ExtractList(list) + if err != nil { + return err + } + + limitSet := listOpts.Limit > 0 + + var resourceVersion string + for _, cache := range c.namespaceToCache { + listObj := list.DeepCopyObject().(client.ObjectList) + err = cache.List(ctx, listObj, &listOpts) + if err != nil { + return err + } + items, err := apimeta.ExtractList(listObj) + if err != nil { + return err + } + accessor, err := apimeta.ListAccessor(listObj) + if err != nil { + return fmt.Errorf("object: %T must be a list type", list) + } + allItems = append(allItems, items...) + + // The last list call should have the most correct resource version. + resourceVersion = accessor.GetResourceVersion() + if limitSet { + // decrement Limit by the number of items + // fetched from the current namespace. + listOpts.Limit -= int64(len(items)) + + // if a Limit was set and the number of + // items read has reached this set limit, + // then stop reading. + if listOpts.Limit == 0 { + break + } + } + } + listAccessor.SetResourceVersion(resourceVersion) + + return apimeta.SetList(list, allItems) +} + +// multiNamespaceInformer knows how to handle interacting with the underlying informer across multiple namespaces. +type multiNamespaceInformer struct { + namespaceToInformer map[string]Informer +} + +type handlerRegistration struct { + handles map[string]toolscache.ResourceEventHandlerRegistration +} + +type syncer interface { + HasSynced() bool +} + +// HasSynced asserts that the handler has been called for the full initial state of the informer. +// This uses syncer to be compatible between client-go 1.27+ and older versions when the interface changed. +func (h handlerRegistration) HasSynced() bool { + for _, reg := range h.handles { + if s, ok := reg.(syncer); ok { + if !s.HasSynced() { + return false + } + } + } + return true +} + +var _ Informer = &multiNamespaceInformer{} + +// AddEventHandler adds the handler to each informer. +func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error) { + handles := handlerRegistration{ + handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer)), + } + + for ns, informer := range i.namespaceToInformer { + registration, err := informer.AddEventHandler(handler) + if err != nil { + return nil, err + } + handles.handles[ns] = registration + } + + return handles, nil +} + +// AddEventHandlerWithResyncPeriod adds the handler with a resync period to each namespaced informer. +func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error) { + handles := handlerRegistration{ + handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer)), + } + + for ns, informer := range i.namespaceToInformer { + registration, err := informer.AddEventHandlerWithResyncPeriod(handler, resyncPeriod) + if err != nil { + return nil, err + } + handles.handles[ns] = registration + } + + return handles, nil +} + +// RemoveEventHandler removes a previously added event handler given by its registration handle. +func (i *multiNamespaceInformer) RemoveEventHandler(h toolscache.ResourceEventHandlerRegistration) error { + handles, ok := h.(handlerRegistration) + if !ok { + return fmt.Errorf("registration is not a registration returned by multiNamespaceInformer") + } + for ns, informer := range i.namespaceToInformer { + registration, ok := handles.handles[ns] + if !ok { + continue + } + if err := informer.RemoveEventHandler(registration); err != nil { + return err + } + } + return nil +} + +// AddIndexers adds the indexers to each informer. +func (i *multiNamespaceInformer) AddIndexers(indexers toolscache.Indexers) error { + for _, informer := range i.namespaceToInformer { + err := informer.AddIndexers(indexers) + if err != nil { + return err + } + } + return nil +} + +// HasSynced checks if each informer has synced. +func (i *multiNamespaceInformer) HasSynced() bool { + for _, informer := range i.namespaceToInformer { + if !informer.HasSynced() { + return false + } + } + return true +} + +// IsStopped checks if each namespaced informer has stopped, returns false if any are still running. +func (i *multiNamespaceInformer) IsStopped() bool { + for _, informer := range i.namespaceToInformer { + if stopped := informer.IsStopped(); !stopped { + return false + } + } + return true +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go b/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go new file mode 100644 index 00000000..2b9b60d8 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/certwatcher.go @@ -0,0 +1,204 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package certwatcher + +import ( + "context" + "crypto/tls" + "fmt" + "sync" + "time" + + "github.com/fsnotify/fsnotify" + kerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + "sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("certwatcher") + +// CertWatcher watches certificate and key files for changes. When either file +// changes, it reads and parses both and calls an optional callback with the new +// certificate. +type CertWatcher struct { + sync.RWMutex + + currentCert *tls.Certificate + watcher *fsnotify.Watcher + + certPath string + keyPath string + + // callback is a function to be invoked when the certificate changes. + callback func(tls.Certificate) +} + +// New returns a new CertWatcher watching the given certificate and key. +func New(certPath, keyPath string) (*CertWatcher, error) { + var err error + + cw := &CertWatcher{ + certPath: certPath, + keyPath: keyPath, + } + + // Initial read of certificate and key. + if err := cw.ReadCertificate(); err != nil { + return nil, err + } + + cw.watcher, err = fsnotify.NewWatcher() + if err != nil { + return nil, err + } + + return cw, nil +} + +// RegisterCallback registers a callback to be invoked when the certificate changes. +func (cw *CertWatcher) RegisterCallback(callback func(tls.Certificate)) { + cw.Lock() + defer cw.Unlock() + // If the current certificate is not nil, invoke the callback immediately. + if cw.currentCert != nil { + callback(*cw.currentCert) + } + cw.callback = callback +} + +// GetCertificate fetches the currently loaded certificate, which may be nil. +func (cw *CertWatcher) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { + cw.RLock() + defer cw.RUnlock() + return cw.currentCert, nil +} + +// Start starts the watch on the certificate and key files. +func (cw *CertWatcher) Start(ctx context.Context) error { + files := sets.New(cw.certPath, cw.keyPath) + + { + var watchErr error + if err := wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, func(ctx context.Context) (done bool, err error) { + for _, f := range files.UnsortedList() { + if err := cw.watcher.Add(f); err != nil { + watchErr = err + return false, nil //nolint:nilerr // We want to keep trying. + } + // We've added the watch, remove it from the set. + files.Delete(f) + } + return true, nil + }); err != nil { + return fmt.Errorf("failed to add watches: %w", kerrors.NewAggregate([]error{err, watchErr})) + } + } + + go cw.Watch() + + log.Info("Starting certificate watcher") + + // Block until the context is done. + <-ctx.Done() + + return cw.watcher.Close() +} + +// Watch reads events from the watcher's channel and reacts to changes. +func (cw *CertWatcher) Watch() { + for { + select { + case event, ok := <-cw.watcher.Events: + // Channel is closed. + if !ok { + return + } + + cw.handleEvent(event) + + case err, ok := <-cw.watcher.Errors: + // Channel is closed. + if !ok { + return + } + + log.Error(err, "certificate watch error") + } + } +} + +// ReadCertificate reads the certificate and key files from disk, parses them, +// and updates the current certificate on the watcher. If a callback is set, it +// is invoked with the new certificate. +func (cw *CertWatcher) ReadCertificate() error { + metrics.ReadCertificateTotal.Inc() + cert, err := tls.LoadX509KeyPair(cw.certPath, cw.keyPath) + if err != nil { + metrics.ReadCertificateErrors.Inc() + return err + } + + cw.Lock() + cw.currentCert = &cert + cw.Unlock() + + log.Info("Updated current TLS certificate") + + // If a callback is registered, invoke it with the new certificate. + cw.RLock() + defer cw.RUnlock() + if cw.callback != nil { + go func() { + cw.callback(cert) + }() + } + return nil +} + +func (cw *CertWatcher) handleEvent(event fsnotify.Event) { + // Only care about events which may modify the contents of the file. + if !(isWrite(event) || isRemove(event) || isCreate(event)) { + return + } + + log.V(1).Info("certificate event", "event", event) + + // If the file was removed, re-add the watch. + if isRemove(event) { + if err := cw.watcher.Add(event.Name); err != nil { + log.Error(err, "error re-watching file") + } + } + + if err := cw.ReadCertificate(); err != nil { + log.Error(err, "error re-reading certificate") + } +} + +func isWrite(event fsnotify.Event) bool { + return event.Op.Has(fsnotify.Write) +} + +func isCreate(event fsnotify.Event) bool { + return event.Op.Has(fsnotify.Create) +} + +func isRemove(event fsnotify.Event) bool { + return event.Op.Has(fsnotify.Remove) +} diff --git a/vendor/k8s.io/code-generator/cmd/client-gen/generators/util/gvpackages.go b/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/doc.go similarity index 63% rename from vendor/k8s.io/code-generator/cmd/client-gen/generators/util/gvpackages.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/doc.go index fcc19509..40c2fc0b 100644 --- a/vendor/k8s.io/code-generator/cmd/client-gen/generators/util/gvpackages.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/doc.go @@ -14,17 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -package util - -import "strings" - -func ParsePathGroupVersion(pgvString string) (gvPath string, gvString string) { - subs := strings.Split(pgvString, "/") - length := len(subs) - switch length { - case 0, 1, 2: - return "", pgvString - default: - return strings.Join(subs[:length-2], "/"), strings.Join(subs[length-2:], "/") - } -} +/* +Package certwatcher is a helper for reloading Certificates from disk to be used +with tls servers. It provides a helper func `GetCertificate` which can be +called from `tls.Config` and passed into your tls.Listener. For a detailed +example server view pkg/webhook/server.go. +*/ +package certwatcher diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics/metrics.go b/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics/metrics.go new file mode 100644 index 00000000..05869eff --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics/metrics.go @@ -0,0 +1,45 @@ +/* +Copyright 2022 The Kubernetes Authors. + +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. +*/ + +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + // ReadCertificateTotal is a prometheus counter metrics which holds the total + // number of certificate reads. + ReadCertificateTotal = prometheus.NewCounter(prometheus.CounterOpts{ + Name: "certwatcher_read_certificate_total", + Help: "Total number of certificate reads", + }) + + // ReadCertificateErrors is a prometheus counter metrics which holds the total + // number of errors from certificate read. + ReadCertificateErrors = prometheus.NewCounter(prometheus.CounterOpts{ + Name: "certwatcher_read_certificate_errors_total", + Help: "Total number of certificate read errors", + }) +) + +func init() { + metrics.Registry.MustRegister( + ReadCertificateTotal, + ReadCertificateErrors, + ) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go new file mode 100644 index 00000000..5f0a6d4b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go @@ -0,0 +1,181 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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. +*/ + +package config + +import ( + "flag" + "fmt" + "os" + "os/user" + "path/filepath" + + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +// KubeconfigFlagName is the name of the kubeconfig flag +const KubeconfigFlagName = "kubeconfig" + +var ( + kubeconfig string + log = logf.RuntimeLog.WithName("client").WithName("config") +) + +// init registers the "kubeconfig" flag to the default command line FlagSet. +// TODO: This should be removed, as it potentially leads to redefined flag errors for users, if they already +// have registered the "kubeconfig" flag to the command line FlagSet in other parts of their code. +func init() { + RegisterFlags(flag.CommandLine) +} + +// RegisterFlags registers flag variables to the given FlagSet if not already registered. +// It uses the default command line FlagSet, if none is provided. Currently, it only registers the kubeconfig flag. +func RegisterFlags(fs *flag.FlagSet) { + if fs == nil { + fs = flag.CommandLine + } + if f := fs.Lookup(KubeconfigFlagName); f != nil { + kubeconfig = f.Value.String() + } else { + fs.StringVar(&kubeconfig, KubeconfigFlagName, "", "Paths to a kubeconfig. Only required if out-of-cluster.") + } +} + +// GetConfig creates a *rest.Config for talking to a Kubernetes API server. +// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running +// in cluster and use the cluster provided kubeconfig. +// +// It also applies saner defaults for QPS and burst based on the Kubernetes +// controller manager defaults (20 QPS, 30 burst) +// +// Config precedence: +// +// * --kubeconfig flag pointing at a file +// +// * KUBECONFIG environment variable pointing at a file +// +// * In-cluster config if running in cluster +// +// * $HOME/.kube/config if exists. +func GetConfig() (*rest.Config, error) { + return GetConfigWithContext("") +} + +// GetConfigWithContext creates a *rest.Config for talking to a Kubernetes API server with a specific context. +// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running +// in cluster and use the cluster provided kubeconfig. +// +// It also applies saner defaults for QPS and burst based on the Kubernetes +// controller manager defaults (20 QPS, 30 burst) +// +// Config precedence: +// +// * --kubeconfig flag pointing at a file +// +// * KUBECONFIG environment variable pointing at a file +// +// * In-cluster config if running in cluster +// +// * $HOME/.kube/config if exists. +func GetConfigWithContext(context string) (*rest.Config, error) { + cfg, err := loadConfig(context) + if err != nil { + return nil, err + } + if cfg.QPS == 0.0 { + cfg.QPS = 20.0 + } + if cfg.Burst == 0 { + cfg.Burst = 30 + } + return cfg, nil +} + +// loadInClusterConfig is a function used to load the in-cluster +// Kubernetes client config. This variable makes is possible to +// test the precedence of loading the config. +var loadInClusterConfig = rest.InClusterConfig + +// loadConfig loads a REST Config as per the rules specified in GetConfig. +func loadConfig(context string) (config *rest.Config, configErr error) { + // If a flag is specified with the config location, use that + if len(kubeconfig) > 0 { + return loadConfigWithContext("", &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}, context) + } + + // If the recommended kubeconfig env variable is not specified, + // try the in-cluster config. + kubeconfigPath := os.Getenv(clientcmd.RecommendedConfigPathEnvVar) + if len(kubeconfigPath) == 0 { + c, err := loadInClusterConfig() + if err == nil { + return c, nil + } + + defer func() { + if configErr != nil { + log.Error(err, "unable to load in-cluster config") + } + }() + } + + // If the recommended kubeconfig env variable is set, or there + // is no in-cluster config, try the default recommended locations. + // + // NOTE: For default config file locations, upstream only checks + // $HOME for the user's home directory, but we can also try + // os/user.HomeDir when $HOME is unset. + // + // TODO(jlanford): could this be done upstream? + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + if _, ok := os.LookupEnv("HOME"); !ok { + u, err := user.Current() + if err != nil { + return nil, fmt.Errorf("could not get current user: %w", err) + } + loadingRules.Precedence = append(loadingRules.Precedence, filepath.Join(u.HomeDir, clientcmd.RecommendedHomeDir, clientcmd.RecommendedFileName)) + } + + return loadConfigWithContext("", loadingRules, context) +} + +func loadConfigWithContext(apiServerURL string, loader clientcmd.ClientConfigLoader, context string) (*rest.Config, error) { + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + loader, + &clientcmd.ConfigOverrides{ + ClusterInfo: clientcmdapi.Cluster{ + Server: apiServerURL, + }, + CurrentContext: context, + }).ClientConfig() +} + +// GetConfigOrDie creates a *rest.Config for talking to a Kubernetes apiserver. +// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running +// in cluster and use the cluster provided kubeconfig. +// +// Will log an error and exit if there is an error creating the rest.Config. +func GetConfigOrDie() *rest.Config { + config, err := GetConfig() + if err != nil { + log.Error(err, "unable to get kubeconfig") + os.Exit(1) + } + return config +} diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/doc.go similarity index 77% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/doc.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/client/config/doc.go index a0ee3480..796c9cf5 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/fake/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/config/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kube Bind Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -// Package fake has the automatically generated clients. -package fake +// Package config contains libraries for initializing REST configs for talking to the Kubernetes API +package config diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go new file mode 100644 index 00000000..248893ea --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go @@ -0,0 +1,316 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package cluster + +import ( + "context" + "errors" + "net/http" + "time" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" +) + +// Cluster provides various methods to interact with a cluster. +type Cluster interface { + // GetHTTPClient returns an HTTP client that can be used to talk to the apiserver + GetHTTPClient() *http.Client + + // GetConfig returns an initialized Config + GetConfig() *rest.Config + + // GetCache returns a cache.Cache + GetCache() cache.Cache + + // GetScheme returns an initialized Scheme + GetScheme() *runtime.Scheme + + // GetClient returns a client configured with the Config. This client may + // not be a fully "direct" client -- it may read from a cache, for + // instance. See Options.NewClient for more information on how the default + // implementation works. + GetClient() client.Client + + // GetFieldIndexer returns a client.FieldIndexer configured with the client + GetFieldIndexer() client.FieldIndexer + + // GetEventRecorderFor returns a new EventRecorder for the provided name + GetEventRecorderFor(name string) record.EventRecorder + + // GetRESTMapper returns a RESTMapper + GetRESTMapper() meta.RESTMapper + + // GetAPIReader returns a reader that will be configured to use the API server. + // This should be used sparingly and only when the client does not fit your + // use case. + GetAPIReader() client.Reader + + // Start starts the cluster + Start(ctx context.Context) error +} + +// Options are the possible options that can be configured for a Cluster. +type Options struct { + // Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources + // Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better + // idea to pass your own scheme in. See the documentation in pkg/scheme for more information. + Scheme *runtime.Scheme + + // MapperProvider provides the rest mapper used to map go types to Kubernetes APIs + MapperProvider func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) + + // Logger is the logger that should be used by this Cluster. + // If none is set, it defaults to log.Log global logger. + Logger logr.Logger + + // SyncPeriod determines the minimum frequency at which watched resources are + // reconciled. A lower period will correct entropy more quickly, but reduce + // responsiveness to change if there are many watched resources. Change this + // value only if you know what you are doing. Defaults to 10 hours if unset. + // there will a 10 percent jitter between the SyncPeriod of all controllers + // so that all controllers will not send list requests simultaneously. + // + // Deprecated: Use Cache.SyncPeriod instead. + SyncPeriod *time.Duration + + // HTTPClient is the http client that will be used to create the default + // Cache and Client. If not set the rest.HTTPClientFor function will be used + // to create the http client. + HTTPClient *http.Client + + // Cache is the cache.Options that will be used to create the default Cache. + // By default, the cache will watch and list requested objects in all namespaces. + Cache cache.Options + + // NewCache is the function that will create the cache to be used + // by the manager. If not set this will use the default new cache function. + // + // When using a custom NewCache, the Cache options will be passed to the + // NewCache function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewCache if you know what you are doing. + NewCache cache.NewCacheFunc + + // Client is the client.Options that will be used to create the default Client. + // By default, the client will use the cache for reads and direct calls for writes. + Client client.Options + + // NewClient is the func that creates the client to be used by the manager. + // If not set this will create a Client backed by a Cache for read operations + // and a direct Client for write operations. + // + // When using a custom NewClient, the Client options will be passed to the + // NewClient function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewClient if you know what you are doing. + NewClient client.NewClientFunc + + // EventBroadcaster records Events emitted by the manager and sends them to the Kubernetes API + // Use this to customize the event correlator and spam filter + // + // Deprecated: using this may cause goroutine leaks if the lifetime of your manager or controllers + // is shorter than the lifetime of your process. + EventBroadcaster record.EventBroadcaster + + // makeBroadcaster allows deferring the creation of the broadcaster to + // avoid leaking goroutines if we never call Start on this manager. It also + // returns whether or not this is a "owned" broadcaster, and as such should be + // stopped with the manager. + makeBroadcaster intrec.EventBroadcasterProducer + + // Dependency injection for testing + newRecorderProvider func(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster intrec.EventBroadcasterProducer) (*intrec.Provider, error) +} + +// Option can be used to manipulate Options. +type Option func(*Options) + +// New constructs a brand new cluster. +func New(config *rest.Config, opts ...Option) (Cluster, error) { + if config == nil { + return nil, errors.New("must specify Config") + } + + originalConfig := config + + config = rest.CopyConfig(config) + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + options := Options{} + for _, opt := range opts { + opt(&options) + } + options, err := setOptionsDefaults(options, config) + if err != nil { + options.Logger.Error(err, "Failed to set defaults") + return nil, err + } + + // Create the mapper provider + mapper, err := options.MapperProvider(config, options.HTTPClient) + if err != nil { + options.Logger.Error(err, "Failed to get API Group-Resources") + return nil, err + } + + // Create the cache for the cached read client and registering informers + cacheOpts := options.Cache + { + if cacheOpts.Scheme == nil { + cacheOpts.Scheme = options.Scheme + } + if cacheOpts.Mapper == nil { + cacheOpts.Mapper = mapper + } + if cacheOpts.HTTPClient == nil { + cacheOpts.HTTPClient = options.HTTPClient + } + if cacheOpts.SyncPeriod == nil { + cacheOpts.SyncPeriod = options.SyncPeriod + } + } + cache, err := options.NewCache(config, cacheOpts) + if err != nil { + return nil, err + } + + // Create the client, and default its options. + clientOpts := options.Client + { + if clientOpts.Scheme == nil { + clientOpts.Scheme = options.Scheme + } + if clientOpts.Mapper == nil { + clientOpts.Mapper = mapper + } + if clientOpts.HTTPClient == nil { + clientOpts.HTTPClient = options.HTTPClient + } + if clientOpts.Cache == nil { + clientOpts.Cache = &client.CacheOptions{ + Unstructured: false, + } + } + if clientOpts.Cache.Reader == nil { + clientOpts.Cache.Reader = cache + } + } + clientWriter, err := options.NewClient(config, clientOpts) + if err != nil { + return nil, err + } + + // Create the API Reader, a client with no cache. + clientReader, err := client.New(config, client.Options{ + HTTPClient: options.HTTPClient, + Scheme: options.Scheme, + Mapper: mapper, + }) + if err != nil { + return nil, err + } + + // Create the recorder provider to inject event recorders for the components. + // TODO(directxman12): the log for the event provider should have a context (name, tags, etc) specific + // to the particular controller that it's being injected into, rather than a generic one like is here. + recorderProvider, err := options.newRecorderProvider(config, options.HTTPClient, options.Scheme, options.Logger.WithName("events"), options.makeBroadcaster) + if err != nil { + return nil, err + } + + return &cluster{ + config: originalConfig, + httpClient: options.HTTPClient, + scheme: options.Scheme, + cache: cache, + fieldIndexes: cache, + client: clientWriter, + apiReader: clientReader, + recorderProvider: recorderProvider, + mapper: mapper, + logger: options.Logger, + }, nil +} + +// setOptionsDefaults set default values for Options fields. +func setOptionsDefaults(options Options, config *rest.Config) (Options, error) { + if options.HTTPClient == nil { + var err error + options.HTTPClient, err = rest.HTTPClientFor(config) + if err != nil { + return options, err + } + } + + // Use the Kubernetes client-go scheme if none is specified + if options.Scheme == nil { + options.Scheme = scheme.Scheme + } + + if options.MapperProvider == nil { + options.MapperProvider = apiutil.NewDynamicRESTMapper + } + + // Allow users to define how to create a new client + if options.NewClient == nil { + options.NewClient = client.New + } + + // Allow newCache to be mocked + if options.NewCache == nil { + options.NewCache = cache.New + } + + // Allow newRecorderProvider to be mocked + if options.newRecorderProvider == nil { + options.newRecorderProvider = intrec.NewProvider + } + + // This is duplicated with pkg/manager, we need it here to provide + // the user with an EventBroadcaster and there for the Leader election + if options.EventBroadcaster == nil { + // defer initialization to avoid leaking by default + options.makeBroadcaster = func() (record.EventBroadcaster, bool) { + return record.NewBroadcaster(), true + } + } else { + options.makeBroadcaster = func() (record.EventBroadcaster, bool) { + return options.EventBroadcaster, false + } + } + + if options.Logger.GetSink() == nil { + options.Logger = logf.RuntimeLog.WithName("cluster") + } + + return options, nil +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go new file mode 100644 index 00000000..27427642 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cluster/internal.go @@ -0,0 +1,105 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package cluster + +import ( + "context" + "net/http" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" +) + +type cluster struct { + // config is the rest.config used to talk to the apiserver. Required. + config *rest.Config + + httpClient *http.Client + scheme *runtime.Scheme + cache cache.Cache + client client.Client + + // apiReader is the reader that will make requests to the api server and not the cache. + apiReader client.Reader + + // fieldIndexes knows how to add field indexes over the Cache used by this controller, + // which can later be consumed via field selectors from the injected client. + fieldIndexes client.FieldIndexer + + // recorderProvider is used to generate event recorders that will be injected into Controllers + // (and EventHandlers, Sources and Predicates). + recorderProvider *intrec.Provider + + // mapper is used to map resources to kind, and map kind and version. + mapper meta.RESTMapper + + // Logger is the logger that should be used by this manager. + // If none is set, it defaults to log.Log global logger. + logger logr.Logger +} + +func (c *cluster) GetConfig() *rest.Config { + return c.config +} + +func (c *cluster) GetHTTPClient() *http.Client { + return c.httpClient +} + +func (c *cluster) GetClient() client.Client { + return c.client +} + +func (c *cluster) GetScheme() *runtime.Scheme { + return c.scheme +} + +func (c *cluster) GetFieldIndexer() client.FieldIndexer { + return c.fieldIndexes +} + +func (c *cluster) GetCache() cache.Cache { + return c.cache +} + +func (c *cluster) GetEventRecorderFor(name string) record.EventRecorder { + return c.recorderProvider.GetEventRecorderFor(name) +} + +func (c *cluster) GetRESTMapper() meta.RESTMapper { + return c.mapper +} + +func (c *cluster) GetAPIReader() client.Reader { + return c.apiReader +} + +func (c *cluster) GetLogger() logr.Logger { + return c.logger +} + +func (c *cluster) Start(ctx context.Context) error { + defer c.recorderProvider.Stop(ctx) + return c.cache.Start(ctx) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go new file mode 100644 index 00000000..9c7b875a --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go @@ -0,0 +1,112 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package config + +import ( + "fmt" + "os" + "sync" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" +) + +// ControllerManagerConfiguration defines the functions necessary to parse a config file +// and to configure the Options struct for the ctrl.Manager. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerManagerConfiguration interface { + runtime.Object + + // Complete returns the versioned configuration + Complete() (v1alpha1.ControllerManagerConfigurationSpec, error) +} + +// DeferredFileLoader is used to configure the decoder for loading controller +// runtime component config types. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type DeferredFileLoader struct { + ControllerManagerConfiguration + path string + scheme *runtime.Scheme + once sync.Once + err error +} + +// File will set up the deferred file loader for the configuration +// this will also configure the defaults for the loader if nothing is +// +// Defaults: +// * Path: "./config.yaml" +// * Kind: GenericControllerManagerConfiguration +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +func File() *DeferredFileLoader { + scheme := runtime.NewScheme() + utilruntime.Must(v1alpha1.AddToScheme(scheme)) + return &DeferredFileLoader{ + path: "./config.yaml", + ControllerManagerConfiguration: &v1alpha1.ControllerManagerConfiguration{}, + scheme: scheme, + } +} + +// Complete will use sync.Once to set the scheme. +func (d *DeferredFileLoader) Complete() (v1alpha1.ControllerManagerConfigurationSpec, error) { + d.once.Do(d.loadFile) + if d.err != nil { + return v1alpha1.ControllerManagerConfigurationSpec{}, d.err + } + return d.ControllerManagerConfiguration.Complete() +} + +// AtPath will set the path to load the file for the decoder. +func (d *DeferredFileLoader) AtPath(path string) *DeferredFileLoader { + d.path = path + return d +} + +// OfKind will set the type to be used for decoding the file into. +func (d *DeferredFileLoader) OfKind(obj ControllerManagerConfiguration) *DeferredFileLoader { + d.ControllerManagerConfiguration = obj + return d +} + +// loadFile is used from the mutex.Once to load the file. +func (d *DeferredFileLoader) loadFile() { + if d.scheme == nil { + d.err = fmt.Errorf("scheme not supplied to controller configuration loader") + return + } + + content, err := os.ReadFile(d.path) + if err != nil { + d.err = fmt.Errorf("could not read file at %s", d.path) + return + } + + codecs := serializer.NewCodecFactory(d.scheme) + + // Regardless of if the bytes are of any external version, + // it will be read successfully and converted into the internal version + if err = runtime.DecodeInto(codecs.UniversalDecoder(), content, d.ControllerManagerConfiguration); err != nil { + d.err = fmt.Errorf("could not decode file into runtime.Object") + } +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/controller.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/controller.go new file mode 100644 index 00000000..b37dffae --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/controller.go @@ -0,0 +1,49 @@ +/* +Copyright 2023 The Kubernetes Authors. + +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. +*/ + +package config + +import "time" + +// Controller contains configuration options for a controller. +type Controller struct { + // GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation + // allowed for that controller. + // + // When a controller is registered within this manager using the builder utilities, + // users have to specify the type the controller reconciles in the For(...) call. + // If the object's kind passed matches one of the keys in this map, the concurrency + // for that controller is set to the number specified. + // + // The key is expected to be consistent in form with GroupKind.String(), + // e.g. ReplicaSet in apps group (regardless of version) would be `ReplicaSet.apps`. + GroupKindConcurrency map[string]int + + // MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1. + MaxConcurrentReconciles int + + // CacheSyncTimeout refers to the time limit set to wait for syncing caches. + // Defaults to 2 minutes if not set. + CacheSyncTimeout time.Duration + + // RecoverPanic indicates whether the panic caused by reconcile should be recovered. + // Defaults to the Controller.RecoverPanic setting from the Manager if unset. + RecoverPanic *bool + + // NeedLeaderElection indicates whether the controller needs to use leader election. + // Defaults to true, which means the controller will use leader election. + NeedLeaderElection *bool +} diff --git a/pkg/client/clientset/versioned/fake/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go similarity index 76% rename from pkg/client/clientset/versioned/fake/doc.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go index ca4191ad..47a5a2f1 100644 --- a/pkg/client/clientset/versioned/fake/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kube Bind Authors. +Copyright 2020 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated fake clientset. -package fake +// Package config contains functionality for interacting with +// configuration for controller-runtime components. +package config diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go similarity index 54% rename from vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/doc.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go index f4200f2f..8fdf14d3 100644 --- a/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Kubernetes Authors. +Copyright 2020 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,10 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package deepcopy generates DeepCopy, DeepCopyInto, and DeepCopyObject -// implementations for types. +// Package v1alpha1 provides the ControllerManagerConfiguration used for +// configuring ctrl.Manager +// +kubebuilder:object:generate=true // -// It's ported from k8s.io/code-generator's / k8s.io/gengo's deepcopy-gen, -// but it's scoped specifically to runtime.Object and skips support for -// deepcopying interfaces, which aren't handled in CRDs anyway. -package deepcopy +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +package v1alpha1 diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go new file mode 100644 index 00000000..ca854bcf --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go @@ -0,0 +1,43 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. + GroupVersion = schema.GroupVersion{Group: "controller-runtime.sigs.k8s.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + // + // Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. + AddToScheme = SchemeBuilder.AddToScheme +) + +func init() { + SchemeBuilder.Register(&ControllerManagerConfiguration{}) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go new file mode 100644 index 00000000..52c8ab30 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go @@ -0,0 +1,179 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + configv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +// ControllerManagerConfigurationSpec defines the desired state of GenericControllerManagerConfiguration. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerManagerConfigurationSpec struct { + // SyncPeriod determines the minimum frequency at which watched resources are + // reconciled. A lower period will correct entropy more quickly, but reduce + // responsiveness to change if there are many watched resources. Change this + // value only if you know what you are doing. Defaults to 10 hours if unset. + // there will a 10 percent jitter between the SyncPeriod of all controllers + // so that all controllers will not send list requests simultaneously. + // +optional + SyncPeriod *metav1.Duration `json:"syncPeriod,omitempty"` + + // LeaderElection is the LeaderElection config to be used when configuring + // the manager.Manager leader election + // +optional + LeaderElection *configv1alpha1.LeaderElectionConfiguration `json:"leaderElection,omitempty"` + + // CacheNamespace if specified restricts the manager's cache to watch objects in + // the desired namespace Defaults to all namespaces + // + // Note: If a namespace is specified, controllers can still Watch for a + // cluster-scoped resource (e.g Node). For namespaced resources the cache + // will only hold objects from the desired namespace. + // +optional + CacheNamespace string `json:"cacheNamespace,omitempty"` + + // GracefulShutdownTimeout is the duration given to runnable to stop before the manager actually returns on stop. + // To disable graceful shutdown, set to time.Duration(0) + // To use graceful shutdown without timeout, set to a negative duration, e.G. time.Duration(-1) + // The graceful shutdown is skipped for safety reasons in case the leader election lease is lost. + GracefulShutdownTimeout *metav1.Duration `json:"gracefulShutDown,omitempty"` + + // Controller contains global configuration options for controllers + // registered within this manager. + // +optional + Controller *ControllerConfigurationSpec `json:"controller,omitempty"` + + // Metrics contains the controller metrics configuration + // +optional + Metrics ControllerMetrics `json:"metrics,omitempty"` + + // Health contains the controller health configuration + // +optional + Health ControllerHealth `json:"health,omitempty"` + + // Webhook contains the controllers webhook configuration + // +optional + Webhook ControllerWebhook `json:"webhook,omitempty"` +} + +// ControllerConfigurationSpec defines the global configuration for +// controllers registered with the manager. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +// +// Deprecated: Controller global configuration can now be set at the manager level, +// using the manager.Options.Controller field. +type ControllerConfigurationSpec struct { + // GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation + // allowed for that controller. + // + // When a controller is registered within this manager using the builder utilities, + // users have to specify the type the controller reconciles in the For(...) call. + // If the object's kind passed matches one of the keys in this map, the concurrency + // for that controller is set to the number specified. + // + // The key is expected to be consistent in form with GroupKind.String(), + // e.g. ReplicaSet in apps group (regardless of version) would be `ReplicaSet.apps`. + // + // +optional + GroupKindConcurrency map[string]int `json:"groupKindConcurrency,omitempty"` + + // CacheSyncTimeout refers to the time limit set to wait for syncing caches. + // Defaults to 2 minutes if not set. + // +optional + CacheSyncTimeout *time.Duration `json:"cacheSyncTimeout,omitempty"` + + // RecoverPanic indicates if panics should be recovered. + // +optional + RecoverPanic *bool `json:"recoverPanic,omitempty"` +} + +// ControllerMetrics defines the metrics configs. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerMetrics struct { + // BindAddress is the TCP address that the controller should bind to + // for serving prometheus metrics. + // It can be set to "0" to disable the metrics serving. + // +optional + BindAddress string `json:"bindAddress,omitempty"` +} + +// ControllerHealth defines the health configs. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerHealth struct { + // HealthProbeBindAddress is the TCP address that the controller should bind to + // for serving health probes + // It can be set to "0" or "" to disable serving the health probe. + // +optional + HealthProbeBindAddress string `json:"healthProbeBindAddress,omitempty"` + + // ReadinessEndpointName, defaults to "readyz" + // +optional + ReadinessEndpointName string `json:"readinessEndpointName,omitempty"` + + // LivenessEndpointName, defaults to "healthz" + // +optional + LivenessEndpointName string `json:"livenessEndpointName,omitempty"` +} + +// ControllerWebhook defines the webhook server for the controller. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerWebhook struct { + // Port is the port that the webhook server serves at. + // It is used to set webhook.Server.Port. + // +optional + Port *int `json:"port,omitempty"` + + // Host is the hostname that the webhook server binds to. + // It is used to set webhook.Server.Host. + // +optional + Host string `json:"host,omitempty"` + + // CertDir is the directory that contains the server key and certificate. + // if not set, webhook server would look up the server key and certificate in + // {TempDir}/k8s-webhook-server/serving-certs. The server key and certificate + // must be named tls.key and tls.crt, respectively. + // +optional + CertDir string `json:"certDir,omitempty"` +} + +// +kubebuilder:object:root=true + +// ControllerManagerConfiguration is the Schema for the GenericControllerManagerConfigurations API. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +type ControllerManagerConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // ControllerManagerConfiguration returns the contfigurations for controllers + ControllerManagerConfigurationSpec `json:",inline"` +} + +// Complete returns the configuration for controller-runtime. +// +// Deprecated: The component config package has been deprecated and will be removed in a future release. Users should migrate to their own config implementation, please share feedback in https://github.com/kubernetes-sigs/controller-runtime/issues/895. +func (c *ControllerManagerConfigurationSpec) Complete() (ControllerManagerConfigurationSpec, error) { + return *c, nil +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000..ff14c055 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,157 @@ +//go:build !ignore_autogenerated + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + configv1alpha1 "k8s.io/component-base/config/v1alpha1" + timex "time" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerConfigurationSpec) DeepCopyInto(out *ControllerConfigurationSpec) { + *out = *in + if in.GroupKindConcurrency != nil { + in, out := &in.GroupKindConcurrency, &out.GroupKindConcurrency + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.CacheSyncTimeout != nil { + in, out := &in.CacheSyncTimeout, &out.CacheSyncTimeout + *out = new(timex.Duration) + **out = **in + } + if in.RecoverPanic != nil { + in, out := &in.RecoverPanic, &out.RecoverPanic + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerConfigurationSpec. +func (in *ControllerConfigurationSpec) DeepCopy() *ControllerConfigurationSpec { + if in == nil { + return nil + } + out := new(ControllerConfigurationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerHealth) DeepCopyInto(out *ControllerHealth) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerHealth. +func (in *ControllerHealth) DeepCopy() *ControllerHealth { + if in == nil { + return nil + } + out := new(ControllerHealth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerManagerConfiguration) DeepCopyInto(out *ControllerManagerConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ControllerManagerConfigurationSpec.DeepCopyInto(&out.ControllerManagerConfigurationSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerManagerConfiguration. +func (in *ControllerManagerConfiguration) DeepCopy() *ControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(ControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ControllerManagerConfiguration) 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 *ControllerManagerConfigurationSpec) DeepCopyInto(out *ControllerManagerConfigurationSpec) { + *out = *in + if in.SyncPeriod != nil { + in, out := &in.SyncPeriod, &out.SyncPeriod + *out = new(v1.Duration) + **out = **in + } + if in.LeaderElection != nil { + in, out := &in.LeaderElection, &out.LeaderElection + *out = new(configv1alpha1.LeaderElectionConfiguration) + (*in).DeepCopyInto(*out) + } + if in.GracefulShutdownTimeout != nil { + in, out := &in.GracefulShutdownTimeout, &out.GracefulShutdownTimeout + *out = new(v1.Duration) + **out = **in + } + if in.Controller != nil { + in, out := &in.Controller, &out.Controller + *out = new(ControllerConfigurationSpec) + (*in).DeepCopyInto(*out) + } + out.Metrics = in.Metrics + out.Health = in.Health + in.Webhook.DeepCopyInto(&out.Webhook) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerManagerConfigurationSpec. +func (in *ControllerManagerConfigurationSpec) DeepCopy() *ControllerManagerConfigurationSpec { + if in == nil { + return nil + } + out := new(ControllerManagerConfigurationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerMetrics) DeepCopyInto(out *ControllerMetrics) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerMetrics. +func (in *ControllerMetrics) DeepCopy() *ControllerMetrics { + if in == nil { + return nil + } + out := new(ControllerMetrics) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerWebhook) DeepCopyInto(out *ControllerWebhook) { + *out = *in + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(int) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerWebhook. +func (in *ControllerWebhook) DeepCopy() *ControllerWebhook { + if in == nil { + return nil + } + out := new(ControllerWebhook) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go new file mode 100644 index 00000000..e48db41f --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go @@ -0,0 +1,176 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package controller + +import ( + "context" + "fmt" + "time" + + "github.com/go-logr/logr" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog/v2" + + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/internal/controller" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/ratelimiter" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +// Options are the arguments for creating a new Controller. +type Options struct { + // MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1. + MaxConcurrentReconciles int + + // CacheSyncTimeout refers to the time limit set to wait for syncing caches. + // Defaults to 2 minutes if not set. + CacheSyncTimeout time.Duration + + // RecoverPanic indicates whether the panic caused by reconcile should be recovered. + // Defaults to the Controller.RecoverPanic setting from the Manager if unset. + RecoverPanic *bool + + // NeedLeaderElection indicates whether the controller needs to use leader election. + // Defaults to true, which means the controller will use leader election. + NeedLeaderElection *bool + + // Reconciler reconciles an object + Reconciler reconcile.Reconciler + + // RateLimiter is used to limit how frequently requests may be queued. + // Defaults to MaxOfRateLimiter which has both overall and per-item rate limiting. + // The overall is a token bucket and the per-item is exponential. + RateLimiter ratelimiter.RateLimiter + + // LogConstructor is used to construct a logger used for this controller and passed + // to each reconciliation via the context field. + LogConstructor func(request *reconcile.Request) logr.Logger +} + +// Controller implements a Kubernetes API. A Controller manages a work queue fed reconcile.Requests +// from source.Sources. Work is performed through the reconcile.Reconciler for each enqueued item. +// Work typically is reads and writes Kubernetes objects to make the system state match the state specified +// in the object Spec. +type Controller interface { + // Reconciler is called to reconcile an object by Namespace/Name + reconcile.Reconciler + + // Watch takes events provided by a Source and uses the EventHandler to + // enqueue reconcile.Requests in response to the events. + // + // Watch may be provided one or more Predicates to filter events before + // they are given to the EventHandler. Events will be passed to the + // EventHandler if all provided Predicates evaluate to true. + Watch(src source.Source, eventhandler handler.EventHandler, predicates ...predicate.Predicate) error + + // Start starts the controller. Start blocks until the context is closed or a + // controller has an error starting. + Start(ctx context.Context) error + + // GetLogger returns this controller logger prefilled with basic information. + GetLogger() logr.Logger +} + +// New returns a new Controller registered with the Manager. The Manager will ensure that shared Caches have +// been synced before the Controller is Started. +func New(name string, mgr manager.Manager, options Options) (Controller, error) { + c, err := NewUnmanaged(name, mgr, options) + if err != nil { + return nil, err + } + + // Add the controller as a Manager components + return c, mgr.Add(c) +} + +// NewUnmanaged returns a new controller without adding it to the manager. The +// caller is responsible for starting the returned controller. +func NewUnmanaged(name string, mgr manager.Manager, options Options) (Controller, error) { + if options.Reconciler == nil { + return nil, fmt.Errorf("must specify Reconciler") + } + + if len(name) == 0 { + return nil, fmt.Errorf("must specify Name for Controller") + } + + if options.LogConstructor == nil { + log := mgr.GetLogger().WithValues( + "controller", name, + ) + options.LogConstructor = func(req *reconcile.Request) logr.Logger { + log := log + if req != nil { + log = log.WithValues( + "object", klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + ) + } + return log + } + } + + if options.MaxConcurrentReconciles <= 0 { + if mgr.GetControllerOptions().MaxConcurrentReconciles > 0 { + options.MaxConcurrentReconciles = mgr.GetControllerOptions().MaxConcurrentReconciles + } else { + options.MaxConcurrentReconciles = 1 + } + } + + if options.CacheSyncTimeout == 0 { + if mgr.GetControllerOptions().CacheSyncTimeout != 0 { + options.CacheSyncTimeout = mgr.GetControllerOptions().CacheSyncTimeout + } else { + options.CacheSyncTimeout = 2 * time.Minute + } + } + + if options.RateLimiter == nil { + options.RateLimiter = workqueue.DefaultControllerRateLimiter() + } + + if options.RecoverPanic == nil { + options.RecoverPanic = mgr.GetControllerOptions().RecoverPanic + } + + if options.NeedLeaderElection == nil { + options.NeedLeaderElection = mgr.GetControllerOptions().NeedLeaderElection + } + + // Create controller with dependencies set + return &controller.Controller{ + Do: options.Reconciler, + MakeQueue: func() workqueue.RateLimitingInterface { + return workqueue.NewRateLimitingQueueWithConfig(options.RateLimiter, workqueue.RateLimitingQueueConfig{ + Name: name, + }) + }, + MaxConcurrentReconciles: options.MaxConcurrentReconciles, + CacheSyncTimeout: options.CacheSyncTimeout, + Name: name, + LogConstructor: options.LogConstructor, + RecoverPanic: options.RecoverPanic, + LeaderElected: options.NeedLeaderElection, + }, nil +} + +// ReconcileIDFromContext gets the reconcileID from the current context. +var ReconcileIDFromContext = controller.ReconcileIDFromContext diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go new file mode 100644 index 00000000..05153f74 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/controllerutil.go @@ -0,0 +1,478 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package controllerutil + +import ( + "context" + "fmt" + "reflect" + + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/utils/ptr" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// AlreadyOwnedError is an error returned if the object you are trying to assign +// a controller reference is already owned by another controller Object is the +// subject and Owner is the reference for the current owner. +type AlreadyOwnedError struct { + Object metav1.Object + Owner metav1.OwnerReference +} + +func (e *AlreadyOwnedError) Error() string { + return fmt.Sprintf("Object %s/%s is already owned by another %s controller %s", e.Object.GetNamespace(), e.Object.GetName(), e.Owner.Kind, e.Owner.Name) +} + +func newAlreadyOwnedError(obj metav1.Object, owner metav1.OwnerReference) *AlreadyOwnedError { + return &AlreadyOwnedError{ + Object: obj, + Owner: owner, + } +} + +// SetControllerReference sets owner as a Controller OwnerReference on controlled. +// This is used for garbage collection of the controlled object and for +// reconciling the owner object on changes to controlled (with a Watch + EnqueueRequestForOwner). +// Since only one OwnerReference can be a controller, it returns an error if +// there is another OwnerReference with Controller flag set. +func SetControllerReference(owner, controlled metav1.Object, scheme *runtime.Scheme) error { + // Validate the owner. + ro, ok := owner.(runtime.Object) + if !ok { + return fmt.Errorf("%T is not a runtime.Object, cannot call SetControllerReference", owner) + } + if err := validateOwner(owner, controlled); err != nil { + return err + } + + // Create a new controller ref. + gvk, err := apiutil.GVKForObject(ro, scheme) + if err != nil { + return err + } + ref := metav1.OwnerReference{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, + Name: owner.GetName(), + UID: owner.GetUID(), + BlockOwnerDeletion: ptr.To(true), + Controller: ptr.To(true), + } + + // Return early with an error if the object is already controlled. + if existing := metav1.GetControllerOf(controlled); existing != nil && !referSameObject(*existing, ref) { + return newAlreadyOwnedError(controlled, *existing) + } + + // Update owner references and return. + upsertOwnerRef(ref, controlled) + return nil +} + +// SetOwnerReference is a helper method to make sure the given object contains an object reference to the object provided. +// This allows you to declare that owner has a dependency on the object without specifying it as a controller. +// If a reference to the same object already exists, it'll be overwritten with the newly provided version. +func SetOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) error { + // Validate the owner. + ro, ok := owner.(runtime.Object) + if !ok { + return fmt.Errorf("%T is not a runtime.Object, cannot call SetOwnerReference", owner) + } + if err := validateOwner(owner, object); err != nil { + return err + } + + // Create a new owner ref. + gvk, err := apiutil.GVKForObject(ro, scheme) + if err != nil { + return err + } + ref := metav1.OwnerReference{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, + UID: owner.GetUID(), + Name: owner.GetName(), + } + + // Update owner references and return. + upsertOwnerRef(ref, object) + return nil +} + +// RemoveOwnerReference is a helper method to make sure the given object removes an owner reference to the object provided. +// This allows you to remove the owner to establish a new owner of the object in a subsequent call. +func RemoveOwnerReference(owner, object metav1.Object, scheme *runtime.Scheme) error { + owners := object.GetOwnerReferences() + length := len(owners) + if length < 1 { + return fmt.Errorf("%T does not have any owner references", object) + } + ro, ok := owner.(runtime.Object) + if !ok { + return fmt.Errorf("%T is not a runtime.Object, cannot call RemoveOwnerReference", owner) + } + gvk, err := apiutil.GVKForObject(ro, scheme) + if err != nil { + return err + } + + index := indexOwnerRef(owners, metav1.OwnerReference{ + APIVersion: gvk.GroupVersion().String(), + Name: owner.GetName(), + Kind: gvk.Kind, + }) + if index == -1 { + return fmt.Errorf("%T does not have an owner reference for %T", object, owner) + } + + owners = append(owners[:index], owners[index+1:]...) + object.SetOwnerReferences(owners) + return nil +} + +// HasControllerReference returns true if the object +// has an owner ref with controller equal to true +func HasControllerReference(object metav1.Object) bool { + owners := object.GetOwnerReferences() + for _, owner := range owners { + isTrue := owner.Controller + if owner.Controller != nil && *isTrue { + return true + } + } + return false +} + +// RemoveControllerReference removes an owner reference where the controller +// equals true +func RemoveControllerReference(owner, object metav1.Object, scheme *runtime.Scheme) error { + if ok := HasControllerReference(object); !ok { + return fmt.Errorf("%T does not have a owner reference with controller equals true", object) + } + ro, ok := owner.(runtime.Object) + if !ok { + return fmt.Errorf("%T is not a runtime.Object, cannot call RemoveControllerReference", owner) + } + gvk, err := apiutil.GVKForObject(ro, scheme) + if err != nil { + return err + } + ownerRefs := object.GetOwnerReferences() + index := indexOwnerRef(ownerRefs, metav1.OwnerReference{ + APIVersion: gvk.GroupVersion().String(), + Name: owner.GetName(), + Kind: gvk.Kind, + }) + + if index == -1 { + return fmt.Errorf("%T does not have an controller reference for %T", object, owner) + } + + if ownerRefs[index].Controller == nil || !*ownerRefs[index].Controller { + return fmt.Errorf("%T owner is not the controller reference for %T", owner, object) + } + + ownerRefs = append(ownerRefs[:index], ownerRefs[index+1:]...) + object.SetOwnerReferences(ownerRefs) + return nil +} + +func upsertOwnerRef(ref metav1.OwnerReference, object metav1.Object) { + owners := object.GetOwnerReferences() + if idx := indexOwnerRef(owners, ref); idx == -1 { + owners = append(owners, ref) + } else { + owners[idx] = ref + } + object.SetOwnerReferences(owners) +} + +// indexOwnerRef returns the index of the owner reference in the slice if found, or -1. +func indexOwnerRef(ownerReferences []metav1.OwnerReference, ref metav1.OwnerReference) int { + for index, r := range ownerReferences { + if referSameObject(r, ref) { + return index + } + } + return -1 +} + +func validateOwner(owner, object metav1.Object) error { + ownerNs := owner.GetNamespace() + if ownerNs != "" { + objNs := object.GetNamespace() + if objNs == "" { + return fmt.Errorf("cluster-scoped resource must not have a namespace-scoped owner, owner's namespace %s", ownerNs) + } + if ownerNs != objNs { + return fmt.Errorf("cross-namespace owner references are disallowed, owner's namespace %s, obj's namespace %s", owner.GetNamespace(), object.GetNamespace()) + } + } + return nil +} + +// Returns true if a and b point to the same object. +func referSameObject(a, b metav1.OwnerReference) bool { + aGV, err := schema.ParseGroupVersion(a.APIVersion) + if err != nil { + return false + } + + bGV, err := schema.ParseGroupVersion(b.APIVersion) + if err != nil { + return false + } + return aGV.Group == bGV.Group && a.Kind == b.Kind && a.Name == b.Name +} + +// OperationResult is the action result of a CreateOrUpdate call. +type OperationResult string + +const ( // They should complete the sentence "Deployment default/foo has been ..." + // OperationResultNone means that the resource has not been changed. + OperationResultNone OperationResult = "unchanged" + // OperationResultCreated means that a new resource is created. + OperationResultCreated OperationResult = "created" + // OperationResultUpdated means that an existing resource is updated. + OperationResultUpdated OperationResult = "updated" + // OperationResultUpdatedStatus means that an existing resource and its status is updated. + OperationResultUpdatedStatus OperationResult = "updatedStatus" + // OperationResultUpdatedStatusOnly means that only an existing status is updated. + OperationResultUpdatedStatusOnly OperationResult = "updatedStatusOnly" +) + +// CreateOrUpdate creates or updates the given object in the Kubernetes +// cluster. The object's desired state must be reconciled with the existing +// state inside the passed in callback MutateFn. +// +// The MutateFn is called regardless of creating or updating an object. +// +// It returns the executed operation and an error. +// +// Note: changes made by MutateFn to any sub-resource (status...), will be +// discarded. +func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) { + key := client.ObjectKeyFromObject(obj) + if err := c.Get(ctx, key, obj); err != nil { + if !apierrors.IsNotFound(err) { + return OperationResultNone, err + } + if err := mutate(f, key, obj); err != nil { + return OperationResultNone, err + } + if err := c.Create(ctx, obj); err != nil { + return OperationResultNone, err + } + return OperationResultCreated, nil + } + + existing := obj.DeepCopyObject() + if err := mutate(f, key, obj); err != nil { + return OperationResultNone, err + } + + if equality.Semantic.DeepEqual(existing, obj) { + return OperationResultNone, nil + } + + if err := c.Update(ctx, obj); err != nil { + return OperationResultNone, err + } + return OperationResultUpdated, nil +} + +// CreateOrPatch creates or patches the given object in the Kubernetes +// cluster. The object's desired state must be reconciled with the before +// state inside the passed in callback MutateFn. +// +// The MutateFn is called regardless of creating or updating an object. +// +// It returns the executed operation and an error. +// +// Note: changes to any sub-resource other than status will be ignored. +// Changes to the status sub-resource will only be applied if the object +// already exist. To change the status on object creation, the easiest +// way is to requeue the object in the controller if OperationResult is +// OperationResultCreated +func CreateOrPatch(ctx context.Context, c client.Client, obj client.Object, f MutateFn) (OperationResult, error) { + key := client.ObjectKeyFromObject(obj) + if err := c.Get(ctx, key, obj); err != nil { + if !apierrors.IsNotFound(err) { + return OperationResultNone, err + } + if f != nil { + if err := mutate(f, key, obj); err != nil { + return OperationResultNone, err + } + } + if err := c.Create(ctx, obj); err != nil { + return OperationResultNone, err + } + return OperationResultCreated, nil + } + + // Create patches for the object and its possible status. + objPatch := client.MergeFrom(obj.DeepCopyObject().(client.Object)) + statusPatch := client.MergeFrom(obj.DeepCopyObject().(client.Object)) + + // Create a copy of the original object as well as converting that copy to + // unstructured data. + before, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj.DeepCopyObject()) + if err != nil { + return OperationResultNone, err + } + + // Attempt to extract the status from the resource for easier comparison later + beforeStatus, hasBeforeStatus, err := unstructured.NestedFieldCopy(before, "status") + if err != nil { + return OperationResultNone, err + } + + // If the resource contains a status then remove it from the unstructured + // copy to avoid unnecessary patching later. + if hasBeforeStatus { + unstructured.RemoveNestedField(before, "status") + } + + // Mutate the original object. + if f != nil { + if err := mutate(f, key, obj); err != nil { + return OperationResultNone, err + } + } + + // Convert the resource to unstructured to compare against our before copy. + after, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return OperationResultNone, err + } + + // Attempt to extract the status from the resource for easier comparison later + afterStatus, hasAfterStatus, err := unstructured.NestedFieldCopy(after, "status") + if err != nil { + return OperationResultNone, err + } + + // If the resource contains a status then remove it from the unstructured + // copy to avoid unnecessary patching later. + if hasAfterStatus { + unstructured.RemoveNestedField(after, "status") + } + + result := OperationResultNone + + if !reflect.DeepEqual(before, after) { + // Only issue a Patch if the before and after resources (minus status) differ + if err := c.Patch(ctx, obj, objPatch); err != nil { + return result, err + } + result = OperationResultUpdated + } + + if (hasBeforeStatus || hasAfterStatus) && !reflect.DeepEqual(beforeStatus, afterStatus) { + // Only issue a Status Patch if the resource has a status and the beforeStatus + // and afterStatus copies differ + if result == OperationResultUpdated { + // If Status was replaced by Patch before, set it to afterStatus + objectAfterPatch, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return result, err + } + if err = unstructured.SetNestedField(objectAfterPatch, afterStatus, "status"); err != nil { + return result, err + } + // If Status was replaced by Patch before, restore patched structure to the obj + if err = runtime.DefaultUnstructuredConverter.FromUnstructured(objectAfterPatch, obj); err != nil { + return result, err + } + } + if err := c.Status().Patch(ctx, obj, statusPatch); err != nil { + return result, err + } + if result == OperationResultUpdated { + result = OperationResultUpdatedStatus + } else { + result = OperationResultUpdatedStatusOnly + } + } + + return result, nil +} + +// mutate wraps a MutateFn and applies validation to its result. +func mutate(f MutateFn, key client.ObjectKey, obj client.Object) error { + if err := f(); err != nil { + return err + } + if newKey := client.ObjectKeyFromObject(obj); key != newKey { + return fmt.Errorf("MutateFn cannot mutate object name and/or object namespace") + } + return nil +} + +// MutateFn is a function which mutates the existing object into its desired state. +type MutateFn func() error + +// AddFinalizer accepts an Object and adds the provided finalizer if not present. +// It returns an indication of whether it updated the object's list of finalizers. +func AddFinalizer(o client.Object, finalizer string) (finalizersUpdated bool) { + f := o.GetFinalizers() + for _, e := range f { + if e == finalizer { + return false + } + } + o.SetFinalizers(append(f, finalizer)) + return true +} + +// RemoveFinalizer accepts an Object and removes the provided finalizer if present. +// It returns an indication of whether it updated the object's list of finalizers. +func RemoveFinalizer(o client.Object, finalizer string) (finalizersUpdated bool) { + f := o.GetFinalizers() + length := len(f) + + index := 0 + for i := 0; i < length; i++ { + if f[i] == finalizer { + continue + } + f[index] = f[i] + index++ + } + o.SetFinalizers(f[:index]) + return length != index +} + +// ContainsFinalizer checks an Object that the provided finalizer is present. +func ContainsFinalizer(o client.Object, finalizer string) bool { + f := o.GetFinalizers() + for _, e := range f { + if e == finalizer { + return true + } + } + return false +} diff --git a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/doc.go similarity index 76% rename from pkg/client/clientset/versioned/typed/kubebind/v1alpha1/doc.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/doc.go index 05ebc8af..ab386b29 100644 --- a/pkg/client/clientset/versioned/typed/kubebind/v1alpha1/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kube Bind Authors. +Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated typed clients. -package v1alpha1 +/* +Package controllerutil contains utility functions for working with and implementing Controllers. +*/ +package controllerutil diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go new file mode 100644 index 00000000..228335e9 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go @@ -0,0 +1,25 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package controller provides types and functions for building Controllers. Controllers implement Kubernetes APIs. + +# Creation + +To create a new Controller, first create a manager.Manager and pass it to the controller.New function. +The Controller MUST be started by calling Manager.Start. +*/ +package controller diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/conversion/conversion.go b/vendor/sigs.k8s.io/controller-runtime/pkg/conversion/conversion.go new file mode 100644 index 00000000..da32ab48 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/conversion/conversion.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +/* +Package conversion provides interface definitions that an API Type needs to +implement for it to be supported by the generic conversion webhook handler +defined under pkg/webhook/conversion. +*/ +package conversion + +import "k8s.io/apimachinery/pkg/runtime" + +// Convertible defines capability of a type to convertible i.e. it can be converted to/from a hub type. +type Convertible interface { + runtime.Object + ConvertTo(dst Hub) error + ConvertFrom(src Hub) error +} + +// Hub marks that a given type is the hub type for conversion. This means that +// all conversions will first convert to the hub type, then convert from the hub +// type to the destination type. All types besides the hub type should implement +// Convertible. +type Hub interface { + runtime.Object + Hub() +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/event/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/event/doc.go new file mode 100644 index 00000000..adba3bbc --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/event/doc.go @@ -0,0 +1,28 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package event contains the definitions for the Event types produced by source.Sources and transformed into +reconcile.Requests by handler.EventHandler. + +You should rarely need to work with these directly -- instead, use Controller.Watch with +source.Sources and handler.EventHandlers. + +Events generally contain both a full runtime.Object that caused the event, as well +as a direct handle to that object's metadata. This saves a lot of typecasting in +code that works with Events. +*/ +package event diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/event/event.go b/vendor/sigs.k8s.io/controller-runtime/pkg/event/event.go new file mode 100644 index 00000000..271b3c00 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/event/event.go @@ -0,0 +1,55 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package event + +import "sigs.k8s.io/controller-runtime/pkg/client" + +// CreateEvent is an event where a Kubernetes object was created. CreateEvent should be generated +// by a source.Source and transformed into a reconcile.Request by an handler.EventHandler. +type CreateEvent struct { + // Object is the object from the event + Object client.Object +} + +// UpdateEvent is an event where a Kubernetes object was updated. UpdateEvent should be generated +// by a source.Source and transformed into a reconcile.Request by an handler.EventHandler. +type UpdateEvent struct { + // ObjectOld is the object from the event + ObjectOld client.Object + + // ObjectNew is the object from the event + ObjectNew client.Object +} + +// DeleteEvent is an event where a Kubernetes object was deleted. DeleteEvent should be generated +// by a source.Source and transformed into a reconcile.Request by an handler.EventHandler. +type DeleteEvent struct { + // Object is the object from the event + Object client.Object + + // DeleteStateUnknown is true if the Delete event was missed but we identified the object + // as having been deleted. + DeleteStateUnknown bool +} + +// GenericEvent is an event where the operation type is unknown (e.g. polling or event originating outside the cluster). +// GenericEvent should be generated by a source.Source and transformed into a reconcile.Request by an +// handler.EventHandler. +type GenericEvent struct { + // Object is the object from the event + Object client.Object +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go new file mode 100644 index 00000000..e5fd177a --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go @@ -0,0 +1,38 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package handler defines EventHandlers that enqueue reconcile.Requests in response to Create, Update, Deletion Events +observed from Watching Kubernetes APIs. Users should provide a source.Source and handler.EventHandler to +Controller.Watch in order to generate and enqueue reconcile.Request work items. + +Generally, following premade event handlers should be sufficient for most use cases: + +EventHandlers: + +EnqueueRequestForObject - Enqueues a reconcile.Request containing the Name and Namespace of the object in the Event. This will +cause the object that was the source of the Event (e.g. the created / deleted / updated object) to be +reconciled. + +EnqueueRequestForOwner - Enqueues a reconcile.Request containing the Name and Namespace of the Owner of the object in the Event. +This will cause owner of the object that was the source of the Event (e.g. the owner object that created the object) +to be reconciled. + +EnqueueRequestsFromMapFunc - Enqueues reconcile.Requests resulting from a user provided transformation function run against the +object in the Event. This will cause an arbitrary collection of objects (defined from a transformation of the +source object) to be reconciled. +*/ +package handler diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go new file mode 100644 index 00000000..c72b2e1e --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue.go @@ -0,0 +1,92 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package handler + +import ( + "context" + + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/event" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var enqueueLog = logf.RuntimeLog.WithName("eventhandler").WithName("EnqueueRequestForObject") + +type empty struct{} + +var _ EventHandler = &EnqueueRequestForObject{} + +// EnqueueRequestForObject enqueues a Request containing the Name and Namespace of the object that is the source of the Event. +// (e.g. the created / deleted / updated objects Name and Namespace). handler.EnqueueRequestForObject is used by almost all +// Controllers that have associated Resources (e.g. CRDs) to reconcile the associated Resource. +type EnqueueRequestForObject struct{} + +// Create implements EventHandler. +func (e *EnqueueRequestForObject) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { + if evt.Object == nil { + enqueueLog.Error(nil, "CreateEvent received with no metadata", "event", evt) + return + } + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.Object.GetName(), + Namespace: evt.Object.GetNamespace(), + }}) +} + +// Update implements EventHandler. +func (e *EnqueueRequestForObject) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { + switch { + case evt.ObjectNew != nil: + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.ObjectNew.GetName(), + Namespace: evt.ObjectNew.GetNamespace(), + }}) + case evt.ObjectOld != nil: + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.ObjectOld.GetName(), + Namespace: evt.ObjectOld.GetNamespace(), + }}) + default: + enqueueLog.Error(nil, "UpdateEvent received with no metadata", "event", evt) + } +} + +// Delete implements EventHandler. +func (e *EnqueueRequestForObject) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + if evt.Object == nil { + enqueueLog.Error(nil, "DeleteEvent received with no metadata", "event", evt) + return + } + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.Object.GetName(), + Namespace: evt.Object.GetNamespace(), + }}) +} + +// Generic implements EventHandler. +func (e *EnqueueRequestForObject) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { + if evt.Object == nil { + enqueueLog.Error(nil, "GenericEvent received with no metadata", "event", evt) + return + } + q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ + Name: evt.Object.GetName(), + Namespace: evt.Object.GetNamespace(), + }}) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go new file mode 100644 index 00000000..b55fdde6 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_mapped.go @@ -0,0 +1,88 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package handler + +import ( + "context" + + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// MapFunc is the signature required for enqueueing requests from a generic function. +// This type is usually used with EnqueueRequestsFromMapFunc when registering an event handler. +type MapFunc func(context.Context, client.Object) []reconcile.Request + +// EnqueueRequestsFromMapFunc enqueues Requests by running a transformation function that outputs a collection +// of reconcile.Requests on each Event. The reconcile.Requests may be for an arbitrary set of objects +// defined by some user specified transformation of the source Event. (e.g. trigger Reconciler for a set of objects +// in response to a cluster resize event caused by adding or deleting a Node) +// +// EnqueueRequestsFromMapFunc is frequently used to fan-out updates from one object to one or more other +// objects of a differing type. +// +// For UpdateEvents which contain both a new and old object, the transformation function is run on both +// objects and both sets of Requests are enqueue. +func EnqueueRequestsFromMapFunc(fn MapFunc) EventHandler { + return &enqueueRequestsFromMapFunc{ + toRequests: fn, + } +} + +var _ EventHandler = &enqueueRequestsFromMapFunc{} + +type enqueueRequestsFromMapFunc struct { + // Mapper transforms the argument into a slice of keys to be reconciled + toRequests MapFunc +} + +// Create implements EventHandler. +func (e *enqueueRequestsFromMapFunc) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.mapAndEnqueue(ctx, q, evt.Object, reqs) +} + +// Update implements EventHandler. +func (e *enqueueRequestsFromMapFunc) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.mapAndEnqueue(ctx, q, evt.ObjectOld, reqs) + e.mapAndEnqueue(ctx, q, evt.ObjectNew, reqs) +} + +// Delete implements EventHandler. +func (e *enqueueRequestsFromMapFunc) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.mapAndEnqueue(ctx, q, evt.Object, reqs) +} + +// Generic implements EventHandler. +func (e *enqueueRequestsFromMapFunc) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.mapAndEnqueue(ctx, q, evt.Object, reqs) +} + +func (e *enqueueRequestsFromMapFunc) mapAndEnqueue(ctx context.Context, q workqueue.RateLimitingInterface, object client.Object, reqs map[reconcile.Request]empty) { + for _, req := range e.toRequests(ctx, object) { + _, ok := reqs[req] + if !ok { + q.Add(req) + reqs[req] = empty{} + } + } +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go new file mode 100644 index 00000000..02e7d756 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/enqueue_owner.go @@ -0,0 +1,199 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package handler + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var _ EventHandler = &enqueueRequestForOwner{} + +var log = logf.RuntimeLog.WithName("eventhandler").WithName("enqueueRequestForOwner") + +// OwnerOption modifies an EnqueueRequestForOwner EventHandler. +type OwnerOption func(e *enqueueRequestForOwner) + +// EnqueueRequestForOwner enqueues Requests for the Owners of an object. E.g. the object that created +// the object that was the source of the Event. +// +// If a ReplicaSet creates Pods, users may reconcile the ReplicaSet in response to Pod Events using: +// +// - a source.Kind Source with Type of Pod. +// +// - a handler.enqueueRequestForOwner EventHandler with an OwnerType of ReplicaSet and OnlyControllerOwner set to true. +func EnqueueRequestForOwner(scheme *runtime.Scheme, mapper meta.RESTMapper, ownerType client.Object, opts ...OwnerOption) EventHandler { + e := &enqueueRequestForOwner{ + ownerType: ownerType, + mapper: mapper, + } + if err := e.parseOwnerTypeGroupKind(scheme); err != nil { + panic(err) + } + for _, opt := range opts { + opt(e) + } + return e +} + +// OnlyControllerOwner if provided will only look at the first OwnerReference with Controller: true. +func OnlyControllerOwner() OwnerOption { + return func(e *enqueueRequestForOwner) { + e.isController = true + } +} + +type enqueueRequestForOwner struct { + // ownerType is the type of the Owner object to look for in OwnerReferences. Only Group and Kind are compared. + ownerType runtime.Object + + // isController if set will only look at the first OwnerReference with Controller: true. + isController bool + + // groupKind is the cached Group and Kind from OwnerType + groupKind schema.GroupKind + + // mapper maps GroupVersionKinds to Resources + mapper meta.RESTMapper +} + +// Create implements EventHandler. +func (e *enqueueRequestForOwner) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.getOwnerReconcileRequest(evt.Object, reqs) + for req := range reqs { + q.Add(req) + } +} + +// Update implements EventHandler. +func (e *enqueueRequestForOwner) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.getOwnerReconcileRequest(evt.ObjectOld, reqs) + e.getOwnerReconcileRequest(evt.ObjectNew, reqs) + for req := range reqs { + q.Add(req) + } +} + +// Delete implements EventHandler. +func (e *enqueueRequestForOwner) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.getOwnerReconcileRequest(evt.Object, reqs) + for req := range reqs { + q.Add(req) + } +} + +// Generic implements EventHandler. +func (e *enqueueRequestForOwner) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { + reqs := map[reconcile.Request]empty{} + e.getOwnerReconcileRequest(evt.Object, reqs) + for req := range reqs { + q.Add(req) + } +} + +// parseOwnerTypeGroupKind parses the OwnerType into a Group and Kind and caches the result. Returns false +// if the OwnerType could not be parsed using the scheme. +func (e *enqueueRequestForOwner) parseOwnerTypeGroupKind(scheme *runtime.Scheme) error { + // Get the kinds of the type + kinds, _, err := scheme.ObjectKinds(e.ownerType) + if err != nil { + log.Error(err, "Could not get ObjectKinds for OwnerType", "owner type", fmt.Sprintf("%T", e.ownerType)) + return err + } + // Expect only 1 kind. If there is more than one kind this is probably an edge case such as ListOptions. + if len(kinds) != 1 { + err := fmt.Errorf("expected exactly 1 kind for OwnerType %T, but found %s kinds", e.ownerType, kinds) + log.Error(nil, "expected exactly 1 kind for OwnerType", "owner type", fmt.Sprintf("%T", e.ownerType), "kinds", kinds) + return err + } + // Cache the Group and Kind for the OwnerType + e.groupKind = schema.GroupKind{Group: kinds[0].Group, Kind: kinds[0].Kind} + return nil +} + +// getOwnerReconcileRequest looks at object and builds a map of reconcile.Request to reconcile +// owners of object that match e.OwnerType. +func (e *enqueueRequestForOwner) getOwnerReconcileRequest(object metav1.Object, result map[reconcile.Request]empty) { + // Iterate through the OwnerReferences looking for a match on Group and Kind against what was requested + // by the user + for _, ref := range e.getOwnersReferences(object) { + // Parse the Group out of the OwnerReference to compare it to what was parsed out of the requested OwnerType + refGV, err := schema.ParseGroupVersion(ref.APIVersion) + if err != nil { + log.Error(err, "Could not parse OwnerReference APIVersion", + "api version", ref.APIVersion) + return + } + + // Compare the OwnerReference Group and Kind against the OwnerType Group and Kind specified by the user. + // If the two match, create a Request for the objected referred to by + // the OwnerReference. Use the Name from the OwnerReference and the Namespace from the + // object in the event. + if ref.Kind == e.groupKind.Kind && refGV.Group == e.groupKind.Group { + // Match found - add a Request for the object referred to in the OwnerReference + request := reconcile.Request{NamespacedName: types.NamespacedName{ + Name: ref.Name, + }} + + // if owner is not namespaced then we should not set the namespace + mapping, err := e.mapper.RESTMapping(e.groupKind, refGV.Version) + if err != nil { + log.Error(err, "Could not retrieve rest mapping", "kind", e.groupKind) + return + } + if mapping.Scope.Name() != meta.RESTScopeNameRoot { + request.Namespace = object.GetNamespace() + } + + result[request] = empty{} + } + } +} + +// getOwnersReferences returns the OwnerReferences for an object as specified by the enqueueRequestForOwner +// - if IsController is true: only take the Controller OwnerReference (if found) +// - if IsController is false: take all OwnerReferences. +func (e *enqueueRequestForOwner) getOwnersReferences(object metav1.Object) []metav1.OwnerReference { + if object == nil { + return nil + } + + // If not filtered as Controller only, then use all the OwnerReferences + if !e.isController { + return object.GetOwnerReferences() + } + // If filtered to a Controller, only take the Controller OwnerReference + if ownerRef := metav1.GetControllerOf(object); ownerRef != nil { + return []metav1.OwnerReference{*ownerRef} + } + // No Controller OwnerReference found + return nil +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go new file mode 100644 index 00000000..ff2f3e80 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/handler/eventhandler.go @@ -0,0 +1,106 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package handler + +import ( + "context" + + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/event" +) + +// EventHandler enqueues reconcile.Requests in response to events (e.g. Pod Create). EventHandlers map an Event +// for one object to trigger Reconciles for either the same object or different objects - e.g. if there is an +// Event for object with type Foo (using source.KindSource) then reconcile one or more object(s) with type Bar. +// +// Identical reconcile.Requests will be batched together through the queuing mechanism before reconcile is called. +// +// * Use EnqueueRequestForObject to reconcile the object the event is for +// - do this for events for the type the Controller Reconciles. (e.g. Deployment for a Deployment Controller) +// +// * Use EnqueueRequestForOwner to reconcile the owner of the object the event is for +// - do this for events for the types the Controller creates. (e.g. ReplicaSets created by a Deployment Controller) +// +// * Use EnqueueRequestsFromMapFunc to transform an event for an object to a reconcile of an object +// of a different type - do this for events for types the Controller may be interested in, but doesn't create. +// (e.g. If Foo responds to cluster size events, map Node events to Foo objects.) +// +// Unless you are implementing your own EventHandler, you can ignore the functions on the EventHandler interface. +// Most users shouldn't need to implement their own EventHandler. +type EventHandler interface { + // Create is called in response to a create event - e.g. Pod Creation. + Create(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) + + // Update is called in response to an update event - e.g. Pod Updated. + Update(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) + + // Delete is called in response to a delete event - e.g. Pod Deleted. + Delete(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) + + // Generic is called in response to an event of an unknown type or a synthetic event triggered as a cron or + // external trigger request - e.g. reconcile Autoscaling, or a Webhook. + Generic(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) +} + +var _ EventHandler = Funcs{} + +// Funcs implements EventHandler. +type Funcs struct { + // Create is called in response to an add event. Defaults to no-op. + // RateLimitingInterface is used to enqueue reconcile.Requests. + CreateFunc func(context.Context, event.CreateEvent, workqueue.RateLimitingInterface) + + // Update is called in response to an update event. Defaults to no-op. + // RateLimitingInterface is used to enqueue reconcile.Requests. + UpdateFunc func(context.Context, event.UpdateEvent, workqueue.RateLimitingInterface) + + // Delete is called in response to a delete event. Defaults to no-op. + // RateLimitingInterface is used to enqueue reconcile.Requests. + DeleteFunc func(context.Context, event.DeleteEvent, workqueue.RateLimitingInterface) + + // GenericFunc is called in response to a generic event. Defaults to no-op. + // RateLimitingInterface is used to enqueue reconcile.Requests. + GenericFunc func(context.Context, event.GenericEvent, workqueue.RateLimitingInterface) +} + +// Create implements EventHandler. +func (h Funcs) Create(ctx context.Context, e event.CreateEvent, q workqueue.RateLimitingInterface) { + if h.CreateFunc != nil { + h.CreateFunc(ctx, e, q) + } +} + +// Delete implements EventHandler. +func (h Funcs) Delete(ctx context.Context, e event.DeleteEvent, q workqueue.RateLimitingInterface) { + if h.DeleteFunc != nil { + h.DeleteFunc(ctx, e, q) + } +} + +// Update implements EventHandler. +func (h Funcs) Update(ctx context.Context, e event.UpdateEvent, q workqueue.RateLimitingInterface) { + if h.UpdateFunc != nil { + h.UpdateFunc(ctx, e, q) + } +} + +// Generic implements EventHandler. +func (h Funcs) Generic(ctx context.Context, e event.GenericEvent, q workqueue.RateLimitingInterface) { + if h.GenericFunc != nil { + h.GenericFunc(ctx, e, q) + } +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/doc.go new file mode 100644 index 00000000..9827eeaf --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/doc.go @@ -0,0 +1,32 @@ +/* +Copyright 2014 The Kubernetes Authors. + +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. +*/ + +// Package healthz contains helpers from supporting liveness and readiness endpoints. +// (often referred to as healthz and readyz, respectively). +// +// This package draws heavily from the apiserver's healthz package +// ( https://github.com/kubernetes/apiserver/tree/master/pkg/server/healthz ) +// but has some changes to bring it in line with controller-runtime's style. +// +// The main entrypoint is the Handler -- this serves both aggregated health status +// and individual health check endpoints. +package healthz + +import ( + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("healthz") diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go b/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go new file mode 100644 index 00000000..cfb5dc8d --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go @@ -0,0 +1,206 @@ +/* +Copyright 2014 The Kubernetes Authors. + +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. +*/ + +package healthz + +import ( + "fmt" + "net/http" + "path" + "sort" + "strings" + + "k8s.io/apimachinery/pkg/util/sets" +) + +// Handler is an http.Handler that aggregates the results of the given +// checkers to the root path, and supports calling individual checkers on +// subpaths of the name of the checker. +// +// Adding checks on the fly is *not* threadsafe -- use a wrapper. +type Handler struct { + Checks map[string]Checker +} + +// checkStatus holds the output of a particular check. +type checkStatus struct { + name string + healthy bool + excluded bool +} + +func (h *Handler) serveAggregated(resp http.ResponseWriter, req *http.Request) { + failed := false + excluded := getExcludedChecks(req) + + parts := make([]checkStatus, 0, len(h.Checks)) + + // calculate the results... + for checkName, check := range h.Checks { + // no-op the check if we've specified we want to exclude the check + if excluded.Has(checkName) { + excluded.Delete(checkName) + parts = append(parts, checkStatus{name: checkName, healthy: true, excluded: true}) + continue + } + if err := check(req); err != nil { + log.V(1).Info("healthz check failed", "checker", checkName, "error", err) + parts = append(parts, checkStatus{name: checkName, healthy: false}) + failed = true + } else { + parts = append(parts, checkStatus{name: checkName, healthy: true}) + } + } + + // ...default a check if none is present... + if len(h.Checks) == 0 { + parts = append(parts, checkStatus{name: "ping", healthy: true}) + } + + for _, c := range excluded.UnsortedList() { + log.V(1).Info("cannot exclude health check, no matches for it", "checker", c) + } + + // ...sort to be consistent... + sort.Slice(parts, func(i, j int) bool { return parts[i].name < parts[j].name }) + + // ...and write out the result + // TODO(directxman12): this should also accept a request for JSON content (via a accept header) + _, forceVerbose := req.URL.Query()["verbose"] + writeStatusesAsText(resp, parts, excluded, failed, forceVerbose) +} + +// writeStatusAsText writes out the given check statuses in some semi-arbitrary +// bespoke text format that we copied from Kubernetes. unknownExcludes lists +// any checks that the user requested to have excluded, but weren't actually +// known checks. writeStatusAsText is always verbose on failure, and can be +// forced to be verbose on success using the given argument. +func writeStatusesAsText(resp http.ResponseWriter, parts []checkStatus, unknownExcludes sets.Set[string], failed, forceVerbose bool) { + resp.Header().Set("Content-Type", "text/plain; charset=utf-8") + resp.Header().Set("X-Content-Type-Options", "nosniff") + + // always write status code first + if failed { + resp.WriteHeader(http.StatusInternalServerError) + } else { + resp.WriteHeader(http.StatusOK) + } + + // shortcut for easy non-verbose success + if !failed && !forceVerbose { + fmt.Fprint(resp, "ok") + return + } + + // we're always verbose on failure, so from this point on we're guaranteed to be verbose + + for _, checkOut := range parts { + switch { + case checkOut.excluded: + fmt.Fprintf(resp, "[+]%s excluded: ok\n", checkOut.name) + case checkOut.healthy: + fmt.Fprintf(resp, "[+]%s ok\n", checkOut.name) + default: + // don't include the error since this endpoint is public. If someone wants more detail + // they should have explicit permission to the detailed checks. + fmt.Fprintf(resp, "[-]%s failed: reason withheld\n", checkOut.name) + } + } + + if unknownExcludes.Len() > 0 { + fmt.Fprintf(resp, "warn: some health checks cannot be excluded: no matches for %s\n", formatQuoted(unknownExcludes.UnsortedList()...)) + } + + if failed { + log.Info("healthz check failed", "statuses", parts) + fmt.Fprintf(resp, "healthz check failed\n") + } else { + fmt.Fprint(resp, "healthz check passed\n") + } +} + +func (h *Handler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + // clean up the request (duplicating the internal logic of http.ServeMux a bit) + // clean up the path a bit + reqPath := req.URL.Path + if reqPath == "" || reqPath[0] != '/' { + reqPath = "/" + reqPath + } + // path.Clean removes the trailing slash except for root for us + // (which is fine, since we're only serving one layer of sub-paths) + reqPath = path.Clean(reqPath) + + // either serve the root endpoint... + if reqPath == "/" { + h.serveAggregated(resp, req) + return + } + + // ...the default check (if nothing else is present)... + if len(h.Checks) == 0 && reqPath[1:] == "ping" { + CheckHandler{Checker: Ping}.ServeHTTP(resp, req) + return + } + + // ...or an individual checker + checkName := reqPath[1:] // ignore the leading slash + checker, known := h.Checks[checkName] + if !known { + http.NotFoundHandler().ServeHTTP(resp, req) + return + } + + CheckHandler{Checker: checker}.ServeHTTP(resp, req) +} + +// CheckHandler is an http.Handler that serves a health check endpoint at the root path, +// based on its checker. +type CheckHandler struct { + Checker +} + +func (h CheckHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + if err := h.Checker(req); err != nil { + http.Error(resp, fmt.Sprintf("internal server error: %v", err), http.StatusInternalServerError) + } else { + fmt.Fprint(resp, "ok") + } +} + +// Checker knows how to perform a health check. +type Checker func(req *http.Request) error + +// Ping returns true automatically when checked. +var Ping Checker = func(_ *http.Request) error { return nil } + +// getExcludedChecks extracts the health check names to be excluded from the query param. +func getExcludedChecks(r *http.Request) sets.Set[string] { + checks, found := r.URL.Query()["exclude"] + if found { + return sets.New[string](checks...) + } + return sets.New[string]() +} + +// formatQuoted returns a formatted string of the health check names, +// preserving the order passed in. +func formatQuoted(names ...string) string { + quoted := make([]string, 0, len(names)) + for _, name := range names { + quoted = append(quoted, fmt.Sprintf("%q", name)) + } + return strings.Join(quoted, ",") +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go new file mode 100644 index 00000000..33883647 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go @@ -0,0 +1,378 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package controller + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/types" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/client-go/util/workqueue" + + "sigs.k8s.io/controller-runtime/pkg/handler" + ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +// Controller implements controller.Controller. +type Controller struct { + // Name is used to uniquely identify a Controller in tracing, logging and monitoring. Name is required. + Name string + + // MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1. + MaxConcurrentReconciles int + + // Reconciler is a function that can be called at any time with the Name / Namespace of an object and + // ensures that the state of the system matches the state specified in the object. + // Defaults to the DefaultReconcileFunc. + Do reconcile.Reconciler + + // MakeQueue constructs the queue for this controller once the controller is ready to start. + // This exists because the standard Kubernetes workqueues start themselves immediately, which + // leads to goroutine leaks if something calls controller.New repeatedly. + MakeQueue func() workqueue.RateLimitingInterface + + // Queue is an listeningQueue that listens for events from Informers and adds object keys to + // the Queue for processing + Queue workqueue.RateLimitingInterface + + // mu is used to synchronize Controller setup + mu sync.Mutex + + // Started is true if the Controller has been Started + Started bool + + // ctx is the context that was passed to Start() and used when starting watches. + // + // According to the docs, contexts should not be stored in a struct: https://golang.org/pkg/context, + // while we usually always strive to follow best practices, we consider this a legacy case and it should + // undergo a major refactoring and redesign to allow for context to not be stored in a struct. + ctx context.Context + + // CacheSyncTimeout refers to the time limit set on waiting for cache to sync + // Defaults to 2 minutes if not set. + CacheSyncTimeout time.Duration + + // startWatches maintains a list of sources, handlers, and predicates to start when the controller is started. + startWatches []watchDescription + + // LogConstructor is used to construct a logger to then log messages to users during reconciliation, + // or for example when a watch is started. + // Note: LogConstructor has to be able to handle nil requests as we are also using it + // outside the context of a reconciliation. + LogConstructor func(request *reconcile.Request) logr.Logger + + // RecoverPanic indicates whether the panic caused by reconcile should be recovered. + RecoverPanic *bool + + // LeaderElected indicates whether the controller is leader elected or always running. + LeaderElected *bool +} + +// watchDescription contains all the information necessary to start a watch. +type watchDescription struct { + src source.Source + handler handler.EventHandler + predicates []predicate.Predicate +} + +// Reconcile implements reconcile.Reconciler. +func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, err error) { + defer func() { + if r := recover(); r != nil { + if c.RecoverPanic != nil && *c.RecoverPanic { + for _, fn := range utilruntime.PanicHandlers { + fn(r) + } + err = fmt.Errorf("panic: %v [recovered]", r) + return + } + + log := logf.FromContext(ctx) + log.Info(fmt.Sprintf("Observed a panic in reconciler: %v", r)) + panic(r) + } + }() + return c.Do.Reconcile(ctx, req) +} + +// Watch implements controller.Controller. +func (c *Controller) Watch(src source.Source, evthdler handler.EventHandler, prct ...predicate.Predicate) error { + c.mu.Lock() + defer c.mu.Unlock() + + // Controller hasn't started yet, store the watches locally and return. + // + // These watches are going to be held on the controller struct until the manager or user calls Start(...). + if !c.Started { + c.startWatches = append(c.startWatches, watchDescription{src: src, handler: evthdler, predicates: prct}) + return nil + } + + c.LogConstructor(nil).Info("Starting EventSource", "source", src) + return src.Start(c.ctx, evthdler, c.Queue, prct...) +} + +// NeedLeaderElection implements the manager.LeaderElectionRunnable interface. +func (c *Controller) NeedLeaderElection() bool { + if c.LeaderElected == nil { + return true + } + return *c.LeaderElected +} + +// Start implements controller.Controller. +func (c *Controller) Start(ctx context.Context) error { + // use an IIFE to get proper lock handling + // but lock outside to get proper handling of the queue shutdown + c.mu.Lock() + if c.Started { + return errors.New("controller was started more than once. This is likely to be caused by being added to a manager multiple times") + } + + c.initMetrics() + + // Set the internal context. + c.ctx = ctx + + c.Queue = c.MakeQueue() + go func() { + <-ctx.Done() + c.Queue.ShutDown() + }() + + wg := &sync.WaitGroup{} + err := func() error { + defer c.mu.Unlock() + + // TODO(pwittrock): Reconsider HandleCrash + defer utilruntime.HandleCrash() + + // NB(directxman12): launch the sources *before* trying to wait for the + // caches to sync so that they have a chance to register their intendeded + // caches. + for _, watch := range c.startWatches { + c.LogConstructor(nil).Info("Starting EventSource", "source", fmt.Sprintf("%s", watch.src)) + + if err := watch.src.Start(ctx, watch.handler, c.Queue, watch.predicates...); err != nil { + return err + } + } + + // Start the SharedIndexInformer factories to begin populating the SharedIndexInformer caches + c.LogConstructor(nil).Info("Starting Controller") + + for _, watch := range c.startWatches { + syncingSource, ok := watch.src.(source.SyncingSource) + if !ok { + continue + } + + if err := func() error { + // use a context with timeout for launching sources and syncing caches. + sourceStartCtx, cancel := context.WithTimeout(ctx, c.CacheSyncTimeout) + defer cancel() + + // WaitForSync waits for a definitive timeout, and returns if there + // is an error or a timeout + if err := syncingSource.WaitForSync(sourceStartCtx); err != nil { + err := fmt.Errorf("failed to wait for %s caches to sync: %w", c.Name, err) + c.LogConstructor(nil).Error(err, "Could not wait for Cache to sync") + return err + } + + return nil + }(); err != nil { + return err + } + } + + // All the watches have been started, we can reset the local slice. + // + // We should never hold watches more than necessary, each watch source can hold a backing cache, + // which won't be garbage collected if we hold a reference to it. + c.startWatches = nil + + // Launch workers to process resources + c.LogConstructor(nil).Info("Starting workers", "worker count", c.MaxConcurrentReconciles) + wg.Add(c.MaxConcurrentReconciles) + for i := 0; i < c.MaxConcurrentReconciles; i++ { + go func() { + defer wg.Done() + // Run a worker thread that just dequeues items, processes them, and marks them done. + // It enforces that the reconcileHandler is never invoked concurrently with the same object. + for c.processNextWorkItem(ctx) { + } + }() + } + + c.Started = true + return nil + }() + if err != nil { + return err + } + + <-ctx.Done() + c.LogConstructor(nil).Info("Shutdown signal received, waiting for all workers to finish") + wg.Wait() + c.LogConstructor(nil).Info("All workers finished") + return nil +} + +// processNextWorkItem will read a single work item off the workqueue and +// attempt to process it, by calling the reconcileHandler. +func (c *Controller) processNextWorkItem(ctx context.Context) bool { + obj, shutdown := c.Queue.Get() + if shutdown { + // Stop working + return false + } + + // We call Done here so the workqueue knows we have finished + // processing this item. We also must remember to call Forget if we + // do not want this work item being re-queued. For example, we do + // not call Forget if a transient error occurs, instead the item is + // put back on the workqueue and attempted again after a back-off + // period. + defer c.Queue.Done(obj) + + ctrlmetrics.ActiveWorkers.WithLabelValues(c.Name).Add(1) + defer ctrlmetrics.ActiveWorkers.WithLabelValues(c.Name).Add(-1) + + c.reconcileHandler(ctx, obj) + return true +} + +const ( + labelError = "error" + labelRequeueAfter = "requeue_after" + labelRequeue = "requeue" + labelSuccess = "success" +) + +func (c *Controller) initMetrics() { + ctrlmetrics.ActiveWorkers.WithLabelValues(c.Name).Set(0) + ctrlmetrics.ReconcileErrors.WithLabelValues(c.Name).Add(0) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelError).Add(0) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelRequeueAfter).Add(0) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelRequeue).Add(0) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelSuccess).Add(0) + ctrlmetrics.WorkerCount.WithLabelValues(c.Name).Set(float64(c.MaxConcurrentReconciles)) +} + +func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) { + // Update metrics after processing each item + reconcileStartTS := time.Now() + defer func() { + c.updateMetrics(time.Since(reconcileStartTS)) + }() + + // Make sure that the object is a valid request. + req, ok := obj.(reconcile.Request) + if !ok { + // As the item in the workqueue is actually invalid, we call + // Forget here else we'd go into a loop of attempting to + // process a work item that is invalid. + c.Queue.Forget(obj) + c.LogConstructor(nil).Error(nil, "Queue item was not a Request", "type", fmt.Sprintf("%T", obj), "value", obj) + // Return true, don't take a break + return + } + + log := c.LogConstructor(&req) + reconcileID := uuid.NewUUID() + + log = log.WithValues("reconcileID", reconcileID) + ctx = logf.IntoContext(ctx, log) + ctx = addReconcileID(ctx, reconcileID) + + // RunInformersAndControllers the syncHandler, passing it the Namespace/Name string of the + // resource to be synced. + log.V(5).Info("Reconciling") + result, err := c.Reconcile(ctx, req) + switch { + case err != nil: + if errors.Is(err, reconcile.TerminalError(nil)) { + ctrlmetrics.TerminalReconcileErrors.WithLabelValues(c.Name).Inc() + } else { + c.Queue.AddRateLimited(req) + } + ctrlmetrics.ReconcileErrors.WithLabelValues(c.Name).Inc() + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelError).Inc() + if !result.IsZero() { + log.Info("Warning: Reconciler returned both a non-zero result and a non-nil error. The result will always be ignored if the error is non-nil and the non-nil error causes reqeueuing with exponential backoff. For more details, see: https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/reconcile#Reconciler") + } + log.Error(err, "Reconciler error") + case result.RequeueAfter > 0: + log.V(5).Info(fmt.Sprintf("Reconcile done, requeueing after %s", result.RequeueAfter)) + // The result.RequeueAfter request will be lost, if it is returned + // along with a non-nil error. But this is intended as + // We need to drive to stable reconcile loops before queuing due + // to result.RequestAfter + c.Queue.Forget(obj) + c.Queue.AddAfter(req, result.RequeueAfter) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelRequeueAfter).Inc() + case result.Requeue: + log.V(5).Info("Reconcile done, requeueing") + c.Queue.AddRateLimited(req) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelRequeue).Inc() + default: + log.V(5).Info("Reconcile successful") + // Finally, if no error occurs we Forget this item so it does not + // get queued again until another change happens. + c.Queue.Forget(obj) + ctrlmetrics.ReconcileTotal.WithLabelValues(c.Name, labelSuccess).Inc() + } +} + +// GetLogger returns this controller's logger. +func (c *Controller) GetLogger() logr.Logger { + return c.LogConstructor(nil) +} + +// updateMetrics updates prometheus metrics within the controller. +func (c *Controller) updateMetrics(reconcileTime time.Duration) { + ctrlmetrics.ReconcileTime.WithLabelValues(c.Name).Observe(reconcileTime.Seconds()) +} + +// ReconcileIDFromContext gets the reconcileID from the current context. +func ReconcileIDFromContext(ctx context.Context) types.UID { + r, ok := ctx.Value(reconcileIDKey{}).(types.UID) + if !ok { + return "" + } + + return r +} + +// reconcileIDKey is a context.Context Value key. Its associated value should +// be a types.UID. +type reconcileIDKey struct{} + +func addReconcileID(ctx context.Context, reconcileID types.UID) context.Context { + return context.WithValue(ctx, reconcileIDKey{}, reconcileID) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go new file mode 100644 index 00000000..b74ce062 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics/metrics.go @@ -0,0 +1,86 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/collectors" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + // ReconcileTotal is a prometheus counter metrics which holds the total + // number of reconciliations per controller. It has two labels. controller label refers + // to the controller name and result label refers to the reconcile result i.e + // success, error, requeue, requeue_after. + ReconcileTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "controller_runtime_reconcile_total", + Help: "Total number of reconciliations per controller", + }, []string{"controller", "result"}) + + // ReconcileErrors is a prometheus counter metrics which holds the total + // number of errors from the Reconciler. + ReconcileErrors = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "controller_runtime_reconcile_errors_total", + Help: "Total number of reconciliation errors per controller", + }, []string{"controller"}) + + // TerminalReconcileErrors is a prometheus counter metrics which holds the total + // number of terminal errors from the Reconciler. + TerminalReconcileErrors = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "controller_runtime_terminal_reconcile_errors_total", + Help: "Total number of terminal reconciliation errors per controller", + }, []string{"controller"}) + + // ReconcileTime is a prometheus metric which keeps track of the duration + // of reconciliations. + ReconcileTime = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "controller_runtime_reconcile_time_seconds", + Help: "Length of time per reconciliation per controller", + Buckets: []float64{0.005, 0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60}, + }, []string{"controller"}) + + // WorkerCount is a prometheus metric which holds the number of + // concurrent reconciles per controller. + WorkerCount = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "controller_runtime_max_concurrent_reconciles", + Help: "Maximum number of concurrent reconciles per controller", + }, []string{"controller"}) + + // ActiveWorkers is a prometheus metric which holds the number + // of active workers per controller. + ActiveWorkers = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "controller_runtime_active_workers", + Help: "Number of currently used workers per controller", + }, []string{"controller"}) +) + +func init() { + metrics.Registry.MustRegister( + ReconcileTotal, + ReconcileErrors, + TerminalReconcileErrors, + ReconcileTime, + WorkerCount, + ActiveWorkers, + // expose process metrics like CPU, Memory, file descriptor usage etc. + collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), + // expose Go runtime metrics like GC stats, memory stats etc. + collectors.NewGoCollector(), + ) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go new file mode 100644 index 00000000..8f6dc71e --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go @@ -0,0 +1,37 @@ +/* +Copyright 2022 The Kubernetes Authors. + +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. +*/ + +package selector + +import ( + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/selection" +) + +// RequiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`. +func RequiresExactMatch(sel fields.Selector) bool { + reqs := sel.Requirements() + if len(reqs) == 0 { + return false + } + + for _, req := range reqs { + if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals { + return false + } + } + return true +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/httpserver/server.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/httpserver/server.go new file mode 100644 index 00000000..b5f91f18 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/httpserver/server.go @@ -0,0 +1,16 @@ +package httpserver + +import ( + "net/http" + "time" +) + +// New returns a new server with sane defaults. +func New(handler http.Handler) *http.Server { + return &http.Server{ + Handler: handler, + MaxHeaderBytes: 1 << 20, + IdleTimeout: 90 * time.Second, // matches http.DefaultTransport keep-alive timeout + ReadHeaderTimeout: 32 * time.Second, + } +} diff --git a/hack/tools.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/log/log.go similarity index 64% rename from hack/tools.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/internal/log/log.go index d038d301..d91a0ca5 100644 --- a/hack/tools.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/log/log.go @@ -1,7 +1,5 @@ -//go:build tools - /* -Copyright 2022 The Kube Bind Authors. +Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,12 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tools +package log import ( - _ "k8s.io/code-generator" - _ "k8s.io/code-generator/cmd/conversion-gen" - _ "k8s.io/code-generator/cmd/deepcopy-gen" - _ "k8s.io/code-generator/cmd/defaulter-gen" - _ "sigs.k8s.io/controller-tools/cmd/controller-gen" + "github.com/go-logr/logr" + + "sigs.k8s.io/controller-runtime/pkg/log" ) + +var ( + // RuntimeLog is a base parent logger for use inside controller-runtime. + RuntimeLog logr.Logger +) + +func init() { + RuntimeLog = log.Log.WithName("controller-runtime") +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go new file mode 100644 index 00000000..21f0146b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go @@ -0,0 +1,181 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package recorder + +import ( + "context" + "fmt" + "net/http" + "sync" + + "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" +) + +// EventBroadcasterProducer makes an event broadcaster, returning +// whether or not the broadcaster should be stopped with the Provider, +// or not (e.g. if it's shared, it shouldn't be stopped with the Provider). +type EventBroadcasterProducer func() (caster record.EventBroadcaster, stopWithProvider bool) + +// Provider is a recorder.Provider that records events to the k8s API server +// and to a logr Logger. +type Provider struct { + lock sync.RWMutex + stopped bool + + // scheme to specify when creating a recorder + scheme *runtime.Scheme + // logger is the logger to use when logging diagnostic event info + logger logr.Logger + evtClient corev1client.EventInterface + makeBroadcaster EventBroadcasterProducer + + broadcasterOnce sync.Once + broadcaster record.EventBroadcaster + stopBroadcaster bool +} + +// NB(directxman12): this manually implements Stop instead of Being a runnable because we need to +// stop it *after* everything else shuts down, otherwise we'll cause panics as the leader election +// code finishes up and tries to continue emitting events. + +// Stop attempts to stop this provider, stopping the underlying broadcaster +// if the broadcaster asked to be stopped. It kinda tries to honor the given +// context, but the underlying broadcaster has an indefinite wait that doesn't +// return until all queued events are flushed, so this may end up just returning +// before the underlying wait has finished instead of cancelling the wait. +// This is Very Frustrating™. +func (p *Provider) Stop(shutdownCtx context.Context) { + doneCh := make(chan struct{}) + + go func() { + // technically, this could start the broadcaster, but practically, it's + // almost certainly already been started (e.g. by leader election). We + // need to invoke this to ensure that we don't inadvertently race with + // an invocation of getBroadcaster. + broadcaster := p.getBroadcaster() + if p.stopBroadcaster { + p.lock.Lock() + broadcaster.Shutdown() + p.stopped = true + p.lock.Unlock() + } + close(doneCh) + }() + + select { + case <-shutdownCtx.Done(): + case <-doneCh: + } +} + +// getBroadcaster ensures that a broadcaster is started for this +// provider, and returns it. It's threadsafe. +func (p *Provider) getBroadcaster() record.EventBroadcaster { + // NB(directxman12): this can technically still leak if something calls + // "getBroadcaster" (i.e. Emits an Event) but never calls Start, but if we + // create the broadcaster in start, we could race with other things that + // are started at the same time & want to emit events. The alternative is + // silently swallowing events and more locking, but that seems suboptimal. + + p.broadcasterOnce.Do(func() { + broadcaster, stop := p.makeBroadcaster() + broadcaster.StartRecordingToSink(&corev1client.EventSinkImpl{Interface: p.evtClient}) + broadcaster.StartEventWatcher( + func(e *corev1.Event) { + p.logger.V(1).Info(e.Message, "type", e.Type, "object", e.InvolvedObject, "reason", e.Reason) + }) + p.broadcaster = broadcaster + p.stopBroadcaster = stop + }) + + return p.broadcaster +} + +// NewProvider create a new Provider instance. +func NewProvider(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster EventBroadcasterProducer) (*Provider, error) { + if httpClient == nil { + panic("httpClient must not be nil") + } + + corev1Client, err := corev1client.NewForConfigAndClient(config, httpClient) + if err != nil { + return nil, fmt.Errorf("failed to init client: %w", err) + } + + p := &Provider{scheme: scheme, logger: logger, makeBroadcaster: makeBroadcaster, evtClient: corev1Client.Events("")} + return p, nil +} + +// GetEventRecorderFor returns an event recorder that broadcasts to this provider's +// broadcaster. All events will be associated with a component of the given name. +func (p *Provider) GetEventRecorderFor(name string) record.EventRecorder { + return &lazyRecorder{ + prov: p, + name: name, + } +} + +// lazyRecorder is a recorder that doesn't actually instantiate any underlying +// recorder until the first event is emitted. +type lazyRecorder struct { + prov *Provider + name string + + recOnce sync.Once + rec record.EventRecorder +} + +// ensureRecording ensures that a concrete recorder is populated for this recorder. +func (l *lazyRecorder) ensureRecording() { + l.recOnce.Do(func() { + broadcaster := l.prov.getBroadcaster() + l.rec = broadcaster.NewRecorder(l.prov.scheme, corev1.EventSource{Component: l.name}) + }) +} + +func (l *lazyRecorder) Event(object runtime.Object, eventtype, reason, message string) { + l.ensureRecording() + + l.prov.lock.RLock() + if !l.prov.stopped { + l.rec.Event(object, eventtype, reason, message) + } + l.prov.lock.RUnlock() +} +func (l *lazyRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { + l.ensureRecording() + + l.prov.lock.RLock() + if !l.prov.stopped { + l.rec.Eventf(object, eventtype, reason, messageFmt, args...) + } + l.prov.lock.RUnlock() +} +func (l *lazyRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { + l.ensureRecording() + + l.prov.lock.RLock() + if !l.prov.stopped { + l.rec.AnnotatedEventf(object, annotations, eventtype, reason, messageFmt, args...) + } + l.prov.lock.RUnlock() +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go new file mode 100644 index 00000000..ae8404a1 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/event_handler.go @@ -0,0 +1,170 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package internal + +import ( + "context" + "fmt" + + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" + + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +var log = logf.RuntimeLog.WithName("source").WithName("EventHandler") + +// NewEventHandler creates a new EventHandler. +func NewEventHandler(ctx context.Context, queue workqueue.RateLimitingInterface, handler handler.EventHandler, predicates []predicate.Predicate) *EventHandler { + return &EventHandler{ + ctx: ctx, + handler: handler, + queue: queue, + predicates: predicates, + } +} + +// EventHandler adapts a handler.EventHandler interface to a cache.ResourceEventHandler interface. +type EventHandler struct { + // ctx stores the context that created the event handler + // that is used to propagate cancellation signals to each handler function. + ctx context.Context + + handler handler.EventHandler + queue workqueue.RateLimitingInterface + predicates []predicate.Predicate +} + +// HandlerFuncs converts EventHandler to a ResourceEventHandlerFuncs +// TODO: switch to ResourceEventHandlerDetailedFuncs with client-go 1.27 +func (e *EventHandler) HandlerFuncs() cache.ResourceEventHandlerFuncs { + return cache.ResourceEventHandlerFuncs{ + AddFunc: e.OnAdd, + UpdateFunc: e.OnUpdate, + DeleteFunc: e.OnDelete, + } +} + +// OnAdd creates CreateEvent and calls Create on EventHandler. +func (e *EventHandler) OnAdd(obj interface{}) { + c := event.CreateEvent{} + + // Pull Object out of the object + if o, ok := obj.(client.Object); ok { + c.Object = o + } else { + log.Error(nil, "OnAdd missing Object", + "object", obj, "type", fmt.Sprintf("%T", obj)) + return + } + + for _, p := range e.predicates { + if !p.Create(c) { + return + } + } + + // Invoke create handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Create(ctx, c, e.queue) +} + +// OnUpdate creates UpdateEvent and calls Update on EventHandler. +func (e *EventHandler) OnUpdate(oldObj, newObj interface{}) { + u := event.UpdateEvent{} + + if o, ok := oldObj.(client.Object); ok { + u.ObjectOld = o + } else { + log.Error(nil, "OnUpdate missing ObjectOld", + "object", oldObj, "type", fmt.Sprintf("%T", oldObj)) + return + } + + // Pull Object out of the object + if o, ok := newObj.(client.Object); ok { + u.ObjectNew = o + } else { + log.Error(nil, "OnUpdate missing ObjectNew", + "object", newObj, "type", fmt.Sprintf("%T", newObj)) + return + } + + for _, p := range e.predicates { + if !p.Update(u) { + return + } + } + + // Invoke update handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Update(ctx, u, e.queue) +} + +// OnDelete creates DeleteEvent and calls Delete on EventHandler. +func (e *EventHandler) OnDelete(obj interface{}) { + d := event.DeleteEvent{} + + // Deal with tombstone events by pulling the object out. Tombstone events wrap the object in a + // DeleteFinalStateUnknown struct, so the object needs to be pulled out. + // Copied from sample-controller + // This should never happen if we aren't missing events, which we have concluded that we are not + // and made decisions off of this belief. Maybe this shouldn't be here? + var ok bool + if _, ok = obj.(client.Object); !ok { + // If the object doesn't have Metadata, assume it is a tombstone object of type DeletedFinalStateUnknown + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + log.Error(nil, "Error decoding objects. Expected cache.DeletedFinalStateUnknown", + "type", fmt.Sprintf("%T", obj), + "object", obj) + return + } + + // Set DeleteStateUnknown to true + d.DeleteStateUnknown = true + + // Set obj to the tombstone obj + obj = tombstone.Obj + } + + // Pull Object out of the object + if o, ok := obj.(client.Object); ok { + d.Object = o + } else { + log.Error(nil, "OnDelete missing Object", + "object", obj, "type", fmt.Sprintf("%T", obj)) + return + } + + for _, p := range e.predicates { + if !p.Delete(d) { + return + } + } + + // Invoke delete handler + ctx, cancel := context.WithCancel(e.ctx) + defer cancel() + e.handler.Delete(ctx, d, e.queue) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go new file mode 100644 index 00000000..b3a82271 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/source/kind.go @@ -0,0 +1,117 @@ +package internal + +import ( + "context" + "errors" + "fmt" + "time" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// Kind is used to provide a source of events originating inside the cluster from Watches (e.g. Pod Create). +type Kind struct { + // Type is the type of object to watch. e.g. &v1.Pod{} + Type client.Object + + // Cache used to watch APIs + Cache cache.Cache + + // started may contain an error if one was encountered during startup. If its closed and does not + // contain an error, startup and syncing finished. + started chan error + startCancel func() +} + +// Start is internal and should be called only by the Controller to register an EventHandler with the Informer +// to enqueue reconcile.Requests. +func (ks *Kind) Start(ctx context.Context, handler handler.EventHandler, queue workqueue.RateLimitingInterface, + prct ...predicate.Predicate) error { + if ks.Type == nil { + return fmt.Errorf("must create Kind with a non-nil object") + } + if ks.Cache == nil { + return fmt.Errorf("must create Kind with a non-nil cache") + } + + // cache.GetInformer will block until its context is cancelled if the cache was already started and it can not + // sync that informer (most commonly due to RBAC issues). + ctx, ks.startCancel = context.WithCancel(ctx) + ks.started = make(chan error) + go func() { + var ( + i cache.Informer + lastErr error + ) + + // Tries to get an informer until it returns true, + // an error or the specified context is cancelled or expired. + if err := wait.PollUntilContextCancel(ctx, 10*time.Second, true, func(ctx context.Context) (bool, error) { + // Lookup the Informer from the Cache and add an EventHandler which populates the Queue + i, lastErr = ks.Cache.GetInformer(ctx, ks.Type) + if lastErr != nil { + kindMatchErr := &meta.NoKindMatchError{} + switch { + case errors.As(lastErr, &kindMatchErr): + log.Error(lastErr, "if kind is a CRD, it should be installed before calling Start", + "kind", kindMatchErr.GroupKind) + case runtime.IsNotRegisteredError(lastErr): + log.Error(lastErr, "kind must be registered to the Scheme") + default: + log.Error(lastErr, "failed to get informer from cache") + } + return false, nil // Retry. + } + return true, nil + }); err != nil { + if lastErr != nil { + ks.started <- fmt.Errorf("failed to get informer from cache: %w", lastErr) + return + } + ks.started <- err + return + } + + _, err := i.AddEventHandler(NewEventHandler(ctx, queue, handler, prct).HandlerFuncs()) + if err != nil { + ks.started <- err + return + } + if !ks.Cache.WaitForCacheSync(ctx) { + // Would be great to return something more informative here + ks.started <- errors.New("cache did not sync") + } + close(ks.started) + }() + + return nil +} + +func (ks *Kind) String() string { + if ks.Type != nil { + return fmt.Sprintf("kind source: %T", ks.Type) + } + return "kind source: unknown type" +} + +// WaitForSync implements SyncingSource to allow controllers to wait with starting +// workers until the cache is synced. +func (ks *Kind) WaitForSync(ctx context.Context) error { + select { + case err := <-ks.started: + return err + case <-ctx.Done(): + ks.startCancel() + if errors.Is(ctx.Err(), context.Canceled) { + return nil + } + return fmt.Errorf("timed out waiting for cache to be synced for Kind %T", ks.Type) + } +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go new file mode 100644 index 00000000..c78a3037 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/internal/syncs/syncs.go @@ -0,0 +1,38 @@ +package syncs + +import ( + "context" + "reflect" + "sync" +) + +// MergeChans returns a channel that is closed when any of the input channels are signaled. +// The caller must call the returned CancelFunc to ensure no resources are leaked. +func MergeChans[T any](chans ...<-chan T) (<-chan T, context.CancelFunc) { + var once sync.Once + out := make(chan T) + cancel := make(chan T) + cancelFunc := func() { + once.Do(func() { + close(cancel) + }) + <-out + } + cases := make([]reflect.SelectCase, len(chans)+1) + for i := range chans { + cases[i] = reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(chans[i]), + } + } + cases[len(cases)-1] = reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(cancel), + } + go func() { + defer close(out) + _, _, _ = reflect.Select(cases) + }() + + return out, cancelFunc +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/doc.go new file mode 100644 index 00000000..37a9aefa --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package leaderelection contains a constructor for a leader election resource lock. +This is used to ensure that multiple copies of a controller manager can be run with +only one active set of controllers, for active-passive HA. + +It uses built-in Kubernetes leader election APIs. +*/ +package leaderelection diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go b/vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go new file mode 100644 index 00000000..ee4fcf4c --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/leaderelection/leader_election.go @@ -0,0 +1,127 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package leaderelection + +import ( + "errors" + "fmt" + "os" + + "k8s.io/apimachinery/pkg/util/uuid" + coordinationv1client "k8s.io/client-go/kubernetes/typed/coordination/v1" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection/resourcelock" + + "sigs.k8s.io/controller-runtime/pkg/recorder" +) + +const inClusterNamespacePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" + +// Options provides the required configuration to create a new resource lock. +type Options struct { + // LeaderElection determines whether or not to use leader election when + // starting the manager. + LeaderElection bool + + // LeaderElectionResourceLock determines which resource lock to use for leader election, + // defaults to "leases". + LeaderElectionResourceLock string + + // LeaderElectionNamespace determines the namespace in which the leader + // election resource will be created. + LeaderElectionNamespace string + + // LeaderElectionID determines the name of the resource that leader election + // will use for holding the leader lock. + LeaderElectionID string +} + +// NewResourceLock creates a new resource lock for use in a leader election loop. +func NewResourceLock(config *rest.Config, recorderProvider recorder.Provider, options Options) (resourcelock.Interface, error) { + if !options.LeaderElection { + return nil, nil + } + + // Default resource lock to "leases". The previous default (from v0.7.0 to v0.11.x) was configmapsleases, which was + // used to migrate from configmaps to leases. Since the default was "configmapsleases" for over a year, spanning + // five minor releases, any actively maintained operators are very likely to have a released version that uses + // "configmapsleases". Therefore defaulting to "leases" should be safe. + if options.LeaderElectionResourceLock == "" { + options.LeaderElectionResourceLock = resourcelock.LeasesResourceLock + } + + // LeaderElectionID must be provided to prevent clashes + if options.LeaderElectionID == "" { + return nil, errors.New("LeaderElectionID must be configured") + } + + // Default the namespace (if running in cluster) + if options.LeaderElectionNamespace == "" { + var err error + options.LeaderElectionNamespace, err = getInClusterNamespace() + if err != nil { + return nil, fmt.Errorf("unable to find leader election namespace: %w", err) + } + } + + // Leader id, needs to be unique + id, err := os.Hostname() + if err != nil { + return nil, err + } + id = id + "_" + string(uuid.NewUUID()) + + // Construct clients for leader election + rest.AddUserAgent(config, "leader-election") + corev1Client, err := corev1client.NewForConfig(config) + if err != nil { + return nil, err + } + + coordinationClient, err := coordinationv1client.NewForConfig(config) + if err != nil { + return nil, err + } + + return resourcelock.New(options.LeaderElectionResourceLock, + options.LeaderElectionNamespace, + options.LeaderElectionID, + corev1Client, + coordinationClient, + resourcelock.ResourceLockConfig{ + Identity: id, + EventRecorder: recorderProvider.GetEventRecorderFor(id), + }) +} + +func getInClusterNamespace() (string, error) { + // Check whether the namespace file exists. + // If not, we are not running in cluster so can't guess the namespace. + if _, err := os.Stat(inClusterNamespacePath); os.IsNotExist(err) { + return "", fmt.Errorf("not running in-cluster, please specify LeaderElectionNamespace") + } else if err != nil { + return "", fmt.Errorf("error checking namespace file: %w", err) + } + + // Load the namespace file and return its content + namespace, err := os.ReadFile(inClusterNamespacePath) + if err != nil { + return "", fmt.Errorf("error reading namespace file: %w", err) + } + return string(namespace), nil +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/doc.go new file mode 100644 index 00000000..f2976c7f --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package manager is required to create Controllers and provides shared dependencies such as clients, caches, schemes, +etc. Controllers must be started by calling Manager.Start. +*/ +package manager diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go new file mode 100644 index 00000000..a16f354a --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go @@ -0,0 +1,605 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package manager + +import ( + "context" + "errors" + "fmt" + "net" + "net/http" + "net/http/pprof" + "sync" + "sync/atomic" + "time" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + kerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection" + "k8s.io/client-go/tools/leaderelection/resourcelock" + "k8s.io/client-go/tools/record" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" + "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/internal/httpserver" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +const ( + // Values taken from: https://github.com/kubernetes/component-base/blob/master/config/v1alpha1/defaults.go + defaultLeaseDuration = 15 * time.Second + defaultRenewDeadline = 10 * time.Second + defaultRetryPeriod = 2 * time.Second + defaultGracefulShutdownPeriod = 30 * time.Second + + defaultReadinessEndpoint = "/readyz" + defaultLivenessEndpoint = "/healthz" +) + +var _ Runnable = &controllerManager{} + +type controllerManager struct { + sync.Mutex + started bool + + stopProcedureEngaged *int64 + errChan chan error + runnables *runnables + + // cluster holds a variety of methods to interact with a cluster. Required. + cluster cluster.Cluster + + // recorderProvider is used to generate event recorders that will be injected into Controllers + // (and EventHandlers, Sources and Predicates). + recorderProvider *intrec.Provider + + // resourceLock forms the basis for leader election + resourceLock resourcelock.Interface + + // leaderElectionReleaseOnCancel defines if the manager should step back from the leader lease + // on shutdown + leaderElectionReleaseOnCancel bool + + // metricsServer is used to serve prometheus metrics + metricsServer metricsserver.Server + + // healthProbeListener is used to serve liveness probe + healthProbeListener net.Listener + + // Readiness probe endpoint name + readinessEndpointName string + + // Liveness probe endpoint name + livenessEndpointName string + + // Readyz probe handler + readyzHandler *healthz.Handler + + // Healthz probe handler + healthzHandler *healthz.Handler + + // pprofListener is used to serve pprof + pprofListener net.Listener + + // controllerConfig are the global controller options. + controllerConfig config.Controller + + // Logger is the logger that should be used by this manager. + // If none is set, it defaults to log.Log global logger. + logger logr.Logger + + // leaderElectionStopped is an internal channel used to signal the stopping procedure that the + // LeaderElection.Run(...) function has returned and the shutdown can proceed. + leaderElectionStopped chan struct{} + + // leaderElectionCancel is used to cancel the leader election. It is distinct from internalStopper, + // because for safety reasons we need to os.Exit() when we lose the leader election, meaning that + // it must be deferred until after gracefulShutdown is done. + leaderElectionCancel context.CancelFunc + + // elected is closed when this manager becomes the leader of a group of + // managers, either because it won a leader election or because no leader + // election was configured. + elected chan struct{} + + webhookServer webhook.Server + // webhookServerOnce will be called in GetWebhookServer() to optionally initialize + // webhookServer if unset, and Add() it to controllerManager. + webhookServerOnce sync.Once + + // leaderElectionID is the name of the resource that leader election + // will use for holding the leader lock. + leaderElectionID string + // leaseDuration is the duration that non-leader candidates will + // wait to force acquire leadership. + leaseDuration time.Duration + // renewDeadline is the duration that the acting controlplane will retry + // refreshing leadership before giving up. + renewDeadline time.Duration + // retryPeriod is the duration the LeaderElector clients should wait + // between tries of actions. + retryPeriod time.Duration + + // gracefulShutdownTimeout is the duration given to runnable to stop + // before the manager actually returns on stop. + gracefulShutdownTimeout time.Duration + + // onStoppedLeading is callled when the leader election lease is lost. + // It can be overridden for tests. + onStoppedLeading func() + + // shutdownCtx is the context that can be used during shutdown. It will be cancelled + // after the gracefulShutdownTimeout ended. It must not be accessed before internalStop + // is closed because it will be nil. + shutdownCtx context.Context + + internalCtx context.Context + internalCancel context.CancelFunc + + // internalProceduresStop channel is used internally to the manager when coordinating + // the proper shutdown of servers. This channel is also used for dependency injection. + internalProceduresStop chan struct{} +} + +type hasCache interface { + Runnable + GetCache() cache.Cache +} + +// Add sets dependencies on i, and adds it to the list of Runnables to start. +func (cm *controllerManager) Add(r Runnable) error { + cm.Lock() + defer cm.Unlock() + return cm.add(r) +} + +func (cm *controllerManager) add(r Runnable) error { + return cm.runnables.Add(r) +} + +// AddHealthzCheck allows you to add Healthz checker. +func (cm *controllerManager) AddHealthzCheck(name string, check healthz.Checker) error { + cm.Lock() + defer cm.Unlock() + + if cm.started { + return fmt.Errorf("unable to add new checker because healthz endpoint has already been created") + } + + if cm.healthzHandler == nil { + cm.healthzHandler = &healthz.Handler{Checks: map[string]healthz.Checker{}} + } + + cm.healthzHandler.Checks[name] = check + return nil +} + +// AddReadyzCheck allows you to add Readyz checker. +func (cm *controllerManager) AddReadyzCheck(name string, check healthz.Checker) error { + cm.Lock() + defer cm.Unlock() + + if cm.started { + return fmt.Errorf("unable to add new checker because healthz endpoint has already been created") + } + + if cm.readyzHandler == nil { + cm.readyzHandler = &healthz.Handler{Checks: map[string]healthz.Checker{}} + } + + cm.readyzHandler.Checks[name] = check + return nil +} + +func (cm *controllerManager) GetHTTPClient() *http.Client { + return cm.cluster.GetHTTPClient() +} + +func (cm *controllerManager) GetConfig() *rest.Config { + return cm.cluster.GetConfig() +} + +func (cm *controllerManager) GetClient() client.Client { + return cm.cluster.GetClient() +} + +func (cm *controllerManager) GetScheme() *runtime.Scheme { + return cm.cluster.GetScheme() +} + +func (cm *controllerManager) GetFieldIndexer() client.FieldIndexer { + return cm.cluster.GetFieldIndexer() +} + +func (cm *controllerManager) GetCache() cache.Cache { + return cm.cluster.GetCache() +} + +func (cm *controllerManager) GetEventRecorderFor(name string) record.EventRecorder { + return cm.cluster.GetEventRecorderFor(name) +} + +func (cm *controllerManager) GetRESTMapper() meta.RESTMapper { + return cm.cluster.GetRESTMapper() +} + +func (cm *controllerManager) GetAPIReader() client.Reader { + return cm.cluster.GetAPIReader() +} + +func (cm *controllerManager) GetWebhookServer() webhook.Server { + cm.webhookServerOnce.Do(func() { + if cm.webhookServer == nil { + panic("webhook should not be nil") + } + if err := cm.Add(cm.webhookServer); err != nil { + panic(fmt.Sprintf("unable to add webhook server to the controller manager: %s", err)) + } + }) + return cm.webhookServer +} + +func (cm *controllerManager) GetLogger() logr.Logger { + return cm.logger +} + +func (cm *controllerManager) GetControllerOptions() config.Controller { + return cm.controllerConfig +} + +func (cm *controllerManager) addHealthProbeServer() error { + mux := http.NewServeMux() + srv := httpserver.New(mux) + + if cm.readyzHandler != nil { + mux.Handle(cm.readinessEndpointName, http.StripPrefix(cm.readinessEndpointName, cm.readyzHandler)) + // Append '/' suffix to handle subpaths + mux.Handle(cm.readinessEndpointName+"/", http.StripPrefix(cm.readinessEndpointName, cm.readyzHandler)) + } + if cm.healthzHandler != nil { + mux.Handle(cm.livenessEndpointName, http.StripPrefix(cm.livenessEndpointName, cm.healthzHandler)) + // Append '/' suffix to handle subpaths + mux.Handle(cm.livenessEndpointName+"/", http.StripPrefix(cm.livenessEndpointName, cm.healthzHandler)) + } + + return cm.add(&server{ + Kind: "health probe", + Log: cm.logger, + Server: srv, + Listener: cm.healthProbeListener, + }) +} + +func (cm *controllerManager) addPprofServer() error { + mux := http.NewServeMux() + srv := httpserver.New(mux) + + mux.HandleFunc("/debug/pprof/", pprof.Index) + mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + + return cm.add(&server{ + Kind: "pprof", + Log: cm.logger, + Server: srv, + Listener: cm.pprofListener, + }) +} + +// Start starts the manager and waits indefinitely. +// There is only two ways to have start return: +// An error has occurred during in one of the internal operations, +// such as leader election, cache start, webhooks, and so on. +// Or, the context is cancelled. +func (cm *controllerManager) Start(ctx context.Context) (err error) { + cm.Lock() + if cm.started { + cm.Unlock() + return errors.New("manager already started") + } + cm.started = true + + var ready bool + defer func() { + // Only unlock the manager if we haven't reached + // the internal readiness condition. + if !ready { + cm.Unlock() + } + }() + + // Initialize the internal context. + cm.internalCtx, cm.internalCancel = context.WithCancel(ctx) + + // This chan indicates that stop is complete, in other words all runnables have returned or timeout on stop request + stopComplete := make(chan struct{}) + defer close(stopComplete) + // This must be deferred after closing stopComplete, otherwise we deadlock. + defer func() { + // https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/gettyimages-459889618-1533579787.jpg + stopErr := cm.engageStopProcedure(stopComplete) + if stopErr != nil { + if err != nil { + // Utilerrors.Aggregate allows to use errors.Is for all contained errors + // whereas fmt.Errorf allows wrapping at most one error which means the + // other one can not be found anymore. + err = kerrors.NewAggregate([]error{err, stopErr}) + } else { + err = stopErr + } + } + }() + + // Add the cluster runnable. + if err := cm.add(cm.cluster); err != nil { + return fmt.Errorf("failed to add cluster to runnables: %w", err) + } + + // Metrics should be served whether the controller is leader or not. + // (If we don't serve metrics for non-leaders, prometheus will still scrape + // the pod but will get a connection refused). + if cm.metricsServer != nil { + // Note: We are adding the metrics server directly to HTTPServers here as matching on the + // metricsserver.Server interface in cm.runnables.Add would be very brittle. + if err := cm.runnables.HTTPServers.Add(cm.metricsServer, nil); err != nil { + return fmt.Errorf("failed to add metrics server: %w", err) + } + } + + // Serve health probes. + if cm.healthProbeListener != nil { + if err := cm.addHealthProbeServer(); err != nil { + return fmt.Errorf("failed to add health probe server: %w", err) + } + } + + // Add pprof server + if cm.pprofListener != nil { + if err := cm.addPprofServer(); err != nil { + return fmt.Errorf("failed to add pprof server: %w", err) + } + } + + // First start any internal HTTP servers, which includes health probes, metrics and profiling if enabled. + // + // WARNING: Internal HTTP servers MUST start before any cache is populated, otherwise it would block + // conversion webhooks to be ready for serving which make the cache never get ready. + if err := cm.runnables.HTTPServers.Start(cm.internalCtx); err != nil { + if err != nil { + return fmt.Errorf("failed to start HTTP servers: %w", err) + } + } + + // Start any webhook servers, which includes conversion, validation, and defaulting + // webhooks that are registered. + // + // WARNING: Webhooks MUST start before any cache is populated, otherwise there is a race condition + // between conversion webhooks and the cache sync (usually initial list) which causes the webhooks + // to never start because no cache can be populated. + if err := cm.runnables.Webhooks.Start(cm.internalCtx); err != nil { + if err != nil { + return fmt.Errorf("failed to start webhooks: %w", err) + } + } + + // Start and wait for caches. + if err := cm.runnables.Caches.Start(cm.internalCtx); err != nil { + if err != nil { + return fmt.Errorf("failed to start caches: %w", err) + } + } + + // Start the non-leaderelection Runnables after the cache has synced. + if err := cm.runnables.Others.Start(cm.internalCtx); err != nil { + if err != nil { + return fmt.Errorf("failed to start other runnables: %w", err) + } + } + + // Start the leader election and all required runnables. + { + ctx, cancel := context.WithCancel(context.Background()) + cm.leaderElectionCancel = cancel + go func() { + if cm.resourceLock != nil { + if err := cm.startLeaderElection(ctx); err != nil { + cm.errChan <- err + } + } else { + // Treat not having leader election enabled the same as being elected. + if err := cm.startLeaderElectionRunnables(); err != nil { + cm.errChan <- err + } + close(cm.elected) + } + }() + } + + ready = true + cm.Unlock() + select { + case <-ctx.Done(): + // We are done + return nil + case err := <-cm.errChan: + // Error starting or running a runnable + return err + } +} + +// engageStopProcedure signals all runnables to stop, reads potential errors +// from the errChan and waits for them to end. It must not be called more than once. +func (cm *controllerManager) engageStopProcedure(stopComplete <-chan struct{}) error { + if !atomic.CompareAndSwapInt64(cm.stopProcedureEngaged, 0, 1) { + return errors.New("stop procedure already engaged") + } + + // Populate the shutdown context, this operation MUST be done before + // closing the internalProceduresStop channel. + // + // The shutdown context immediately expires if the gracefulShutdownTimeout is not set. + var shutdownCancel context.CancelFunc + if cm.gracefulShutdownTimeout < 0 { + // We want to wait forever for the runnables to stop. + cm.shutdownCtx, shutdownCancel = context.WithCancel(context.Background()) + } else { + cm.shutdownCtx, shutdownCancel = context.WithTimeout(context.Background(), cm.gracefulShutdownTimeout) + } + defer shutdownCancel() + + // Start draining the errors before acquiring the lock to make sure we don't deadlock + // if something that has the lock is blocked on trying to write into the unbuffered + // channel after something else already wrote into it. + var closeOnce sync.Once + go func() { + for { + // Closing in the for loop is required to avoid race conditions between + // the closure of all internal procedures and making sure to have a reader off the error channel. + closeOnce.Do(func() { + // Cancel the internal stop channel and wait for the procedures to stop and complete. + close(cm.internalProceduresStop) + cm.internalCancel() + }) + select { + case err, ok := <-cm.errChan: + if ok { + cm.logger.Error(err, "error received after stop sequence was engaged") + } + case <-stopComplete: + return + } + } + }() + + // We want to close this after the other runnables stop, because we don't + // want things like leader election to try and emit events on a closed + // channel + defer cm.recorderProvider.Stop(cm.shutdownCtx) + defer func() { + // Cancel leader election only after we waited. It will os.Exit() the app for safety. + if cm.resourceLock != nil { + // After asking the context to be cancelled, make sure + // we wait for the leader stopped channel to be closed, otherwise + // we might encounter race conditions between this code + // and the event recorder, which is used within leader election code. + cm.leaderElectionCancel() + <-cm.leaderElectionStopped + } + }() + + go func() { + // First stop the non-leader election runnables. + cm.logger.Info("Stopping and waiting for non leader election runnables") + cm.runnables.Others.StopAndWait(cm.shutdownCtx) + + // Stop all the leader election runnables, which includes reconcilers. + cm.logger.Info("Stopping and waiting for leader election runnables") + cm.runnables.LeaderElection.StopAndWait(cm.shutdownCtx) + + // Stop the caches before the leader election runnables, this is an important + // step to make sure that we don't race with the reconcilers by receiving more events + // from the API servers and enqueueing them. + cm.logger.Info("Stopping and waiting for caches") + cm.runnables.Caches.StopAndWait(cm.shutdownCtx) + + // Webhooks and internal HTTP servers should come last, as they might be still serving some requests. + cm.logger.Info("Stopping and waiting for webhooks") + cm.runnables.Webhooks.StopAndWait(cm.shutdownCtx) + + cm.logger.Info("Stopping and waiting for HTTP servers") + cm.runnables.HTTPServers.StopAndWait(cm.shutdownCtx) + + // Proceed to close the manager and overall shutdown context. + cm.logger.Info("Wait completed, proceeding to shutdown the manager") + shutdownCancel() + }() + + <-cm.shutdownCtx.Done() + if err := cm.shutdownCtx.Err(); err != nil && !errors.Is(err, context.Canceled) { + if errors.Is(err, context.DeadlineExceeded) { + if cm.gracefulShutdownTimeout > 0 { + return fmt.Errorf("failed waiting for all runnables to end within grace period of %s: %w", cm.gracefulShutdownTimeout, err) + } + return nil + } + // For any other error, return the error. + return err + } + + return nil +} + +func (cm *controllerManager) startLeaderElectionRunnables() error { + return cm.runnables.LeaderElection.Start(cm.internalCtx) +} + +func (cm *controllerManager) startLeaderElection(ctx context.Context) (err error) { + l, err := leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{ + Lock: cm.resourceLock, + LeaseDuration: cm.leaseDuration, + RenewDeadline: cm.renewDeadline, + RetryPeriod: cm.retryPeriod, + Callbacks: leaderelection.LeaderCallbacks{ + OnStartedLeading: func(_ context.Context) { + if err := cm.startLeaderElectionRunnables(); err != nil { + cm.errChan <- err + return + } + close(cm.elected) + }, + OnStoppedLeading: func() { + if cm.onStoppedLeading != nil { + cm.onStoppedLeading() + } + // Make sure graceful shutdown is skipped if we lost the leader lock without + // intending to. + cm.gracefulShutdownTimeout = time.Duration(0) + // Most implementations of leader election log.Fatal() here. + // Since Start is wrapped in log.Fatal when called, we can just return + // an error here which will cause the program to exit. + cm.errChan <- errors.New("leader election lost") + }, + }, + ReleaseOnCancel: cm.leaderElectionReleaseOnCancel, + Name: cm.leaderElectionID, + }) + if err != nil { + return err + } + + // Start the leader elector process + go func() { + l.Run(ctx) + <-ctx.Done() + close(cm.leaderElectionStopped) + }() + return nil +} + +func (cm *controllerManager) Elected() <-chan struct{} { + return cm.elected +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go new file mode 100644 index 00000000..25c3c737 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go @@ -0,0 +1,669 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package manager + +import ( + "context" + "errors" + "fmt" + "net" + "net/http" + "reflect" + "time" + + "github.com/go-logr/logr" + coordinationv1 "k8s.io/api/coordination/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection/resourcelock" + "k8s.io/client-go/tools/record" + "k8s.io/utils/ptr" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" + "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/healthz" + intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder" + "sigs.k8s.io/controller-runtime/pkg/leaderelection" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/recorder" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// Manager initializes shared dependencies such as Caches and Clients, and provides them to Runnables. +// A Manager is required to create Controllers. +type Manager interface { + // Cluster holds a variety of methods to interact with a cluster. + cluster.Cluster + + // Add will set requested dependencies on the component, and cause the component to be + // started when Start is called. + // Depending on if a Runnable implements LeaderElectionRunnable interface, a Runnable can be run in either + // non-leaderelection mode (always running) or leader election mode (managed by leader election if enabled). + Add(Runnable) error + + // Elected is closed when this manager is elected leader of a group of + // managers, either because it won a leader election or because no leader + // election was configured. + Elected() <-chan struct{} + + // AddHealthzCheck allows you to add Healthz checker + AddHealthzCheck(name string, check healthz.Checker) error + + // AddReadyzCheck allows you to add Readyz checker + AddReadyzCheck(name string, check healthz.Checker) error + + // Start starts all registered Controllers and blocks until the context is cancelled. + // Returns an error if there is an error starting any controller. + // + // If LeaderElection is used, the binary must be exited immediately after this returns, + // otherwise components that need leader election might continue to run after the leader + // lock was lost. + Start(ctx context.Context) error + + // GetWebhookServer returns a webhook.Server + GetWebhookServer() webhook.Server + + // GetLogger returns this manager's logger. + GetLogger() logr.Logger + + // GetControllerOptions returns controller global configuration options. + GetControllerOptions() config.Controller +} + +// Options are the arguments for creating a new Manager. +type Options struct { + // Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources. + // Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better + // to pass your own scheme in. See the documentation in pkg/scheme for more information. + // + // If set, the Scheme will be used to create the default Client and Cache. + Scheme *runtime.Scheme + + // MapperProvider provides the rest mapper used to map go types to Kubernetes APIs. + // + // If set, the RESTMapper returned by this function is used to create the RESTMapper + // used by the Client and Cache. + MapperProvider func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) + + // Cache is the cache.Options that will be used to create the default Cache. + // By default, the cache will watch and list requested objects in all namespaces. + Cache cache.Options + + // NewCache is the function that will create the cache to be used + // by the manager. If not set this will use the default new cache function. + // + // When using a custom NewCache, the Cache options will be passed to the + // NewCache function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewCache if you know what you are doing. + NewCache cache.NewCacheFunc + + // Client is the client.Options that will be used to create the default Client. + // By default, the client will use the cache for reads and direct calls for writes. + Client client.Options + + // NewClient is the func that creates the client to be used by the manager. + // If not set this will create a Client backed by a Cache for read operations + // and a direct Client for write operations. + // + // When using a custom NewClient, the Client options will be passed to the + // NewClient function. + // + // NOTE: LOW LEVEL PRIMITIVE! + // Only use a custom NewClient if you know what you are doing. + NewClient client.NewClientFunc + + // Logger is the logger that should be used by this manager. + // If none is set, it defaults to log.Log global logger. + Logger logr.Logger + + // LeaderElection determines whether or not to use leader election when + // starting the manager. + LeaderElection bool + + // LeaderElectionResourceLock determines which resource lock to use for leader election, + // defaults to "leases". Change this value only if you know what you are doing. + // + // If you are using `configmaps`/`endpoints` resource lock and want to migrate to "leases", + // you might do so by migrating to the respective multilock first ("configmapsleases" or "endpointsleases"), + // which will acquire a leader lock on both resources. + // After all your users have migrated to the multilock, you can go ahead and migrate to "leases". + // Please also keep in mind, that users might skip versions of your controller. + // + // Note: before controller-runtime version v0.7, it was set to "configmaps". + // And from v0.7 to v0.11, the default was "configmapsleases", which was + // used to migrate from configmaps to leases. + // Since the default was "configmapsleases" for over a year, spanning five minor releases, + // any actively maintained operators are very likely to have a released version that uses + // "configmapsleases". Therefore defaulting to "leases" should be safe since v0.12. + // + // So, what do you have to do when you are updating your controller-runtime dependency + // from a lower version to v0.12 or newer? + // - If your operator matches at least one of these conditions: + // - the LeaderElectionResourceLock in your operator has already been explicitly set to "leases" + // - the old controller-runtime version is between v0.7.0 and v0.11.x and the + // LeaderElectionResourceLock wasn't set or was set to "leases"/"configmapsleases"/"endpointsleases" + // feel free to update controller-runtime to v0.12 or newer. + // - Otherwise, you may have to take these steps: + // 1. update controller-runtime to v0.12 or newer in your go.mod + // 2. set LeaderElectionResourceLock to "configmapsleases" (or "endpointsleases") + // 3. package your operator and upgrade it in all your clusters + // 4. only if you have finished 3, you can remove the LeaderElectionResourceLock to use the default "leases" + // Otherwise, your operator might end up with multiple running instances that + // each acquired leadership through different resource locks during upgrades and thus + // act on the same resources concurrently. + LeaderElectionResourceLock string + + // LeaderElectionNamespace determines the namespace in which the leader + // election resource will be created. + LeaderElectionNamespace string + + // LeaderElectionID determines the name of the resource that leader election + // will use for holding the leader lock. + LeaderElectionID string + + // LeaderElectionConfig can be specified to override the default configuration + // that is used to build the leader election client. + LeaderElectionConfig *rest.Config + + // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily + // when the Manager ends. This requires the binary to immediately end when the + // Manager is stopped, otherwise this setting is unsafe. Setting this significantly + // speeds up voluntary leader transitions as the new leader doesn't have to wait + // LeaseDuration time first. + LeaderElectionReleaseOnCancel bool + + // LeaderElectionResourceLockInterface allows to provide a custom resourcelock.Interface that was created outside + // of the controller-runtime. If this value is set the options LeaderElectionID, LeaderElectionNamespace, + // LeaderElectionResourceLock, LeaseDuration, RenewDeadline and RetryPeriod will be ignored. This can be useful if you + // want to use a locking mechanism that is currently not supported, like a MultiLock across two Kubernetes clusters. + LeaderElectionResourceLockInterface resourcelock.Interface + + // LeaseDuration is the duration that non-leader candidates will + // wait to force acquire leadership. This is measured against time of + // last observed ack. Default is 15 seconds. + LeaseDuration *time.Duration + + // RenewDeadline is the duration that the acting controlplane will retry + // refreshing leadership before giving up. Default is 10 seconds. + RenewDeadline *time.Duration + + // RetryPeriod is the duration the LeaderElector clients should wait + // between tries of actions. Default is 2 seconds. + RetryPeriod *time.Duration + + // Metrics are the metricsserver.Options that will be used to create the metricsserver.Server. + Metrics metricsserver.Options + + // HealthProbeBindAddress is the TCP address that the controller should bind to + // for serving health probes + // It can be set to "0" or "" to disable serving the health probe. + HealthProbeBindAddress string + + // Readiness probe endpoint name, defaults to "readyz" + ReadinessEndpointName string + + // Liveness probe endpoint name, defaults to "healthz" + LivenessEndpointName string + + // PprofBindAddress is the TCP address that the controller should bind to + // for serving pprof. + // It can be set to "" or "0" to disable the pprof serving. + // Since pprof may contain sensitive information, make sure to protect it + // before exposing it to public. + PprofBindAddress string + + // WebhookServer is an externally configured webhook.Server. By default, + // a Manager will create a server via webhook.NewServer with default settings. + // If this is set, the Manager will use this server instead. + WebhookServer webhook.Server + + // BaseContext is the function that provides Context values to Runnables + // managed by the Manager. If a BaseContext function isn't provided, Runnables + // will receive a new Background Context instead. + BaseContext BaseContextFunc + + // EventBroadcaster records Events emitted by the manager and sends them to the Kubernetes API + // Use this to customize the event correlator and spam filter + // + // Deprecated: using this may cause goroutine leaks if the lifetime of your manager or controllers + // is shorter than the lifetime of your process. + EventBroadcaster record.EventBroadcaster + + // GracefulShutdownTimeout is the duration given to runnable to stop before the manager actually returns on stop. + // To disable graceful shutdown, set to time.Duration(0) + // To use graceful shutdown without timeout, set to a negative duration, e.G. time.Duration(-1) + // The graceful shutdown is skipped for safety reasons in case the leader election lease is lost. + GracefulShutdownTimeout *time.Duration + + // Controller contains global configuration options for controllers + // registered within this manager. + // +optional + Controller config.Controller + + // makeBroadcaster allows deferring the creation of the broadcaster to + // avoid leaking goroutines if we never call Start on this manager. It also + // returns whether or not this is a "owned" broadcaster, and as such should be + // stopped with the manager. + makeBroadcaster intrec.EventBroadcasterProducer + + // Dependency injection for testing + newRecorderProvider func(config *rest.Config, httpClient *http.Client, scheme *runtime.Scheme, logger logr.Logger, makeBroadcaster intrec.EventBroadcasterProducer) (*intrec.Provider, error) + newResourceLock func(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error) + newMetricsServer func(options metricsserver.Options, config *rest.Config, httpClient *http.Client) (metricsserver.Server, error) + newHealthProbeListener func(addr string) (net.Listener, error) + newPprofListener func(addr string) (net.Listener, error) +} + +// BaseContextFunc is a function used to provide a base Context to Runnables +// managed by a Manager. +type BaseContextFunc func() context.Context + +// Runnable allows a component to be started. +// It's very important that Start blocks until +// it's done running. +type Runnable interface { + // Start starts running the component. The component will stop running + // when the context is closed. Start blocks until the context is closed or + // an error occurs. + Start(context.Context) error +} + +// RunnableFunc implements Runnable using a function. +// It's very important that the given function block +// until it's done running. +type RunnableFunc func(context.Context) error + +// Start implements Runnable. +func (r RunnableFunc) Start(ctx context.Context) error { + return r(ctx) +} + +// LeaderElectionRunnable knows if a Runnable needs to be run in the leader election mode. +type LeaderElectionRunnable interface { + // NeedLeaderElection returns true if the Runnable needs to be run in the leader election mode. + // e.g. controllers need to be run in leader election mode, while webhook server doesn't. + NeedLeaderElection() bool +} + +// New returns a new Manager for creating Controllers. +// Note that if ContentType in the given config is not set, "application/vnd.kubernetes.protobuf" +// will be used for all built-in resources of Kubernetes, and "application/json" is for other types +// including all CRD resources. +func New(config *rest.Config, options Options) (Manager, error) { + if config == nil { + return nil, errors.New("must specify Config") + } + // Set default values for options fields + options = setOptionsDefaults(options) + + cluster, err := cluster.New(config, func(clusterOptions *cluster.Options) { + clusterOptions.Scheme = options.Scheme + clusterOptions.MapperProvider = options.MapperProvider + clusterOptions.Logger = options.Logger + clusterOptions.NewCache = options.NewCache + clusterOptions.NewClient = options.NewClient + clusterOptions.Cache = options.Cache + clusterOptions.Client = options.Client + clusterOptions.EventBroadcaster = options.EventBroadcaster //nolint:staticcheck + }) + if err != nil { + return nil, err + } + + config = rest.CopyConfig(config) + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + // Create the recorder provider to inject event recorders for the components. + // TODO(directxman12): the log for the event provider should have a context (name, tags, etc) specific + // to the particular controller that it's being injected into, rather than a generic one like is here. + recorderProvider, err := options.newRecorderProvider(config, cluster.GetHTTPClient(), cluster.GetScheme(), options.Logger.WithName("events"), options.makeBroadcaster) + if err != nil { + return nil, err + } + + // Create the resource lock to enable leader election) + var leaderConfig *rest.Config + var leaderRecorderProvider *intrec.Provider + + if options.LeaderElectionConfig == nil { + leaderConfig = rest.CopyConfig(config) + leaderRecorderProvider = recorderProvider + } else { + leaderConfig = rest.CopyConfig(options.LeaderElectionConfig) + scheme := cluster.GetScheme() + err := corev1.AddToScheme(scheme) + if err != nil { + return nil, err + } + err = coordinationv1.AddToScheme(scheme) + if err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(options.LeaderElectionConfig) + if err != nil { + return nil, err + } + leaderRecorderProvider, err = options.newRecorderProvider(leaderConfig, httpClient, scheme, options.Logger.WithName("events"), options.makeBroadcaster) + if err != nil { + return nil, err + } + } + + var resourceLock resourcelock.Interface + if options.LeaderElectionResourceLockInterface != nil && options.LeaderElection { + resourceLock = options.LeaderElectionResourceLockInterface + } else { + resourceLock, err = options.newResourceLock(leaderConfig, leaderRecorderProvider, leaderelection.Options{ + LeaderElection: options.LeaderElection, + LeaderElectionResourceLock: options.LeaderElectionResourceLock, + LeaderElectionID: options.LeaderElectionID, + LeaderElectionNamespace: options.LeaderElectionNamespace, + }) + if err != nil { + return nil, err + } + } + + // Create the metrics server. + metricsServer, err := options.newMetricsServer(options.Metrics, config, cluster.GetHTTPClient()) + if err != nil { + return nil, err + } + + // Create health probes listener. This will throw an error if the bind + // address is invalid or already in use. + healthProbeListener, err := options.newHealthProbeListener(options.HealthProbeBindAddress) + if err != nil { + return nil, err + } + + // Create pprof listener. This will throw an error if the bind + // address is invalid or already in use. + pprofListener, err := options.newPprofListener(options.PprofBindAddress) + if err != nil { + return nil, fmt.Errorf("failed to new pprof listener: %w", err) + } + + errChan := make(chan error, 1) + runnables := newRunnables(options.BaseContext, errChan) + return &controllerManager{ + stopProcedureEngaged: ptr.To(int64(0)), + cluster: cluster, + runnables: runnables, + errChan: errChan, + recorderProvider: recorderProvider, + resourceLock: resourceLock, + metricsServer: metricsServer, + controllerConfig: options.Controller, + logger: options.Logger, + elected: make(chan struct{}), + webhookServer: options.WebhookServer, + leaderElectionID: options.LeaderElectionID, + leaseDuration: *options.LeaseDuration, + renewDeadline: *options.RenewDeadline, + retryPeriod: *options.RetryPeriod, + healthProbeListener: healthProbeListener, + readinessEndpointName: options.ReadinessEndpointName, + livenessEndpointName: options.LivenessEndpointName, + pprofListener: pprofListener, + gracefulShutdownTimeout: *options.GracefulShutdownTimeout, + internalProceduresStop: make(chan struct{}), + leaderElectionStopped: make(chan struct{}), + leaderElectionReleaseOnCancel: options.LeaderElectionReleaseOnCancel, + }, nil +} + +// AndFrom will use a supplied type and convert to Options +// any options already set on Options will be ignored, this is used to allow +// cli flags to override anything specified in the config file. +// +// Deprecated: This function has been deprecated and will be removed in a future release, +// The Component Configuration package has been unmaintained for over a year and is no longer +// actively developed. Users should migrate to their own configuration format +// and configure Manager.Options directly. +// See https://github.com/kubernetes-sigs/controller-runtime/issues/895 +// for more information, feedback, and comments. +func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options, error) { + newObj, err := loader.Complete() + if err != nil { + return o, err + } + + o = o.setLeaderElectionConfig(newObj) + + if o.Cache.SyncPeriod == nil && newObj.SyncPeriod != nil { + o.Cache.SyncPeriod = &newObj.SyncPeriod.Duration + } + + if len(o.Cache.DefaultNamespaces) == 0 && newObj.CacheNamespace != "" { + o.Cache.DefaultNamespaces = map[string]cache.Config{newObj.CacheNamespace: {}} + } + + if o.Metrics.BindAddress == "" && newObj.Metrics.BindAddress != "" { + o.Metrics.BindAddress = newObj.Metrics.BindAddress + } + + if o.HealthProbeBindAddress == "" && newObj.Health.HealthProbeBindAddress != "" { + o.HealthProbeBindAddress = newObj.Health.HealthProbeBindAddress + } + + if o.ReadinessEndpointName == "" && newObj.Health.ReadinessEndpointName != "" { + o.ReadinessEndpointName = newObj.Health.ReadinessEndpointName + } + + if o.LivenessEndpointName == "" && newObj.Health.LivenessEndpointName != "" { + o.LivenessEndpointName = newObj.Health.LivenessEndpointName + } + + if o.WebhookServer == nil { + port := 0 + if newObj.Webhook.Port != nil { + port = *newObj.Webhook.Port + } + o.WebhookServer = webhook.NewServer(webhook.Options{ + Port: port, + Host: newObj.Webhook.Host, + CertDir: newObj.Webhook.CertDir, + }) + } + + if newObj.Controller != nil { + if o.Controller.CacheSyncTimeout == 0 && newObj.Controller.CacheSyncTimeout != nil { + o.Controller.CacheSyncTimeout = *newObj.Controller.CacheSyncTimeout + } + + if len(o.Controller.GroupKindConcurrency) == 0 && len(newObj.Controller.GroupKindConcurrency) > 0 { + o.Controller.GroupKindConcurrency = newObj.Controller.GroupKindConcurrency + } + } + + return o, nil +} + +// AndFromOrDie will use options.AndFrom() and will panic if there are errors. +// +// Deprecated: This function has been deprecated and will be removed in a future release, +// The Component Configuration package has been unmaintained for over a year and is no longer +// actively developed. Users should migrate to their own configuration format +// and configure Manager.Options directly. +// See https://github.com/kubernetes-sigs/controller-runtime/issues/895 +// for more information, feedback, and comments. +func (o Options) AndFromOrDie(loader config.ControllerManagerConfiguration) Options { + o, err := o.AndFrom(loader) + if err != nil { + panic(fmt.Sprintf("could not parse config file: %v", err)) + } + return o +} + +func (o Options) setLeaderElectionConfig(obj v1alpha1.ControllerManagerConfigurationSpec) Options { + if obj.LeaderElection == nil { + // The source does not have any configuration; noop + return o + } + + if !o.LeaderElection && obj.LeaderElection.LeaderElect != nil { + o.LeaderElection = *obj.LeaderElection.LeaderElect + } + + if o.LeaderElectionResourceLock == "" && obj.LeaderElection.ResourceLock != "" { + o.LeaderElectionResourceLock = obj.LeaderElection.ResourceLock + } + + if o.LeaderElectionNamespace == "" && obj.LeaderElection.ResourceNamespace != "" { + o.LeaderElectionNamespace = obj.LeaderElection.ResourceNamespace + } + + if o.LeaderElectionID == "" && obj.LeaderElection.ResourceName != "" { + o.LeaderElectionID = obj.LeaderElection.ResourceName + } + + if o.LeaseDuration == nil && !reflect.DeepEqual(obj.LeaderElection.LeaseDuration, metav1.Duration{}) { + o.LeaseDuration = &obj.LeaderElection.LeaseDuration.Duration + } + + if o.RenewDeadline == nil && !reflect.DeepEqual(obj.LeaderElection.RenewDeadline, metav1.Duration{}) { + o.RenewDeadline = &obj.LeaderElection.RenewDeadline.Duration + } + + if o.RetryPeriod == nil && !reflect.DeepEqual(obj.LeaderElection.RetryPeriod, metav1.Duration{}) { + o.RetryPeriod = &obj.LeaderElection.RetryPeriod.Duration + } + + return o +} + +// defaultHealthProbeListener creates the default health probes listener bound to the given address. +func defaultHealthProbeListener(addr string) (net.Listener, error) { + if addr == "" || addr == "0" { + return nil, nil + } + + ln, err := net.Listen("tcp", addr) + if err != nil { + return nil, fmt.Errorf("error listening on %s: %w", addr, err) + } + return ln, nil +} + +// defaultPprofListener creates the default pprof listener bound to the given address. +func defaultPprofListener(addr string) (net.Listener, error) { + if addr == "" || addr == "0" { + return nil, nil + } + + ln, err := net.Listen("tcp", addr) + if err != nil { + return nil, fmt.Errorf("error listening on %s: %w", addr, err) + } + return ln, nil +} + +// defaultBaseContext is used as the BaseContext value in Options if one +// has not already been set. +func defaultBaseContext() context.Context { + return context.Background() +} + +// setOptionsDefaults set default values for Options fields. +func setOptionsDefaults(options Options) Options { + // Allow newResourceLock to be mocked + if options.newResourceLock == nil { + options.newResourceLock = leaderelection.NewResourceLock + } + + // Allow newRecorderProvider to be mocked + if options.newRecorderProvider == nil { + options.newRecorderProvider = intrec.NewProvider + } + + // This is duplicated with pkg/cluster, we need it here + // for the leader election and there to provide the user with + // an EventBroadcaster + if options.EventBroadcaster == nil { + // defer initialization to avoid leaking by default + options.makeBroadcaster = func() (record.EventBroadcaster, bool) { + return record.NewBroadcaster(), true + } + } else { + options.makeBroadcaster = func() (record.EventBroadcaster, bool) { + return options.EventBroadcaster, false + } + } + + if options.newMetricsServer == nil { + options.newMetricsServer = metricsserver.NewServer + } + leaseDuration, renewDeadline, retryPeriod := defaultLeaseDuration, defaultRenewDeadline, defaultRetryPeriod + if options.LeaseDuration == nil { + options.LeaseDuration = &leaseDuration + } + + if options.RenewDeadline == nil { + options.RenewDeadline = &renewDeadline + } + + if options.RetryPeriod == nil { + options.RetryPeriod = &retryPeriod + } + + if options.ReadinessEndpointName == "" { + options.ReadinessEndpointName = defaultReadinessEndpoint + } + + if options.LivenessEndpointName == "" { + options.LivenessEndpointName = defaultLivenessEndpoint + } + + if options.newHealthProbeListener == nil { + options.newHealthProbeListener = defaultHealthProbeListener + } + + if options.newPprofListener == nil { + options.newPprofListener = defaultPprofListener + } + + if options.GracefulShutdownTimeout == nil { + gracefulShutdownTimeout := defaultGracefulShutdownPeriod + options.GracefulShutdownTimeout = &gracefulShutdownTimeout + } + + if options.Logger.GetSink() == nil { + options.Logger = log.Log + } + + if options.BaseContext == nil { + options.BaseContext = defaultBaseContext + } + + if options.WebhookServer == nil { + options.WebhookServer = webhook.NewServer(webhook.Options{}) + } + + return options +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go new file mode 100644 index 00000000..96566f5d --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/runnable_group.go @@ -0,0 +1,301 @@ +package manager + +import ( + "context" + "errors" + "sync" + + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +var ( + errRunnableGroupStopped = errors.New("can't accept new runnable as stop procedure is already engaged") +) + +// readyRunnable encapsulates a runnable with +// a ready check. +type readyRunnable struct { + Runnable + Check runnableCheck + signalReady bool +} + +// runnableCheck can be passed to Add() to let the runnable group determine that a +// runnable is ready. A runnable check should block until a runnable is ready, +// if the returned result is false, the runnable is considered not ready and failed. +type runnableCheck func(ctx context.Context) bool + +// runnables handles all the runnables for a manager by grouping them accordingly to their +// type (webhooks, caches etc.). +type runnables struct { + HTTPServers *runnableGroup + Webhooks *runnableGroup + Caches *runnableGroup + LeaderElection *runnableGroup + Others *runnableGroup +} + +// newRunnables creates a new runnables object. +func newRunnables(baseContext BaseContextFunc, errChan chan error) *runnables { + return &runnables{ + HTTPServers: newRunnableGroup(baseContext, errChan), + Webhooks: newRunnableGroup(baseContext, errChan), + Caches: newRunnableGroup(baseContext, errChan), + LeaderElection: newRunnableGroup(baseContext, errChan), + Others: newRunnableGroup(baseContext, errChan), + } +} + +// Add adds a runnable to closest group of runnable that they belong to. +// +// Add should be able to be called before and after Start, but not after StopAndWait. +// Add should return an error when called during StopAndWait. +// The runnables added before Start are started when Start is called. +// The runnables added after Start are started directly. +func (r *runnables) Add(fn Runnable) error { + switch runnable := fn.(type) { + case *server: + return r.HTTPServers.Add(fn, nil) + case hasCache: + return r.Caches.Add(fn, func(ctx context.Context) bool { + return runnable.GetCache().WaitForCacheSync(ctx) + }) + case webhook.Server: + return r.Webhooks.Add(fn, nil) + case LeaderElectionRunnable: + if !runnable.NeedLeaderElection() { + return r.Others.Add(fn, nil) + } + return r.LeaderElection.Add(fn, nil) + default: + return r.LeaderElection.Add(fn, nil) + } +} + +// runnableGroup manages a group of runnables that are +// meant to be running together until StopAndWait is called. +// +// Runnables can be added to a group after the group has started +// but not after it's stopped or while shutting down. +type runnableGroup struct { + ctx context.Context + cancel context.CancelFunc + + start sync.Mutex + startOnce sync.Once + started bool + startQueue []*readyRunnable + startReadyCh chan *readyRunnable + + stop sync.RWMutex + stopOnce sync.Once + stopped bool + + // errChan is the error channel passed by the caller + // when the group is created. + // All errors are forwarded to this channel once they occur. + errChan chan error + + // ch is the internal channel where the runnables are read off from. + ch chan *readyRunnable + + // wg is an internal sync.WaitGroup that allows us to properly stop + // and wait for all the runnables to finish before returning. + wg *sync.WaitGroup +} + +func newRunnableGroup(baseContext BaseContextFunc, errChan chan error) *runnableGroup { + r := &runnableGroup{ + startReadyCh: make(chan *readyRunnable), + errChan: errChan, + ch: make(chan *readyRunnable), + wg: new(sync.WaitGroup), + } + + r.ctx, r.cancel = context.WithCancel(baseContext()) + return r +} + +// Started returns true if the group has started. +func (r *runnableGroup) Started() bool { + r.start.Lock() + defer r.start.Unlock() + return r.started +} + +// Start starts the group and waits for all +// initially registered runnables to start. +// It can only be called once, subsequent calls have no effect. +func (r *runnableGroup) Start(ctx context.Context) error { + var retErr error + + r.startOnce.Do(func() { + defer close(r.startReadyCh) + + // Start the internal reconciler. + go r.reconcile() + + // Start the group and queue up all + // the runnables that were added prior. + r.start.Lock() + r.started = true + for _, rn := range r.startQueue { + rn.signalReady = true + r.ch <- rn + } + r.start.Unlock() + + // If we don't have any queue, return. + if len(r.startQueue) == 0 { + return + } + + // Wait for all runnables to signal. + for { + select { + case <-ctx.Done(): + if err := ctx.Err(); !errors.Is(err, context.Canceled) { + retErr = err + } + case rn := <-r.startReadyCh: + for i, existing := range r.startQueue { + if existing == rn { + // Remove the item from the start queue. + r.startQueue = append(r.startQueue[:i], r.startQueue[i+1:]...) + break + } + } + // We're done waiting if the queue is empty, return. + if len(r.startQueue) == 0 { + return + } + } + } + }) + + return retErr +} + +// reconcile is our main entrypoint for every runnable added +// to this group. Its primary job is to read off the internal channel +// and schedule runnables while tracking their state. +func (r *runnableGroup) reconcile() { + for runnable := range r.ch { + // Handle stop. + // If the shutdown has been called we want to avoid + // adding new goroutines to the WaitGroup because Wait() + // panics if Add() is called after it. + { + r.stop.RLock() + if r.stopped { + // Drop any runnables if we're stopped. + r.errChan <- errRunnableGroupStopped + r.stop.RUnlock() + continue + } + + // Why is this here? + // When StopAndWait is called, if a runnable is in the process + // of being added, we could end up in a situation where + // the WaitGroup is incremented while StopAndWait has called Wait(), + // which would result in a panic. + r.wg.Add(1) + r.stop.RUnlock() + } + + // Start the runnable. + go func(rn *readyRunnable) { + go func() { + if rn.Check(r.ctx) { + if rn.signalReady { + r.startReadyCh <- rn + } + } + }() + + // If we return, the runnable ended cleanly + // or returned an error to the channel. + // + // We should always decrement the WaitGroup here. + defer r.wg.Done() + + // Start the runnable. + if err := rn.Start(r.ctx); err != nil { + r.errChan <- err + } + }(runnable) + } +} + +// Add should be able to be called before and after Start, but not after StopAndWait. +// Add should return an error when called during StopAndWait. +func (r *runnableGroup) Add(rn Runnable, ready runnableCheck) error { + r.stop.RLock() + if r.stopped { + r.stop.RUnlock() + return errRunnableGroupStopped + } + r.stop.RUnlock() + + if ready == nil { + ready = func(_ context.Context) bool { return true } + } + + readyRunnable := &readyRunnable{ + Runnable: rn, + Check: ready, + } + + // Handle start. + // If the overall runnable group isn't started yet + // we want to buffer the runnables and let Start() + // queue them up again later. + { + r.start.Lock() + + // Check if we're already started. + if !r.started { + // Store the runnable in the internal if not. + r.startQueue = append(r.startQueue, readyRunnable) + r.start.Unlock() + return nil + } + r.start.Unlock() + } + + // Enqueue the runnable. + r.ch <- readyRunnable + return nil +} + +// StopAndWait waits for all the runnables to finish before returning. +func (r *runnableGroup) StopAndWait(ctx context.Context) { + r.stopOnce.Do(func() { + // Close the reconciler channel once we're done. + defer close(r.ch) + + _ = r.Start(ctx) + r.stop.Lock() + // Store the stopped variable so we don't accept any new + // runnables for the time being. + r.stopped = true + r.stop.Unlock() + + // Cancel the internal channel. + r.cancel() + + done := make(chan struct{}) + go func() { + defer close(done) + // Wait for all the runnables to finish. + r.wg.Wait() + }() + + select { + case <-done: + // We're done, exit. + case <-ctx.Done(): + // Calling context has expired, exit. + } + }) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/server.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/server.go new file mode 100644 index 00000000..b6509f48 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/server.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 The Kubernetes Authors. + +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. +*/ + +package manager + +import ( + "context" + "errors" + "net" + "net/http" + + "github.com/go-logr/logr" +) + +// server is a general purpose HTTP server Runnable for a manager +// to serve some internal handlers such as health probes, metrics and profiling. +type server struct { + Kind string + Log logr.Logger + Server *http.Server + Listener net.Listener +} + +func (s *server) Start(ctx context.Context) error { + log := s.Log.WithValues("kind", s.Kind, "addr", s.Listener.Addr()) + + serverShutdown := make(chan struct{}) + go func() { + <-ctx.Done() + log.Info("shutting down server") + if err := s.Server.Shutdown(context.Background()); err != nil { + log.Error(err, "error shutting down server") + } + close(serverShutdown) + }() + + log.Info("starting server") + if err := s.Server.Serve(s.Listener); err != nil && !errors.Is(err, http.ErrServerClosed) { + return err + } + + <-serverShutdown + return nil +} + +func (s *server) NeedLeaderElection() bool { + return false +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go new file mode 100644 index 00000000..737cc7ef --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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. +*/ + +// Package signals contains libraries for handling signals to gracefully +// shutdown the manager in combination with Kubernetes pod graceful termination +// policy. +package signals diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go new file mode 100644 index 00000000..a79cfb42 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go @@ -0,0 +1,45 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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. +*/ + +package signals + +import ( + "context" + "os" + "os/signal" +) + +var onlyOneSignalHandler = make(chan struct{}) + +// SetupSignalHandler registers for SIGTERM and SIGINT. A context is returned +// which is canceled on one of these signals. If a second signal is caught, the program +// is terminated with exit code 1. +func SetupSignalHandler() context.Context { + close(onlyOneSignalHandler) // panics when called twice + + ctx, cancel := context.WithCancel(context.Background()) + + c := make(chan os.Signal, 2) + signal.Notify(c, shutdownSignals...) + go func() { + <-c + cancel() + <-c + os.Exit(1) // second signal. Exit directly. + }() + + return ctx +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go new file mode 100644 index 00000000..a0f00a73 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go @@ -0,0 +1,27 @@ +//go:build !windows +// +build !windows + +/* +Copyright 2017 The Kubernetes Authors. + +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. +*/ + +package signals + +import ( + "os" + "syscall" +) + +var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM} diff --git a/vendor/k8s.io/code-generator/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go similarity index 81% rename from vendor/k8s.io/code-generator/doc.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go index fd867306..4907d573 100644 --- a/vendor/k8s.io/code-generator/doc.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,4 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -package codegenerator // import "k8s.io/code-generator" +package signals + +import ( + "os" +) + +var shutdownSignals = []os.Signal{os.Interrupt} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go new file mode 100644 index 00000000..ff28998c --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go @@ -0,0 +1,71 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package metrics + +import ( + "context" + + "github.com/prometheus/client_golang/prometheus" + clientmetrics "k8s.io/client-go/tools/metrics" +) + +// this file contains setup logic to initialize the myriad of places +// that client-go registers metrics. We copy the names and formats +// from Kubernetes so that we match the core controllers. + +var ( + // client metrics. + + requestResult = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "rest_client_requests_total", + Help: "Number of HTTP requests, partitioned by status code, method, and host.", + }, + []string{"code", "method", "host"}, + ) +) + +func init() { + registerClientMetrics() +} + +// registerClientMetrics sets up the client latency metrics from client-go. +func registerClientMetrics() { + // register the metrics with our registry + Registry.MustRegister(requestResult) + + // register the metrics with client-go + clientmetrics.Register(clientmetrics.RegisterOpts{ + RequestResult: &resultAdapter{metric: requestResult}, + }) +} + +// this section contains adapters, implementations, and other sundry organic, artisanally +// hand-crafted syntax trees required to convince client-go that it actually wants to let +// someone use its metrics. + +// Client metrics adapters (method #1 for client-go metrics), +// copied (more-or-less directly) from k8s.io/kubernetes setup code +// (which isn't anywhere in an easily-importable place). + +type resultAdapter struct { + metric *prometheus.CounterVec +} + +func (r *resultAdapter) Increment(_ context.Context, code, method, host string) { + r.metric.WithLabelValues(code, method, host).Inc() +} diff --git a/hack/boilerplate/boilerplate.go.txt b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/doc.go similarity index 81% rename from hack/boilerplate/boilerplate.go.txt rename to vendor/sigs.k8s.io/controller-runtime/pkg/metrics/doc.go index 462a02bb..6ed9df95 100644 --- a/hack/boilerplate/boilerplate.go.txt +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/doc.go @@ -1,5 +1,5 @@ /* -Copyright YEAR The Kube Bind Authors. +Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,3 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +/* +Package metrics contains controller related metrics utilities +*/ +package metrics diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go new file mode 100644 index 00000000..a19c0996 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go @@ -0,0 +1,40 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "k8s.io/client-go/tools/leaderelection" +) + +// This file is copied and adapted from k8s.io/component-base/metrics/prometheus/clientgo/leaderelection +// which registers metrics to the k8s legacy Registry. We require very +// similar functionality, but must register metrics to a different Registry. + +var ( + leaderGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "leader_election_master_status", + Help: "Gauge of if the reporting system is master of the relevant lease, 0 indicates backup, 1 indicates master. 'name' is the string used to identify the lease. Please make sure to group by name.", + }, []string{"name"}) +) + +func init() { + Registry.MustRegister(leaderGauge) + leaderelection.SetProvider(leaderelectionMetricsProvider{}) +} + +type leaderelectionMetricsProvider struct{} + +func (leaderelectionMetricsProvider) NewLeaderMetric() leaderelection.SwitchMetric { + return &switchAdapter{gauge: leaderGauge} +} + +type switchAdapter struct { + gauge *prometheus.GaugeVec +} + +func (s *switchAdapter) On(name string) { + s.gauge.WithLabelValues(name).Set(1.0) +} + +func (s *switchAdapter) Off(name string) { + s.gauge.WithLabelValues(name).Set(0.0) +} diff --git a/vendor/k8s.io/gengo/examples/set-gen/generators/tags.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/registry.go similarity index 53% rename from vendor/k8s.io/gengo/examples/set-gen/generators/tags.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/metrics/registry.go index 52e87677..ce17124d 100644 --- a/vendor/k8s.io/gengo/examples/set-gen/generators/tags.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/registry.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,20 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -package generators +package metrics -import ( - "k8s.io/gengo/types" - "k8s.io/klog/v2" -) +import "github.com/prometheus/client_golang/prometheus" -// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if -// it exists, the value is boolean. If the tag did not exist, it returns -// false. -func extractBoolTagOrDie(key string, lines []string) bool { - val, err := types.ExtractSingleBoolCommentTag("+", key, false, lines) - if err != nil { - klog.Fatalf(err.Error()) - } - return val +// RegistererGatherer combines both parts of the API of a Prometheus +// registry, both the Registerer and the Gatherer interfaces. +type RegistererGatherer interface { + prometheus.Registerer + prometheus.Gatherer } + +// Registry is a prometheus registry for storing metrics within the +// controller-runtime. +var Registry RegistererGatherer = prometheus.NewRegistry() diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/server/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/server/doc.go new file mode 100644 index 00000000..4c42f6ee --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/server/doc.go @@ -0,0 +1,26 @@ +/* +Copyright 2023 The Kubernetes Authors. + +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. +*/ + +/* +Package server provides the metrics server implementation. +*/ +package server + +import ( + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("metrics") diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/server/server.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/server/server.go new file mode 100644 index 00000000..e10c5c21 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/server/server.go @@ -0,0 +1,312 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package server + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "net/http" + "os" + "path/filepath" + "sync" + "time" + + "github.com/go-logr/logr" + "github.com/prometheus/client_golang/prometheus/promhttp" + "k8s.io/client-go/rest" + certutil "k8s.io/client-go/util/cert" + + "sigs.k8s.io/controller-runtime/pkg/certwatcher" + "sigs.k8s.io/controller-runtime/pkg/internal/httpserver" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +const ( + defaultMetricsEndpoint = "/metrics" +) + +// DefaultBindAddress is the default bind address for the metrics server. +var DefaultBindAddress = ":8080" + +// Server is a server that serves metrics. +type Server interface { + // NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates + // the metrics server doesn't need leader election. + NeedLeaderElection() bool + + // Start runs the server. + // It will install the metrics related resources depending on the server configuration. + Start(ctx context.Context) error +} + +// Options are all available options for the metrics.Server +type Options struct { + // SecureServing enables serving metrics via https. + // Per default metrics will be served via http. + SecureServing bool + + // BindAddress is the bind address for the metrics server. + // It will be defaulted to ":8080" if unspecified. + // Set this to "0" to disable the metrics server. + BindAddress string + + // ExtraHandlers contains a map of handlers (by path) which will be added to the metrics server. + // This might be useful to register diagnostic endpoints e.g. pprof. + // Note that pprof endpoints are meant to be sensitive and shouldn't be exposed publicly. + // If the simple path -> handler mapping offered here is not enough, a new http + // server/listener should be added as Runnable to the manager via the Add method. + ExtraHandlers map[string]http.Handler + + // FilterProvider provides a filter which is a func that is added around + // the metrics and the extra handlers on the metrics server. + // This can be e.g. used to enforce authentication and authorization on the handlers + // endpoint by setting this field to filters.WithAuthenticationAndAuthorization. + FilterProvider func(c *rest.Config, httpClient *http.Client) (Filter, error) + + // CertDir is the directory that contains the server key and certificate. Defaults to + // /k8s-metrics-server/serving-certs. + // + // Note: This option is only used when TLSOpts does not set GetCertificate. + // Note: If certificate or key doesn't exist a self-signed certificate will be used. + CertDir string + + // CertName is the server certificate name. Defaults to tls.crt. + // + // Note: This option is only used when TLSOpts does not set GetCertificate. + // Note: If certificate or key doesn't exist a self-signed certificate will be used. + CertName string + + // KeyName is the server key name. Defaults to tls.key. + // + // Note: This option is only used when TLSOpts does not set GetCertificate. + // Note: If certificate or key doesn't exist a self-signed certificate will be used. + KeyName string + + // TLSOpts is used to allow configuring the TLS config used for the server. + // This also allows providing a certificate via GetCertificate. + TLSOpts []func(*tls.Config) +} + +// Filter is a func that is added around metrics and extra handlers on the metrics server. +type Filter func(log logr.Logger, handler http.Handler) (http.Handler, error) + +// NewServer constructs a new metrics.Server from the provided options. +func NewServer(o Options, config *rest.Config, httpClient *http.Client) (Server, error) { + o.setDefaults() + + // Skip server creation if metrics are disabled. + if o.BindAddress == "0" { + return nil, nil + } + + // Validate that ExtraHandlers is not overwriting the default /metrics endpoint. + if o.ExtraHandlers != nil { + if _, ok := o.ExtraHandlers[defaultMetricsEndpoint]; ok { + return nil, fmt.Errorf("overriding builtin %s endpoint is not allowed", defaultMetricsEndpoint) + } + } + + // Create the metrics filter if a FilterProvider is set. + var metricsFilter Filter + if o.FilterProvider != nil { + var err error + metricsFilter, err = o.FilterProvider(config, httpClient) + if err != nil { + return nil, fmt.Errorf("filter provider failed to create filter for the metrics server: %w", err) + } + } + + return &defaultServer{ + metricsFilter: metricsFilter, + options: o, + }, nil +} + +// defaultServer is the default implementation used for Server. +type defaultServer struct { + options Options + + // metricsFilter is a filter which is added around + // the metrics and the extra handlers on the metrics server. + metricsFilter Filter + + // mu protects access to the bindAddr field. + mu sync.RWMutex + + // bindAddr is used to store the bindAddr after the listener has been created. + // This is used during testing to figure out the port that has been chosen randomly. + bindAddr string +} + +// setDefaults does defaulting for the Server. +func (o *Options) setDefaults() { + if o.BindAddress == "" { + o.BindAddress = DefaultBindAddress + } + + if len(o.CertDir) == 0 { + o.CertDir = filepath.Join(os.TempDir(), "k8s-metrics-server", "serving-certs") + } + + if len(o.CertName) == 0 { + o.CertName = "tls.crt" + } + + if len(o.KeyName) == 0 { + o.KeyName = "tls.key" + } +} + +// NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates +// the metrics server doesn't need leader election. +func (*defaultServer) NeedLeaderElection() bool { + return false +} + +// Start runs the server. +// It will install the metrics related resources depend on the server configuration. +func (s *defaultServer) Start(ctx context.Context) error { + log.Info("Starting metrics server") + + listener, err := s.createListener(ctx, log) + if err != nil { + return fmt.Errorf("failed to start metrics server: failed to create listener: %w", err) + } + // Storing bindAddr here so we can retrieve it during testing via GetBindAddr. + s.mu.Lock() + s.bindAddr = listener.Addr().String() + s.mu.Unlock() + + mux := http.NewServeMux() + + handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{ + ErrorHandling: promhttp.HTTPErrorOnError, + }) + if s.metricsFilter != nil { + log := log.WithValues("path", defaultMetricsEndpoint) + var err error + handler, err = s.metricsFilter(log, handler) + if err != nil { + return fmt.Errorf("failed to start metrics server: failed to add metrics filter: %w", err) + } + } + // TODO(JoelSpeed): Use existing Kubernetes machinery for serving metrics + mux.Handle(defaultMetricsEndpoint, handler) + + for path, extraHandler := range s.options.ExtraHandlers { + if s.metricsFilter != nil { + log := log.WithValues("path", path) + var err error + extraHandler, err = s.metricsFilter(log, extraHandler) + if err != nil { + return fmt.Errorf("failed to start metrics server: failed to add metrics filter to extra handler for path %s: %w", path, err) + } + } + mux.Handle(path, extraHandler) + } + + log.Info("Serving metrics server", "bindAddress", s.options.BindAddress, "secure", s.options.SecureServing) + + srv := httpserver.New(mux) + + idleConnsClosed := make(chan struct{}) + go func() { + <-ctx.Done() + log.Info("Shutting down metrics server with timeout of 1 minute") + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { + // Error from closing listeners, or context timeout + log.Error(err, "error shutting down the HTTP server") + } + close(idleConnsClosed) + }() + + if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed { + return err + } + + <-idleConnsClosed + return nil +} + +func (s *defaultServer) createListener(ctx context.Context, log logr.Logger) (net.Listener, error) { + if !s.options.SecureServing { + return net.Listen("tcp", s.options.BindAddress) + } + + cfg := &tls.Config{ //nolint:gosec + NextProtos: []string{"h2"}, + } + // fallback TLS config ready, will now mutate if passer wants full control over it + for _, op := range s.options.TLSOpts { + op(cfg) + } + + if cfg.GetCertificate == nil { + certPath := filepath.Join(s.options.CertDir, s.options.CertName) + keyPath := filepath.Join(s.options.CertDir, s.options.KeyName) + + _, certErr := os.Stat(certPath) + certExists := !os.IsNotExist(certErr) + _, keyErr := os.Stat(keyPath) + keyExists := !os.IsNotExist(keyErr) + if certExists && keyExists { + // Create the certificate watcher and + // set the config's GetCertificate on the TLSConfig + certWatcher, err := certwatcher.New(certPath, keyPath) + if err != nil { + return nil, err + } + cfg.GetCertificate = certWatcher.GetCertificate + + go func() { + if err := certWatcher.Start(ctx); err != nil { + log.Error(err, "certificate watcher error") + } + }() + } + } + + // If cfg.GetCertificate is still nil, i.e. we didn't configure a cert watcher, fallback to a self-signed certificate. + if cfg.GetCertificate == nil { + // Note: Using self-signed certificates here should be good enough. It's just important that we + // encrypt the communication. For example kube-controller-manager also uses a self-signed certificate + // for the metrics endpoint per default. + cert, key, err := certutil.GenerateSelfSignedCertKeyWithFixtures("localhost", []net.IP{{127, 0, 0, 1}}, nil, "") + if err != nil { + return nil, fmt.Errorf("failed to generate self-signed certificate for metrics server: %w", err) + } + + keyPair, err := tls.X509KeyPair(cert, key) + if err != nil { + return nil, fmt.Errorf("failed to create self-signed key pair for metrics server: %w", err) + } + cfg.Certificates = []tls.Certificate{keyPair} + } + + return tls.Listen("tcp", s.options.BindAddress, cfg) +} + +func (s *defaultServer) GetBindAddr() string { + s.mu.RLock() + defer s.mu.RUnlock() + return s.bindAddr +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go new file mode 100644 index 00000000..cff1de4c --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go @@ -0,0 +1,130 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "k8s.io/client-go/util/workqueue" +) + +// This file is copied and adapted from k8s.io/component-base/metrics/prometheus/workqueue +// which registers metrics to the k8s legacy Registry. We require very +// similar functionality, but must register metrics to a different Registry. + +// Metrics subsystem and all keys used by the workqueue. +const ( + WorkQueueSubsystem = "workqueue" + DepthKey = "depth" + AddsKey = "adds_total" + QueueLatencyKey = "queue_duration_seconds" + WorkDurationKey = "work_duration_seconds" + UnfinishedWorkKey = "unfinished_work_seconds" + LongestRunningProcessorKey = "longest_running_processor_seconds" + RetriesKey = "retries_total" +) + +var ( + depth = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: DepthKey, + Help: "Current depth of workqueue", + }, []string{"name"}) + + adds = prometheus.NewCounterVec(prometheus.CounterOpts{ + Subsystem: WorkQueueSubsystem, + Name: AddsKey, + Help: "Total number of adds handled by workqueue", + }, []string{"name"}) + + latency = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Subsystem: WorkQueueSubsystem, + Name: QueueLatencyKey, + Help: "How long in seconds an item stays in workqueue before being requested", + Buckets: prometheus.ExponentialBuckets(10e-9, 10, 12), + }, []string{"name"}) + + workDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Subsystem: WorkQueueSubsystem, + Name: WorkDurationKey, + Help: "How long in seconds processing an item from workqueue takes.", + Buckets: prometheus.ExponentialBuckets(10e-9, 10, 12), + }, []string{"name"}) + + unfinished = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: UnfinishedWorkKey, + Help: "How many seconds of work has been done that " + + "is in progress and hasn't been observed by work_duration. Large " + + "values indicate stuck threads. One can deduce the number of stuck " + + "threads by observing the rate at which this increases.", + }, []string{"name"}) + + longestRunningProcessor = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: LongestRunningProcessorKey, + Help: "How many seconds has the longest running " + + "processor for workqueue been running.", + }, []string{"name"}) + + retries = prometheus.NewCounterVec(prometheus.CounterOpts{ + Subsystem: WorkQueueSubsystem, + Name: RetriesKey, + Help: "Total number of retries handled by workqueue", + }, []string{"name"}) +) + +func init() { + Registry.MustRegister(depth) + Registry.MustRegister(adds) + Registry.MustRegister(latency) + Registry.MustRegister(workDuration) + Registry.MustRegister(unfinished) + Registry.MustRegister(longestRunningProcessor) + Registry.MustRegister(retries) + + workqueue.SetProvider(workqueueMetricsProvider{}) +} + +type workqueueMetricsProvider struct{} + +func (workqueueMetricsProvider) NewDepthMetric(name string) workqueue.GaugeMetric { + return depth.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewAddsMetric(name string) workqueue.CounterMetric { + return adds.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewLatencyMetric(name string) workqueue.HistogramMetric { + return latency.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewWorkDurationMetric(name string) workqueue.HistogramMetric { + return workDuration.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewUnfinishedWorkSecondsMetric(name string) workqueue.SettableGaugeMetric { + return unfinished.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewLongestRunningProcessorSecondsMetric(name string) workqueue.SettableGaugeMetric { + return longestRunningProcessor.WithLabelValues(name) +} + +func (workqueueMetricsProvider) NewRetriesMetric(name string) workqueue.CounterMetric { + return retries.WithLabelValues(name) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/doc.go new file mode 100644 index 00000000..e498107e --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package predicate defines Predicates used by Controllers to filter Events before they are provided to EventHandlers. +*/ +package predicate diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go b/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go new file mode 100644 index 00000000..31463587 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go @@ -0,0 +1,360 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package predicate + +import ( + "reflect" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("predicate").WithName("eventFilters") + +// Predicate filters events before enqueuing the keys. +type Predicate interface { + // Create returns true if the Create event should be processed + Create(event.CreateEvent) bool + + // Delete returns true if the Delete event should be processed + Delete(event.DeleteEvent) bool + + // Update returns true if the Update event should be processed + Update(event.UpdateEvent) bool + + // Generic returns true if the Generic event should be processed + Generic(event.GenericEvent) bool +} + +var _ Predicate = Funcs{} +var _ Predicate = ResourceVersionChangedPredicate{} +var _ Predicate = GenerationChangedPredicate{} +var _ Predicate = AnnotationChangedPredicate{} +var _ Predicate = or{} +var _ Predicate = and{} +var _ Predicate = not{} + +// Funcs is a function that implements Predicate. +type Funcs struct { + // Create returns true if the Create event should be processed + CreateFunc func(event.CreateEvent) bool + + // Delete returns true if the Delete event should be processed + DeleteFunc func(event.DeleteEvent) bool + + // Update returns true if the Update event should be processed + UpdateFunc func(event.UpdateEvent) bool + + // Generic returns true if the Generic event should be processed + GenericFunc func(event.GenericEvent) bool +} + +// Create implements Predicate. +func (p Funcs) Create(e event.CreateEvent) bool { + if p.CreateFunc != nil { + return p.CreateFunc(e) + } + return true +} + +// Delete implements Predicate. +func (p Funcs) Delete(e event.DeleteEvent) bool { + if p.DeleteFunc != nil { + return p.DeleteFunc(e) + } + return true +} + +// Update implements Predicate. +func (p Funcs) Update(e event.UpdateEvent) bool { + if p.UpdateFunc != nil { + return p.UpdateFunc(e) + } + return true +} + +// Generic implements Predicate. +func (p Funcs) Generic(e event.GenericEvent) bool { + if p.GenericFunc != nil { + return p.GenericFunc(e) + } + return true +} + +// NewPredicateFuncs returns a predicate funcs that applies the given filter function +// on CREATE, UPDATE, DELETE and GENERIC events. For UPDATE events, the filter is applied +// to the new object. +func NewPredicateFuncs(filter func(object client.Object) bool) Funcs { + return Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return filter(e.Object) + }, + UpdateFunc: func(e event.UpdateEvent) bool { + return filter(e.ObjectNew) + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return filter(e.Object) + }, + GenericFunc: func(e event.GenericEvent) bool { + return filter(e.Object) + }, + } +} + +// ResourceVersionChangedPredicate implements a default update predicate function on resource version change. +type ResourceVersionChangedPredicate struct { + Funcs +} + +// Update implements default UpdateEvent filter for validating resource version change. +func (ResourceVersionChangedPredicate) Update(e event.UpdateEvent) bool { + if e.ObjectOld == nil { + log.Error(nil, "Update event has no old object to update", "event", e) + return false + } + if e.ObjectNew == nil { + log.Error(nil, "Update event has no new object to update", "event", e) + return false + } + + return e.ObjectNew.GetResourceVersion() != e.ObjectOld.GetResourceVersion() +} + +// GenerationChangedPredicate implements a default update predicate function on Generation change. +// +// This predicate will skip update events that have no change in the object's metadata.generation field. +// The metadata.generation field of an object is incremented by the API server when writes are made to the spec field of an object. +// This allows a controller to ignore update events where the spec is unchanged, and only the metadata and/or status fields are changed. +// +// For CustomResource objects the Generation is only incremented when the status subresource is enabled. +// +// Caveats: +// +// * The assumption that the Generation is incremented only on writing to the spec does not hold for all APIs. +// E.g For Deployment objects the Generation is also incremented on writes to the metadata.annotations field. +// For object types other than CustomResources be sure to verify which fields will trigger a Generation increment when they are written to. +// +// * With this predicate, any update events with writes only to the status field will not be reconciled. +// So in the event that the status block is overwritten or wiped by someone else the controller will not self-correct to restore the correct status. +type GenerationChangedPredicate struct { + Funcs +} + +// Update implements default UpdateEvent filter for validating generation change. +func (GenerationChangedPredicate) Update(e event.UpdateEvent) bool { + if e.ObjectOld == nil { + log.Error(nil, "Update event has no old object to update", "event", e) + return false + } + if e.ObjectNew == nil { + log.Error(nil, "Update event has no new object for update", "event", e) + return false + } + + return e.ObjectNew.GetGeneration() != e.ObjectOld.GetGeneration() +} + +// AnnotationChangedPredicate implements a default update predicate function on annotation change. +// +// This predicate will skip update events that have no change in the object's annotation. +// It is intended to be used in conjunction with the GenerationChangedPredicate, as in the following example: +// +// Controller.Watch( +// &source.Kind{Type: v1.MyCustomKind}, +// &handler.EnqueueRequestForObject{}, +// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.AnnotationChangedPredicate{})) +// +// This is mostly useful for controllers that needs to trigger both when the resource's generation is incremented +// (i.e., when the resource' .spec changes), or an annotation changes (e.g., for a staging/alpha API). +type AnnotationChangedPredicate struct { + Funcs +} + +// Update implements default UpdateEvent filter for validating annotation change. +func (AnnotationChangedPredicate) Update(e event.UpdateEvent) bool { + if e.ObjectOld == nil { + log.Error(nil, "Update event has no old object to update", "event", e) + return false + } + if e.ObjectNew == nil { + log.Error(nil, "Update event has no new object for update", "event", e) + return false + } + + return !reflect.DeepEqual(e.ObjectNew.GetAnnotations(), e.ObjectOld.GetAnnotations()) +} + +// LabelChangedPredicate implements a default update predicate function on label change. +// +// This predicate will skip update events that have no change in the object's label. +// It is intended to be used in conjunction with the GenerationChangedPredicate, as in the following example: +// +// Controller.Watch( +// +// &source.Kind{Type: v1.MyCustomKind}, +// &handler.EnqueueRequestForObject{}, +// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{})) +// +// This will be helpful when object's labels is carrying some extra specification information beyond object's spec, +// and the controller will be triggered if any valid spec change (not only in spec, but also in labels) happens. +type LabelChangedPredicate struct { + Funcs +} + +// Update implements default UpdateEvent filter for checking label change. +func (LabelChangedPredicate) Update(e event.UpdateEvent) bool { + if e.ObjectOld == nil { + log.Error(nil, "Update event has no old object to update", "event", e) + return false + } + if e.ObjectNew == nil { + log.Error(nil, "Update event has no new object for update", "event", e) + return false + } + + return !reflect.DeepEqual(e.ObjectNew.GetLabels(), e.ObjectOld.GetLabels()) +} + +// And returns a composite predicate that implements a logical AND of the predicates passed to it. +func And(predicates ...Predicate) Predicate { + return and{predicates} +} + +type and struct { + predicates []Predicate +} + +func (a and) Create(e event.CreateEvent) bool { + for _, p := range a.predicates { + if !p.Create(e) { + return false + } + } + return true +} + +func (a and) Update(e event.UpdateEvent) bool { + for _, p := range a.predicates { + if !p.Update(e) { + return false + } + } + return true +} + +func (a and) Delete(e event.DeleteEvent) bool { + for _, p := range a.predicates { + if !p.Delete(e) { + return false + } + } + return true +} + +func (a and) Generic(e event.GenericEvent) bool { + for _, p := range a.predicates { + if !p.Generic(e) { + return false + } + } + return true +} + +// Or returns a composite predicate that implements a logical OR of the predicates passed to it. +func Or(predicates ...Predicate) Predicate { + return or{predicates} +} + +type or struct { + predicates []Predicate +} + +func (o or) Create(e event.CreateEvent) bool { + for _, p := range o.predicates { + if p.Create(e) { + return true + } + } + return false +} + +func (o or) Update(e event.UpdateEvent) bool { + for _, p := range o.predicates { + if p.Update(e) { + return true + } + } + return false +} + +func (o or) Delete(e event.DeleteEvent) bool { + for _, p := range o.predicates { + if p.Delete(e) { + return true + } + } + return false +} + +func (o or) Generic(e event.GenericEvent) bool { + for _, p := range o.predicates { + if p.Generic(e) { + return true + } + } + return false +} + +// Not returns a predicate that implements a logical NOT of the predicate passed to it. +func Not(predicate Predicate) Predicate { + return not{predicate} +} + +type not struct { + predicate Predicate +} + +func (n not) Create(e event.CreateEvent) bool { + return !n.predicate.Create(e) +} + +func (n not) Update(e event.UpdateEvent) bool { + return !n.predicate.Update(e) +} + +func (n not) Delete(e event.DeleteEvent) bool { + return !n.predicate.Delete(e) +} + +func (n not) Generic(e event.GenericEvent) bool { + return !n.predicate.Generic(e) +} + +// LabelSelectorPredicate constructs a Predicate from a LabelSelector. +// Only objects matching the LabelSelector will be admitted. +func LabelSelectorPredicate(s metav1.LabelSelector) (Predicate, error) { + selector, err := metav1.LabelSelectorAsSelector(&s) + if err != nil { + return Funcs{}, err + } + return NewPredicateFuncs(func(o client.Object) bool { + return selector.Matches(labels.Set(o.GetLabels())) + }), nil +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/ratelimiter/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/ratelimiter/doc.go new file mode 100644 index 00000000..a01d603f --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/ratelimiter/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +/* +Package ratelimiter defines rate limiters used by Controllers to limit how frequently requests may be queued. + +Typical rate limiters that can be used are implemented in client-go's workqueue package. +*/ +package ratelimiter diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/ratelimiter/ratelimiter.go b/vendor/sigs.k8s.io/controller-runtime/pkg/ratelimiter/ratelimiter.go new file mode 100644 index 00000000..565a3a22 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/ratelimiter/ratelimiter.go @@ -0,0 +1,30 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package ratelimiter + +import "time" + +// RateLimiter is an identical interface of client-go workqueue RateLimiter. +type RateLimiter interface { + // When gets an item and gets to decide how long that item should wait + When(item interface{}) time.Duration + // Forget indicates that an item is finished being retried. Doesn't matter whether its for perm failing + // or for success, we'll stop tracking it + Forget(item interface{}) + // NumRequeues returns back how many failures the item has had + NumRequeues(item interface{}) int +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/doc.go new file mode 100644 index 00000000..d221dd7b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package reconcile defines the Reconciler interface to implement Kubernetes APIs. Reconciler is provided +to Controllers at creation time as the API implementation. +*/ +package reconcile diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go b/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go new file mode 100644 index 00000000..f1cce87c --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go @@ -0,0 +1,170 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package reconcile + +import ( + "context" + "errors" + "reflect" + "time" + + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Result contains the result of a Reconciler invocation. +type Result struct { + // Requeue tells the Controller to requeue the reconcile key. Defaults to false. + Requeue bool + + // RequeueAfter if greater than 0, tells the Controller to requeue the reconcile key after the Duration. + // Implies that Requeue is true, there is no need to set Requeue to true at the same time as RequeueAfter. + RequeueAfter time.Duration +} + +// IsZero returns true if this result is empty. +func (r *Result) IsZero() bool { + if r == nil { + return true + } + return *r == Result{} +} + +// Request contains the information necessary to reconcile a Kubernetes object. This includes the +// information to uniquely identify the object - its Name and Namespace. It does NOT contain information about +// any specific Event or the object contents itself. +type Request struct { + // NamespacedName is the name and namespace of the object to reconcile. + types.NamespacedName +} + +/* +Reconciler implements a Kubernetes API for a specific Resource by Creating, Updating or Deleting Kubernetes +objects, or by making changes to systems external to the cluster (e.g. cloudproviders, github, etc). + +reconcile implementations compare the state specified in an object by a user against the actual cluster state, +and then perform operations to make the actual cluster state reflect the state specified by the user. + +Typically, reconcile is triggered by a Controller in response to cluster Events (e.g. Creating, Updating, +Deleting Kubernetes objects) or external Events (GitHub Webhooks, polling external sources, etc). + +Example reconcile Logic: + +* Read an object and all the Pods it owns. +* Observe that the object spec specifies 5 replicas but actual cluster contains only 1 Pod replica. +* Create 4 Pods and set their OwnerReferences to the object. + +reconcile may be implemented as either a type: + + type reconciler struct {} + + func (reconciler) Reconcile(ctx context.Context, o reconcile.Request) (reconcile.Result, error) { + // Implement business logic of reading and writing objects here + return reconcile.Result{}, nil + } + +Or as a function: + + reconcile.Func(func(ctx context.Context, o reconcile.Request) (reconcile.Result, error) { + // Implement business logic of reading and writing objects here + return reconcile.Result{}, nil + }) + +Reconciliation is level-based, meaning action isn't driven off changes in individual Events, but instead is +driven by actual cluster state read from the apiserver or a local cache. +For example if responding to a Pod Delete Event, the Request won't contain that a Pod was deleted, +instead the reconcile function observes this when reading the cluster state and seeing the Pod as missing. +*/ +type Reconciler interface { + // Reconcile performs a full reconciliation for the object referred to by the Request. + // + // If the returned error is non-nil, the Result is ignored and the request will be + // requeued using exponential backoff. The only exception is if the error is a + // TerminalError in which case no requeuing happens. + // + // If the error is nil and the returned Result has a non-zero result.RequeueAfter, the request + // will be requeued after the specified duration. + // + // If the error is nil and result.RequeueAfter is zero and result.Requeue is true, the request + // will be requeued using exponential backoff. + Reconcile(context.Context, Request) (Result, error) +} + +// Func is a function that implements the reconcile interface. +type Func func(context.Context, Request) (Result, error) + +var _ Reconciler = Func(nil) + +// Reconcile implements Reconciler. +func (r Func) Reconcile(ctx context.Context, o Request) (Result, error) { return r(ctx, o) } + +// ObjectReconciler is a specialized version of Reconciler that acts on instances of client.Object. Each reconciliation +// event gets the associated object from Kubernetes before passing it to Reconcile. An ObjectReconciler can be used in +// Builder.Complete by calling AsReconciler. See Reconciler for more details. +type ObjectReconciler[T client.Object] interface { + Reconcile(context.Context, T) (Result, error) +} + +// AsReconciler creates a Reconciler based on the given ObjectReconciler. +func AsReconciler[T client.Object](client client.Client, rec ObjectReconciler[T]) Reconciler { + return &objectReconcilerAdapter[T]{ + objReconciler: rec, + client: client, + } +} + +type objectReconcilerAdapter[T client.Object] struct { + objReconciler ObjectReconciler[T] + client client.Client +} + +// Reconcile implements Reconciler. +func (a *objectReconcilerAdapter[T]) Reconcile(ctx context.Context, req Request) (Result, error) { + o := reflect.New(reflect.TypeOf(*new(T)).Elem()).Interface().(T) + if err := a.client.Get(ctx, req.NamespacedName, o); err != nil { + return Result{}, client.IgnoreNotFound(err) + } + + return a.objReconciler.Reconcile(ctx, o) +} + +// TerminalError is an error that will not be retried but still be logged +// and recorded in metrics. +func TerminalError(wrapped error) error { + return &terminalError{err: wrapped} +} + +type terminalError struct { + err error +} + +// This function will return nil if te.err is nil. +func (te *terminalError) Unwrap() error { + return te.err +} + +func (te *terminalError) Error() string { + if te.err == nil { + return "nil terminal error" + } + return "terminal error: " + te.err.Error() +} + +func (te *terminalError) Is(target error) bool { + tp := &terminalError{} + return errors.As(target, &tp) +} diff --git a/vendor/k8s.io/code-generator/cmd/register-gen/args/args.go b/vendor/sigs.k8s.io/controller-runtime/pkg/recorder/recorder.go similarity index 53% rename from vendor/k8s.io/code-generator/cmd/register-gen/args/args.go rename to vendor/sigs.k8s.io/controller-runtime/pkg/recorder/recorder.go index 2e3ab084..f093f0a7 100644 --- a/vendor/k8s.io/code-generator/cmd/register-gen/args/args.go +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/recorder/recorder.go @@ -14,26 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -package args +// Package recorder defines interfaces for working with Kubernetes event recorders. +// +// You can use these to emit Kubernetes events associated with a particular Kubernetes +// object. +package recorder import ( - "fmt" - - "k8s.io/gengo/args" + "k8s.io/client-go/tools/record" ) -// NewDefaults returns default arguments for the generator. -func NewDefaults() *args.GeneratorArgs { - genericArgs := args.Default().WithoutDefaultFlagParsing() - genericArgs.OutputFileBaseName = "zz_generated.register" - return genericArgs -} - -// Validate checks the given arguments. -func Validate(genericArgs *args.GeneratorArgs) error { - if len(genericArgs.OutputFileBaseName) == 0 { - return fmt.Errorf("output file base name cannot be empty") - } - - return nil +// Provider knows how to generate new event recorders with given name. +type Provider interface { + // NewRecorder returns an EventRecorder with given name. + GetEventRecorderFor(name string) record.EventRecorder } diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go b/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go new file mode 100644 index 00000000..55ebe217 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go @@ -0,0 +1,93 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +// Package scheme contains utilities for gradually building Schemes, +// which contain information associating Go types with Kubernetes +// groups, versions, and kinds. +// +// Each API group should define a utility function +// called AddToScheme for adding its types to a Scheme: +// +// // in package myapigroupv1... +// var ( +// SchemeGroupVersion = schema.GroupVersion{Group: "my.api.group", Version: "v1"} +// SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} +// AddToScheme = SchemeBuilder.AddToScheme +// ) +// +// func init() { +// SchemeBuilder.Register(&MyType{}, &MyTypeList) +// } +// var ( +// scheme *runtime.Scheme = runtime.NewScheme() +// ) +// +// This also true of the built-in Kubernetes types. Then, in the entrypoint for +// your manager, assemble the scheme containing exactly the types you need, +// panicing if scheme registration failed. For instance, if our controller needs +// types from the core/v1 API group (e.g. Pod), plus types from my.api.group/v1: +// +// func init() { +// utilruntime.Must(myapigroupv1.AddToScheme(scheme)) +// utilruntime.Must(kubernetesscheme.AddToScheme(scheme)) +// } +// +// func main() { +// mgr := controllers.NewManager(context.Background(), controllers.GetConfigOrDie(), manager.Options{ +// Scheme: scheme, +// }) +// // ... +// } +package scheme + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// Builder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds. +type Builder struct { + GroupVersion schema.GroupVersion + runtime.SchemeBuilder +} + +// Register adds one or more objects to the SchemeBuilder so they can be added to a Scheme. Register mutates bld. +func (bld *Builder) Register(object ...runtime.Object) *Builder { + bld.SchemeBuilder.Register(func(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(bld.GroupVersion, object...) + metav1.AddToGroupVersion(scheme, bld.GroupVersion) + return nil + }) + return bld +} + +// RegisterAll registers all types from the Builder argument. RegisterAll mutates bld. +func (bld *Builder) RegisterAll(b *Builder) *Builder { + bld.SchemeBuilder = append(bld.SchemeBuilder, b.SchemeBuilder...) + return bld +} + +// AddToScheme adds all registered types to s. +func (bld *Builder) AddToScheme(s *runtime.Scheme) error { + return bld.SchemeBuilder.AddToScheme(s) +} + +// Build returns a new Scheme containing the registered types. +func (bld *Builder) Build() (*runtime.Scheme, error) { + s := runtime.NewScheme() + return s, bld.AddToScheme(s) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/source/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/source/doc.go new file mode 100644 index 00000000..31935c83 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/source/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package source provides event streams to hook up to Controllers with Controller.Watch. Events are +used with handler.EventHandlers to enqueue reconcile.Requests and trigger Reconciles for Kubernetes +objects. +*/ +package source diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go b/vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go new file mode 100644 index 00000000..099c8d68 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go @@ -0,0 +1,225 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package source + +import ( + "context" + "fmt" + "sync" + + "k8s.io/client-go/util/workqueue" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + internal "sigs.k8s.io/controller-runtime/pkg/internal/source" + + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +const ( + // defaultBufferSize is the default number of event notifications that can be buffered. + defaultBufferSize = 1024 +) + +// Source is a source of events (eh.g. Create, Update, Delete operations on Kubernetes Objects, Webhook callbacks, etc) +// which should be processed by event.EventHandlers to enqueue reconcile.Requests. +// +// * Use Kind for events originating in the cluster (e.g. Pod Create, Pod Update, Deployment Update). +// +// * Use Channel for events originating outside the cluster (eh.g. GitHub Webhook callback, Polling external urls). +// +// Users may build their own Source implementations. +type Source interface { + // Start is internal and should be called only by the Controller to register an EventHandler with the Informer + // to enqueue reconcile.Requests. + Start(context.Context, handler.EventHandler, workqueue.RateLimitingInterface, ...predicate.Predicate) error +} + +// SyncingSource is a source that needs syncing prior to being usable. The controller +// will call its WaitForSync prior to starting workers. +type SyncingSource interface { + Source + WaitForSync(ctx context.Context) error +} + +// Kind creates a KindSource with the given cache provider. +func Kind(cache cache.Cache, object client.Object) SyncingSource { + return &internal.Kind{Type: object, Cache: cache} +} + +var _ Source = &Channel{} + +// Channel is used to provide a source of events originating outside the cluster +// (e.g. GitHub Webhook callback). Channel requires the user to wire the external +// source (eh.g. http handler) to write GenericEvents to the underlying channel. +type Channel struct { + // once ensures the event distribution goroutine will be performed only once + once sync.Once + + // Source is the source channel to fetch GenericEvents + Source <-chan event.GenericEvent + + // dest is the destination channels of the added event handlers + dest []chan event.GenericEvent + + // DestBufferSize is the specified buffer size of dest channels. + // Default to 1024 if not specified. + DestBufferSize int + + // destLock is to ensure the destination channels are safely added/removed + destLock sync.Mutex +} + +func (cs *Channel) String() string { + return fmt.Sprintf("channel source: %p", cs) +} + +// Start implements Source and should only be called by the Controller. +func (cs *Channel) Start( + ctx context.Context, + handler handler.EventHandler, + queue workqueue.RateLimitingInterface, + prct ...predicate.Predicate) error { + // Source should have been specified by the user. + if cs.Source == nil { + return fmt.Errorf("must specify Channel.Source") + } + + // use default value if DestBufferSize not specified + if cs.DestBufferSize == 0 { + cs.DestBufferSize = defaultBufferSize + } + + dst := make(chan event.GenericEvent, cs.DestBufferSize) + + cs.destLock.Lock() + cs.dest = append(cs.dest, dst) + cs.destLock.Unlock() + + cs.once.Do(func() { + // Distribute GenericEvents to all EventHandler / Queue pairs Watching this source + go cs.syncLoop(ctx) + }) + + go func() { + for evt := range dst { + shouldHandle := true + for _, p := range prct { + if !p.Generic(evt) { + shouldHandle = false + break + } + } + + if shouldHandle { + func() { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + handler.Generic(ctx, evt, queue) + }() + } + } + }() + + return nil +} + +func (cs *Channel) doStop() { + cs.destLock.Lock() + defer cs.destLock.Unlock() + + for _, dst := range cs.dest { + close(dst) + } +} + +func (cs *Channel) distribute(evt event.GenericEvent) { + cs.destLock.Lock() + defer cs.destLock.Unlock() + + for _, dst := range cs.dest { + // We cannot make it under goroutine here, or we'll meet the + // race condition of writing message to closed channels. + // To avoid blocking, the dest channels are expected to be of + // proper buffer size. If we still see it blocked, then + // the controller is thought to be in an abnormal state. + dst <- evt + } +} + +func (cs *Channel) syncLoop(ctx context.Context) { + for { + select { + case <-ctx.Done(): + // Close destination channels + cs.doStop() + return + case evt, stillOpen := <-cs.Source: + if !stillOpen { + // if the source channel is closed, we're never gonna get + // anything more on it, so stop & bail + cs.doStop() + return + } + cs.distribute(evt) + } + } +} + +// Informer is used to provide a source of events originating inside the cluster from Watches (e.g. Pod Create). +type Informer struct { + // Informer is the controller-runtime Informer + Informer cache.Informer +} + +var _ Source = &Informer{} + +// Start is internal and should be called only by the Controller to register an EventHandler with the Informer +// to enqueue reconcile.Requests. +func (is *Informer) Start(ctx context.Context, handler handler.EventHandler, queue workqueue.RateLimitingInterface, + prct ...predicate.Predicate) error { + // Informer should have been specified by the user. + if is.Informer == nil { + return fmt.Errorf("must specify Informer.Informer") + } + + _, err := is.Informer.AddEventHandler(internal.NewEventHandler(ctx, queue, handler, prct).HandlerFuncs()) + if err != nil { + return err + } + return nil +} + +func (is *Informer) String() string { + return fmt.Sprintf("informer source: %p", is.Informer) +} + +var _ Source = Func(nil) + +// Func is a function that implements Source. +type Func func(context.Context, handler.EventHandler, workqueue.RateLimitingInterface, ...predicate.Predicate) error + +// Start implements Source. +func (f Func) Start(ctx context.Context, evt handler.EventHandler, queue workqueue.RateLimitingInterface, + pr ...predicate.Predicate) error { + return f(ctx, evt, queue, pr...) +} + +func (f Func) String() string { + return fmt.Sprintf("func source: %p", f) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go new file mode 100644 index 00000000..7e9c0a96 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/decode.go @@ -0,0 +1,79 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/json" +) + +// Decoder knows how to decode the contents of an admission +// request into a concrete object. +type Decoder struct { + codecs serializer.CodecFactory +} + +// NewDecoder creates a Decoder given the runtime.Scheme. +func NewDecoder(scheme *runtime.Scheme) *Decoder { + if scheme == nil { + panic("scheme should never be nil") + } + return &Decoder{codecs: serializer.NewCodecFactory(scheme)} +} + +// Decode decodes the inlined object in the AdmissionRequest into the passed-in runtime.Object. +// If you want decode the OldObject in the AdmissionRequest, use DecodeRaw. +// It errors out if req.Object.Raw is empty i.e. containing 0 raw bytes. +func (d *Decoder) Decode(req Request, into runtime.Object) error { + // we error out if rawObj is an empty object. + if len(req.Object.Raw) == 0 { + return fmt.Errorf("there is no content to decode") + } + return d.DecodeRaw(req.Object, into) +} + +// DecodeRaw decodes a RawExtension object into the passed-in runtime.Object. +// It errors out if rawObj is empty i.e. containing 0 raw bytes. +func (d *Decoder) DecodeRaw(rawObj runtime.RawExtension, into runtime.Object) error { + // NB(directxman12): there's a bug/weird interaction between decoders and + // the API server where the API server doesn't send a GVK on the embedded + // objects, which means the unstructured decoder refuses to decode. It + // also means we can't pass the unstructured directly in, since it'll try + // and call unstructured's special Unmarshal implementation, which calls + // back into that same decoder :-/ + // See kubernetes/kubernetes#74373. + + // we error out if rawObj is an empty object. + if len(rawObj.Raw) == 0 { + return fmt.Errorf("there is no content to decode") + } + if unstructuredInto, isUnstructured := into.(runtime.Unstructured); isUnstructured { + // unmarshal into unstructured's underlying object to avoid calling the decoder + var object map[string]interface{} + if err := json.Unmarshal(rawObj.Raw, &object); err != nil { + return err + } + unstructuredInto.SetUnstructuredContent(object) + return nil + } + + deserializer := d.codecs.UniversalDeserializer() + return runtime.DecodeInto(deserializer, rawObj.Raw, into) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go new file mode 100644 index 00000000..c9662ce1 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go @@ -0,0 +1,84 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "context" + "encoding/json" + "net/http" + + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Defaulter defines functions for setting defaults on resources. +// Deprecated: Ue CustomDefaulter instead. +type Defaulter interface { + runtime.Object + Default() +} + +// DefaultingWebhookFor creates a new Webhook for Defaulting the provided type. +// Deprecated: Use WithCustomDefaulter instead. +func DefaultingWebhookFor(scheme *runtime.Scheme, defaulter Defaulter) *Webhook { + return &Webhook{ + Handler: &mutatingHandler{defaulter: defaulter, decoder: NewDecoder(scheme)}, + } +} + +type mutatingHandler struct { + defaulter Defaulter + decoder *Decoder +} + +// Handle handles admission requests. +func (h *mutatingHandler) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } + if h.defaulter == nil { + panic("defaulter should never be nil") + } + + // always skip when a DELETE operation received in mutation handler + // describe in https://github.com/kubernetes-sigs/controller-runtime/issues/1762 + if req.Operation == admissionv1.Delete { + return Response{AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }} + } + + // Get the object in the request + obj := h.defaulter.DeepCopyObject().(Defaulter) + if err := h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + // Default the object + obj.Default() + marshalled, err := json.Marshal(obj) + if err != nil { + return Errored(http.StatusInternalServerError, err) + } + + // Create the patch + return PatchResponseFromRaw(req.Object.Raw, marshalled) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go new file mode 100644 index 00000000..5f697e7d --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go @@ -0,0 +1,94 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "context" + "encoding/json" + "errors" + "net/http" + + admissionv1 "k8s.io/api/admission/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// CustomDefaulter defines functions for setting defaults on resources. +type CustomDefaulter interface { + Default(ctx context.Context, obj runtime.Object) error +} + +// WithCustomDefaulter creates a new Webhook for a CustomDefaulter interface. +func WithCustomDefaulter(scheme *runtime.Scheme, obj runtime.Object, defaulter CustomDefaulter) *Webhook { + return &Webhook{ + Handler: &defaulterForType{object: obj, defaulter: defaulter, decoder: NewDecoder(scheme)}, + } +} + +type defaulterForType struct { + defaulter CustomDefaulter + object runtime.Object + decoder *Decoder +} + +// Handle handles admission requests. +func (h *defaulterForType) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } + if h.defaulter == nil { + panic("defaulter should never be nil") + } + if h.object == nil { + panic("object should never be nil") + } + + // Always skip when a DELETE operation received in custom mutation handler. + if req.Operation == admissionv1.Delete { + return Response{AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }} + } + + ctx = NewContextWithRequest(ctx, req) + + // Get the object in the request + obj := h.object.DeepCopyObject() + if err := h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + // Default the object + if err := h.defaulter.Default(ctx, obj); err != nil { + var apiStatus apierrors.APIStatus + if errors.As(err, &apiStatus) { + return validationResponseFromStatus(false, apiStatus.Status()) + } + return Denied(err.Error()) + } + + // Create the patch + marshalled, err := json.Marshal(obj) + if err != nil { + return Errored(http.StatusInternalServerError, err) + } + return PatchResponseFromRaw(req.Object.Raw, marshalled) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go new file mode 100644 index 00000000..8dc0cbec --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package admission provides implementation for admission webhook and methods to implement admission webhook handlers. + +See examples/mutatingwebhook.go and examples/validatingwebhook.go for examples of admission webhooks. +*/ +package admission diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go new file mode 100644 index 00000000..f049fb66 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go @@ -0,0 +1,173 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + + v1 "k8s.io/api/admission/v1" + "k8s.io/api/admission/v1beta1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var admissionScheme = runtime.NewScheme() +var admissionCodecs = serializer.NewCodecFactory(admissionScheme) + +// adapted from https://github.com/kubernetes/kubernetes/blob/c28c2009181fcc44c5f6b47e10e62dacf53e4da0/staging/src/k8s.io/pod-security-admission/cmd/webhook/server/server.go +// +// From https://github.com/kubernetes/apiserver/blob/d6876a0600de06fef75968c4641c64d7da499f25/pkg/server/config.go#L433-L442C5: +// +// 1.5MB is the recommended client request size in byte +// the etcd server should accept. See +// https://github.com/etcd-io/etcd/blob/release-3.4/embed/config.go#L56. +// A request body might be encoded in json, and is converted to +// proto when persisted in etcd, so we allow 2x as the largest request +// body size to be accepted and decoded in a write request. +// +// For the admission request, we can infer that it contains at most two objects +// (the old and new versions of the object being admitted), each of which can +// be at most 3MB in size. For the rest of the request, we can assume that +// it will be less than 1MB in size. Therefore, we can set the max request +// size to 7MB. +// If your use case requires larger max request sizes, please +// open an issue (https://github.com/kubernetes-sigs/controller-runtime/issues/new). +const maxRequestSize = int64(7 * 1024 * 1024) + +func init() { + utilruntime.Must(v1.AddToScheme(admissionScheme)) + utilruntime.Must(v1beta1.AddToScheme(admissionScheme)) +} + +var _ http.Handler = &Webhook{} + +func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + if wh.WithContextFunc != nil { + ctx = wh.WithContextFunc(ctx, r) + } + + if r.Body == nil || r.Body == http.NoBody { + err := errors.New("request body is empty") + wh.getLogger(nil).Error(err, "bad request") + wh.writeResponse(w, Errored(http.StatusBadRequest, err)) + return + } + + defer r.Body.Close() + limitedReader := &io.LimitedReader{R: r.Body, N: maxRequestSize} + body, err := io.ReadAll(limitedReader) + if err != nil { + wh.getLogger(nil).Error(err, "unable to read the body from the incoming request") + wh.writeResponse(w, Errored(http.StatusBadRequest, err)) + return + } + if limitedReader.N <= 0 { + err := fmt.Errorf("request entity is too large; limit is %d bytes", maxRequestSize) + wh.getLogger(nil).Error(err, "unable to read the body from the incoming request; limit reached") + wh.writeResponse(w, Errored(http.StatusRequestEntityTooLarge, err)) + return + } + + // verify the content type is accurate + if contentType := r.Header.Get("Content-Type"); contentType != "application/json" { + err = fmt.Errorf("contentType=%s, expected application/json", contentType) + wh.getLogger(nil).Error(err, "unable to process a request with unknown content type") + wh.writeResponse(w, Errored(http.StatusBadRequest, err)) + return + } + + // Both v1 and v1beta1 AdmissionReview types are exactly the same, so the v1beta1 type can + // be decoded into the v1 type. However the runtime codec's decoder guesses which type to + // decode into by type name if an Object's TypeMeta isn't set. By setting TypeMeta of an + // unregistered type to the v1 GVK, the decoder will coerce a v1beta1 AdmissionReview to v1. + // The actual AdmissionReview GVK will be used to write a typed response in case the + // webhook config permits multiple versions, otherwise this response will fail. + req := Request{} + ar := unversionedAdmissionReview{} + // avoid an extra copy + ar.Request = &req.AdmissionRequest + ar.SetGroupVersionKind(v1.SchemeGroupVersion.WithKind("AdmissionReview")) + _, actualAdmRevGVK, err := admissionCodecs.UniversalDeserializer().Decode(body, nil, &ar) + if err != nil { + wh.getLogger(nil).Error(err, "unable to decode the request") + wh.writeResponse(w, Errored(http.StatusBadRequest, err)) + return + } + wh.getLogger(&req).V(5).Info("received request") + + wh.writeResponseTyped(w, wh.Handle(ctx, req), actualAdmRevGVK) +} + +// writeResponse writes response to w generically, i.e. without encoding GVK information. +func (wh *Webhook) writeResponse(w io.Writer, response Response) { + wh.writeAdmissionResponse(w, v1.AdmissionReview{Response: &response.AdmissionResponse}) +} + +// writeResponseTyped writes response to w with GVK set to admRevGVK, which is necessary +// if multiple AdmissionReview versions are permitted by the webhook. +func (wh *Webhook) writeResponseTyped(w io.Writer, response Response, admRevGVK *schema.GroupVersionKind) { + ar := v1.AdmissionReview{ + Response: &response.AdmissionResponse, + } + // Default to a v1 AdmissionReview, otherwise the API server may not recognize the request + // if multiple AdmissionReview versions are permitted by the webhook config. + // TODO(estroz): this should be configurable since older API servers won't know about v1. + if admRevGVK == nil || *admRevGVK == (schema.GroupVersionKind{}) { + ar.SetGroupVersionKind(v1.SchemeGroupVersion.WithKind("AdmissionReview")) + } else { + ar.SetGroupVersionKind(*admRevGVK) + } + wh.writeAdmissionResponse(w, ar) +} + +// writeAdmissionResponse writes ar to w. +func (wh *Webhook) writeAdmissionResponse(w io.Writer, ar v1.AdmissionReview) { + if err := json.NewEncoder(w).Encode(ar); err != nil { + wh.getLogger(nil).Error(err, "unable to encode and write the response") + // Since the `ar v1.AdmissionReview` is a clear and legal object, + // it should not have problem to be marshalled into bytes. + // The error here is probably caused by the abnormal HTTP connection, + // e.g., broken pipe, so we can only write the error response once, + // to avoid endless circular calling. + serverError := Errored(http.StatusInternalServerError, err) + if err = json.NewEncoder(w).Encode(v1.AdmissionReview{Response: &serverError.AdmissionResponse}); err != nil { + wh.getLogger(nil).Error(err, "still unable to encode and write the InternalServerError response") + } + } else { + res := ar.Response + if log := wh.getLogger(nil); log.V(5).Enabled() { + if res.Result != nil { + log = log.WithValues("code", res.Result.Code, "reason", res.Result.Reason, "message", res.Result.Message) + } + log.V(5).Info("wrote response", "requestID", res.UID, "allowed", res.Allowed) + } + } +} + +// unversionedAdmissionReview is used to decode both v1 and v1beta1 AdmissionReview types. +type unversionedAdmissionReview struct { + v1.AdmissionReview +} + +var _ runtime.Object = &unversionedAdmissionReview{} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go new file mode 100644 index 00000000..2f7820d0 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/multi.go @@ -0,0 +1,95 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + jsonpatch "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type multiMutating []Handler + +func (hs multiMutating) Handle(ctx context.Context, req Request) Response { + patches := []jsonpatch.JsonPatchOperation{} + for _, handler := range hs { + resp := handler.Handle(ctx, req) + if !resp.Allowed { + return resp + } + if resp.PatchType != nil && *resp.PatchType != admissionv1.PatchTypeJSONPatch { + return Errored(http.StatusInternalServerError, + fmt.Errorf("unexpected patch type returned by the handler: %v, only allow: %v", + resp.PatchType, admissionv1.PatchTypeJSONPatch)) + } + patches = append(patches, resp.Patches...) + } + var err error + marshaledPatch, err := json.Marshal(patches) + if err != nil { + return Errored(http.StatusBadRequest, fmt.Errorf("error when marshaling the patch: %w", err)) + } + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + Patch: marshaledPatch, + PatchType: func() *admissionv1.PatchType { pt := admissionv1.PatchTypeJSONPatch; return &pt }(), + }, + } +} + +// MultiMutatingHandler combines multiple mutating webhook handlers into a single +// mutating webhook handler. Handlers are called in sequential order, and the first +// `allowed: false` response may short-circuit the rest. Users must take care to +// ensure patches are disjoint. +func MultiMutatingHandler(handlers ...Handler) Handler { + return multiMutating(handlers) +} + +type multiValidating []Handler + +func (hs multiValidating) Handle(ctx context.Context, req Request) Response { + for _, handler := range hs { + resp := handler.Handle(ctx, req) + if !resp.Allowed { + return resp + } + } + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Code: http.StatusOK, + }, + }, + } +} + +// MultiValidatingHandler combines multiple validating webhook handlers into a single +// validating webhook handler. Handlers are called in sequential order, and the first +// `allowed: false` response may short-circuit the rest. +func MultiValidatingHandler(handlers ...Handler) Handler { + return multiValidating(handlers) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go new file mode 100644 index 00000000..ec1c88c9 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/response.go @@ -0,0 +1,124 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "net/http" + + jsonpatch "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Allowed constructs a response indicating that the given operation +// is allowed (without any patches). +func Allowed(message string) Response { + return ValidationResponse(true, message) +} + +// Denied constructs a response indicating that the given operation +// is not allowed. +func Denied(message string) Response { + return ValidationResponse(false, message) +} + +// Patched constructs a response indicating that the given operation is +// allowed, and that the target object should be modified by the given +// JSONPatch operations. +func Patched(message string, patches ...jsonpatch.JsonPatchOperation) Response { + resp := Allowed(message) + resp.Patches = patches + + return resp +} + +// Errored creates a new Response for error-handling a request. +func Errored(code int32, err error) Response { + return Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Code: code, + Message: err.Error(), + }, + }, + } +} + +// ValidationResponse returns a response for admitting a request. +func ValidationResponse(allowed bool, message string) Response { + code := http.StatusForbidden + reason := metav1.StatusReasonForbidden + if allowed { + code = http.StatusOK + reason = "" + } + resp := Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: allowed, + Result: &metav1.Status{ + Code: int32(code), + Reason: reason, + }, + }, + } + if len(message) > 0 { + resp.Result.Message = message + } + return resp +} + +// PatchResponseFromRaw takes 2 byte arrays and returns a new response with json patch. +// The original object should be passed in as raw bytes to avoid the roundtripping problem +// described in https://github.com/kubernetes-sigs/kubebuilder/issues/510. +func PatchResponseFromRaw(original, current []byte) Response { + patches, err := jsonpatch.CreatePatch(original, current) + if err != nil { + return Errored(http.StatusInternalServerError, err) + } + return Response{ + Patches: patches, + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: true, + PatchType: func() *admissionv1.PatchType { + if len(patches) == 0 { + return nil + } + pt := admissionv1.PatchTypeJSONPatch + return &pt + }(), + }, + } +} + +// validationResponseFromStatus returns a response for admitting a request with provided Status object. +func validationResponseFromStatus(allowed bool, status metav1.Status) Response { + resp := Response{ + AdmissionResponse: admissionv1.AdmissionResponse{ + Allowed: allowed, + Result: &status, + }, + } + return resp +} + +// WithWarnings adds the given warnings to the Response. +// If any warnings were already given, they will not be overwritten. +func (r Response) WithWarnings(warnings ...string) Response { + r.AdmissionResponse.Warnings = append(r.AdmissionResponse.Warnings, warnings...) + return r +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go new file mode 100644 index 00000000..fa42217b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator.go @@ -0,0 +1,127 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "context" + "errors" + "fmt" + "net/http" + + v1 "k8s.io/api/admission/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +// Warnings represents warning messages. +type Warnings []string + +// Validator defines functions for validating an operation. +// The custom resource kind which implements this interface can validate itself. +// To validate the custom resource with another specific struct, use CustomValidator instead. +// Deprecated: Use CustomValidator instead. +type Validator interface { + runtime.Object + + // ValidateCreate validates the object on creation. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateCreate() (warnings Warnings, err error) + + // ValidateUpdate validates the object on update. The oldObj is the object before the update. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateUpdate(old runtime.Object) (warnings Warnings, err error) + + // ValidateDelete validates the object on deletion. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateDelete() (warnings Warnings, err error) +} + +// ValidatingWebhookFor creates a new Webhook for validating the provided type. +// Deprecated: Use WithCustomValidator instead. +func ValidatingWebhookFor(scheme *runtime.Scheme, validator Validator) *Webhook { + return &Webhook{ + Handler: &validatingHandler{validator: validator, decoder: NewDecoder(scheme)}, + } +} + +type validatingHandler struct { + validator Validator + decoder *Decoder +} + +// Handle handles admission requests. +func (h *validatingHandler) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } + if h.validator == nil { + panic("validator should never be nil") + } + // Get the object in the request + obj := h.validator.DeepCopyObject().(Validator) + + var err error + var warnings []string + + switch req.Operation { + case v1.Connect: + // No validation for connect requests. + // TODO(vincepri): Should we validate CONNECT requests? In what cases? + case v1.Create: + if err = h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = obj.ValidateCreate() + case v1.Update: + oldObj := obj.DeepCopyObject() + + err = h.decoder.DecodeRaw(req.Object, obj) + if err != nil { + return Errored(http.StatusBadRequest, err) + } + err = h.decoder.DecodeRaw(req.OldObject, oldObj) + if err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = obj.ValidateUpdate(oldObj) + case v1.Delete: + // In reference to PR: https://github.com/kubernetes/kubernetes/pull/76346 + // OldObject contains the object being deleted + err = h.decoder.DecodeRaw(req.OldObject, obj) + if err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = obj.ValidateDelete() + default: + return Errored(http.StatusBadRequest, fmt.Errorf("unknown operation %q", req.Operation)) + } + + if err != nil { + var apiStatus apierrors.APIStatus + if errors.As(err, &apiStatus) { + return validationResponseFromStatus(false, apiStatus.Status()).WithWarnings(warnings...) + } + return Denied(err.Error()).WithWarnings(warnings...) + } + return Allowed("").WithWarnings(warnings...) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go new file mode 100644 index 00000000..07650aa6 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go @@ -0,0 +1,125 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "context" + "errors" + "fmt" + "net/http" + + v1 "k8s.io/api/admission/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +// CustomValidator defines functions for validating an operation. +// The object to be validated is passed into methods as a parameter. +type CustomValidator interface { + // ValidateCreate validates the object on creation. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateCreate(ctx context.Context, obj runtime.Object) (warnings Warnings, err error) + + // ValidateUpdate validates the object on update. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings Warnings, err error) + + // ValidateDelete validates the object on deletion. + // The optional warnings will be added to the response as warning messages. + // Return an error if the object is invalid. + ValidateDelete(ctx context.Context, obj runtime.Object) (warnings Warnings, err error) +} + +// WithCustomValidator creates a new Webhook for validating the provided type. +func WithCustomValidator(scheme *runtime.Scheme, obj runtime.Object, validator CustomValidator) *Webhook { + return &Webhook{ + Handler: &validatorForType{object: obj, validator: validator, decoder: NewDecoder(scheme)}, + } +} + +type validatorForType struct { + validator CustomValidator + object runtime.Object + decoder *Decoder +} + +// Handle handles admission requests. +func (h *validatorForType) Handle(ctx context.Context, req Request) Response { + if h.decoder == nil { + panic("decoder should never be nil") + } + if h.validator == nil { + panic("validator should never be nil") + } + if h.object == nil { + panic("object should never be nil") + } + + ctx = NewContextWithRequest(ctx, req) + + // Get the object in the request + obj := h.object.DeepCopyObject() + + var err error + var warnings []string + + switch req.Operation { + case v1.Connect: + // No validation for connect requests. + // TODO(vincepri): Should we validate CONNECT requests? In what cases? + case v1.Create: + if err := h.decoder.Decode(req, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = h.validator.ValidateCreate(ctx, obj) + case v1.Update: + oldObj := obj.DeepCopyObject() + if err := h.decoder.DecodeRaw(req.Object, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + if err := h.decoder.DecodeRaw(req.OldObject, oldObj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = h.validator.ValidateUpdate(ctx, oldObj, obj) + case v1.Delete: + // In reference to PR: https://github.com/kubernetes/kubernetes/pull/76346 + // OldObject contains the object being deleted + if err := h.decoder.DecodeRaw(req.OldObject, obj); err != nil { + return Errored(http.StatusBadRequest, err) + } + + warnings, err = h.validator.ValidateDelete(ctx, obj) + default: + return Errored(http.StatusBadRequest, fmt.Errorf("unknown operation %q", req.Operation)) + } + + // Check the error message first. + if err != nil { + var apiStatus apierrors.APIStatus + if errors.As(err, &apiStatus) { + return validationResponseFromStatus(false, apiStatus.Status()).WithWarnings(warnings...) + } + return Denied(err.Error()).WithWarnings(warnings...) + } + + // Return allowed if everything succeeded. + return Allowed("").WithWarnings(warnings...) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go new file mode 100644 index 00000000..f1767f31 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go @@ -0,0 +1,251 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package admission + +import ( + "context" + "errors" + "fmt" + "net/http" + "sync" + + "github.com/go-logr/logr" + "gomodules.xyz/jsonpatch/v2" + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/json" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics" +) + +var ( + errUnableToEncodeResponse = errors.New("unable to encode response") +) + +// Request defines the input for an admission handler. +// It contains information to identify the object in +// question (group, version, kind, resource, subresource, +// name, namespace), as well as the operation in question +// (e.g. Get, Create, etc), and the object itself. +type Request struct { + admissionv1.AdmissionRequest +} + +// Response is the output of an admission handler. +// It contains a response indicating if a given +// operation is allowed, as well as a set of patches +// to mutate the object in the case of a mutating admission handler. +type Response struct { + // Patches are the JSON patches for mutating webhooks. + // Using this instead of setting Response.Patch to minimize + // overhead of serialization and deserialization. + // Patches set here will override any patches in the response, + // so leave this empty if you want to set the patch response directly. + Patches []jsonpatch.JsonPatchOperation + // AdmissionResponse is the raw admission response. + // The Patch field in it will be overwritten by the listed patches. + admissionv1.AdmissionResponse +} + +// Complete populates any fields that are yet to be set in +// the underlying AdmissionResponse, It mutates the response. +func (r *Response) Complete(req Request) error { + r.UID = req.UID + + // ensure that we have a valid status code + if r.Result == nil { + r.Result = &metav1.Status{} + } + if r.Result.Code == 0 { + r.Result.Code = http.StatusOK + } + // TODO(directxman12): do we need to populate this further, and/or + // is code actually necessary (the same webhook doesn't use it) + + if len(r.Patches) == 0 { + return nil + } + + var err error + r.Patch, err = json.Marshal(r.Patches) + if err != nil { + return err + } + patchType := admissionv1.PatchTypeJSONPatch + r.PatchType = &patchType + + return nil +} + +// Handler can handle an AdmissionRequest. +type Handler interface { + // Handle yields a response to an AdmissionRequest. + // + // The supplied context is extracted from the received http.Request, allowing wrapping + // http.Handlers to inject values into and control cancelation of downstream request processing. + Handle(context.Context, Request) Response +} + +// HandlerFunc implements Handler interface using a single function. +type HandlerFunc func(context.Context, Request) Response + +var _ Handler = HandlerFunc(nil) + +// Handle process the AdmissionRequest by invoking the underlying function. +func (f HandlerFunc) Handle(ctx context.Context, req Request) Response { + return f(ctx, req) +} + +// Webhook represents each individual webhook. +// +// It must be registered with a webhook.Server or +// populated by StandaloneWebhook to be ran on an arbitrary HTTP server. +type Webhook struct { + // Handler actually processes an admission request returning whether it was allowed or denied, + // and potentially patches to apply to the handler. + Handler Handler + + // RecoverPanic indicates whether the panic caused by webhook should be recovered. + RecoverPanic bool + + // WithContextFunc will allow you to take the http.Request.Context() and + // add any additional information such as passing the request path or + // headers thus allowing you to read them from within the handler + WithContextFunc func(context.Context, *http.Request) context.Context + + // LogConstructor is used to construct a logger for logging messages during webhook calls + // based on the given base logger (which might carry more values like the webhook's path). + // Note: LogConstructor has to be able to handle nil requests as we are also using it + // outside the context of requests. + LogConstructor func(base logr.Logger, req *Request) logr.Logger + + setupLogOnce sync.Once + log logr.Logger +} + +// WithRecoverPanic takes a bool flag which indicates whether the panic caused by webhook should be recovered. +func (wh *Webhook) WithRecoverPanic(recoverPanic bool) *Webhook { + wh.RecoverPanic = recoverPanic + return wh +} + +// Handle processes AdmissionRequest. +// If the webhook is mutating type, it delegates the AdmissionRequest to each handler and merge the patches. +// If the webhook is validating type, it delegates the AdmissionRequest to each handler and +// deny the request if anyone denies. +func (wh *Webhook) Handle(ctx context.Context, req Request) (response Response) { + if wh.RecoverPanic { + defer func() { + if r := recover(); r != nil { + for _, fn := range utilruntime.PanicHandlers { + fn(r) + } + response = Errored(http.StatusInternalServerError, fmt.Errorf("panic: %v [recovered]", r)) + return + } + }() + } + + reqLog := wh.getLogger(&req) + ctx = logf.IntoContext(ctx, reqLog) + + resp := wh.Handler.Handle(ctx, req) + if err := resp.Complete(req); err != nil { + reqLog.Error(err, "unable to encode response") + return Errored(http.StatusInternalServerError, errUnableToEncodeResponse) + } + + return resp +} + +// getLogger constructs a logger from the injected log and LogConstructor. +func (wh *Webhook) getLogger(req *Request) logr.Logger { + wh.setupLogOnce.Do(func() { + if wh.log.GetSink() == nil { + wh.log = logf.Log.WithName("admission") + } + }) + + logConstructor := wh.LogConstructor + if logConstructor == nil { + logConstructor = DefaultLogConstructor + } + return logConstructor(wh.log, req) +} + +// DefaultLogConstructor adds some commonly interesting fields to the given logger. +func DefaultLogConstructor(base logr.Logger, req *Request) logr.Logger { + if req != nil { + return base.WithValues("object", klog.KRef(req.Namespace, req.Name), + "namespace", req.Namespace, "name", req.Name, + "resource", req.Resource, "user", req.UserInfo.Username, + "requestID", req.UID, + ) + } + return base +} + +// StandaloneOptions let you configure a StandaloneWebhook. +type StandaloneOptions struct { + // Logger to be used by the webhook. + // If none is set, it defaults to log.Log global logger. + Logger logr.Logger + // MetricsPath is used for labelling prometheus metrics + // by the path is served on. + // If none is set, prometheus metrics will not be generated. + MetricsPath string +} + +// StandaloneWebhook prepares a webhook for use without a webhook.Server, +// passing in the information normally populated by webhook.Server +// and instrumenting the webhook with metrics. +// +// Use this to attach your webhook to an arbitrary HTTP server or mux. +// +// Note that you are responsible for terminating TLS if you use StandaloneWebhook +// in your own server/mux. In order to be accessed by a kubernetes cluster, +// all webhook servers require TLS. +func StandaloneWebhook(hook *Webhook, opts StandaloneOptions) (http.Handler, error) { + if opts.Logger.GetSink() != nil { + hook.log = opts.Logger + } + if opts.MetricsPath == "" { + return hook, nil + } + return metrics.InstrumentedHook(opts.MetricsPath, hook), nil +} + +// requestContextKey is how we find the admission.Request in a context.Context. +type requestContextKey struct{} + +// RequestFromContext returns an admission.Request from ctx. +func RequestFromContext(ctx context.Context) (Request, error) { + if v, ok := ctx.Value(requestContextKey{}).(Request); ok { + return v, nil + } + + return Request{}, errors.New("admission.Request not found in context") +} + +// NewContextWithRequest returns a new Context, derived from ctx, which carries the +// provided admission.Request. +func NewContextWithRequest(ctx context.Context, req Request) context.Context { + return context.WithValue(ctx, requestContextKey{}, req) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go new file mode 100644 index 00000000..e8439e2e --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/alias.go @@ -0,0 +1,81 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package webhook + +import ( + "gomodules.xyz/jsonpatch/v2" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// define some aliases for common bits of the webhook functionality + +// Defaulter defines functions for setting defaults on resources. +// Deprecated: Use CustomDefaulter instead. +type Defaulter = admission.Defaulter + +// Validator defines functions for validating an operation. +// Deprecated: Use CustomValidator instead. +type Validator = admission.Validator + +// CustomDefaulter defines functions for setting defaults on resources. +type CustomDefaulter = admission.CustomDefaulter + +// CustomValidator defines functions for validating an operation. +type CustomValidator = admission.CustomValidator + +// AdmissionRequest defines the input for an admission handler. +// It contains information to identify the object in +// question (group, version, kind, resource, subresource, +// name, namespace), as well as the operation in question +// (e.g. Get, Create, etc), and the object itself. +type AdmissionRequest = admission.Request + +// AdmissionResponse is the output of an admission handler. +// It contains a response indicating if a given +// operation is allowed, as well as a set of patches +// to mutate the object in the case of a mutating admission handler. +type AdmissionResponse = admission.Response + +// Admission is webhook suitable for registration with the server +// an admission webhook that validates API operations and potentially +// mutates their contents. +type Admission = admission.Webhook + +// AdmissionHandler knows how to process admission requests, validating them, +// and potentially mutating the objects they contain. +type AdmissionHandler = admission.Handler + +// AdmissionDecoder knows how to decode objects from admission requests. +type AdmissionDecoder = admission.Decoder + +// JSONPatchOp represents a single JSONPatch patch operation. +type JSONPatchOp = jsonpatch.Operation + +var ( + // Allowed indicates that the admission request should be allowed for the given reason. + Allowed = admission.Allowed + + // Denied indicates that the admission request should be denied for the given reason. + Denied = admission.Denied + + // Patched indicates that the admission request should be allowed for the given reason, + // and that the contained object should be mutated using the given patches. + Patched = admission.Patched + + // Errored indicates that an error occurred in the admission request. + Errored = admission.Errored +) diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go new file mode 100644 index 00000000..249a364b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go @@ -0,0 +1,343 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +/* +Package conversion provides implementation for CRD conversion webhook that implements handler for version conversion requests for types that are convertible. + +See pkg/conversion for interface definitions required to ensure an API Type is convertible. +*/ +package conversion + +import ( + "encoding/json" + "fmt" + "net/http" + + apix "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/conversion" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +var ( + log = logf.Log.WithName("conversion-webhook") +) + +func NewWebhookHandler(scheme *runtime.Scheme) http.Handler { + return &webhook{scheme: scheme, decoder: NewDecoder(scheme)} +} + +// webhook implements a CRD conversion webhook HTTP handler. +type webhook struct { + scheme *runtime.Scheme + decoder *Decoder +} + +// ensure Webhook implements http.Handler +var _ http.Handler = &webhook{} + +func (wh *webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { + convertReview := &apix.ConversionReview{} + err := json.NewDecoder(r.Body).Decode(convertReview) + if err != nil { + log.Error(err, "failed to read conversion request") + w.WriteHeader(http.StatusBadRequest) + return + } + + if convertReview.Request == nil { + log.Error(nil, "conversion request is nil") + w.WriteHeader(http.StatusBadRequest) + return + } + + // TODO(droot): may be move the conversion logic to a separate module to + // decouple it from the http layer ? + resp, err := wh.handleConvertRequest(convertReview.Request) + if err != nil { + log.Error(err, "failed to convert", "request", convertReview.Request.UID) + convertReview.Response = errored(err) + } else { + convertReview.Response = resp + } + convertReview.Response.UID = convertReview.Request.UID + convertReview.Request = nil + + err = json.NewEncoder(w).Encode(convertReview) + if err != nil { + log.Error(err, "failed to write response") + return + } +} + +// handles a version conversion request. +func (wh *webhook) handleConvertRequest(req *apix.ConversionRequest) (*apix.ConversionResponse, error) { + if req == nil { + return nil, fmt.Errorf("conversion request is nil") + } + var objects []runtime.RawExtension + + for _, obj := range req.Objects { + src, gvk, err := wh.decoder.Decode(obj.Raw) + if err != nil { + return nil, err + } + dst, err := wh.allocateDstObject(req.DesiredAPIVersion, gvk.Kind) + if err != nil { + return nil, err + } + err = wh.convertObject(src, dst) + if err != nil { + return nil, err + } + objects = append(objects, runtime.RawExtension{Object: dst}) + } + return &apix.ConversionResponse{ + UID: req.UID, + ConvertedObjects: objects, + Result: metav1.Status{ + Status: metav1.StatusSuccess, + }, + }, nil +} + +// convertObject will convert given a src object to dst object. +// Note(droot): couldn't find a way to reduce the cyclomatic complexity under 10 +// without compromising readability, so disabling gocyclo linter +func (wh *webhook) convertObject(src, dst runtime.Object) error { + srcGVK := src.GetObjectKind().GroupVersionKind() + dstGVK := dst.GetObjectKind().GroupVersionKind() + + if srcGVK.GroupKind() != dstGVK.GroupKind() { + return fmt.Errorf("src %T and dst %T does not belong to same API Group", src, dst) + } + + if srcGVK == dstGVK { + return fmt.Errorf("conversion is not allowed between same type %T", src) + } + + srcIsHub, dstIsHub := isHub(src), isHub(dst) + srcIsConvertible, dstIsConvertible := isConvertible(src), isConvertible(dst) + + switch { + case srcIsHub && dstIsConvertible: + return dst.(conversion.Convertible).ConvertFrom(src.(conversion.Hub)) + case dstIsHub && srcIsConvertible: + return src.(conversion.Convertible).ConvertTo(dst.(conversion.Hub)) + case srcIsConvertible && dstIsConvertible: + return wh.convertViaHub(src.(conversion.Convertible), dst.(conversion.Convertible)) + default: + return fmt.Errorf("%T is not convertible to %T", src, dst) + } +} + +func (wh *webhook) convertViaHub(src, dst conversion.Convertible) error { + hub, err := wh.getHub(src) + if err != nil { + return err + } + + if hub == nil { + return fmt.Errorf("%s does not have any Hub defined", src) + } + + err = src.ConvertTo(hub) + if err != nil { + return fmt.Errorf("%T failed to convert to hub version %T : %w", src, hub, err) + } + + err = dst.ConvertFrom(hub) + if err != nil { + return fmt.Errorf("%T failed to convert from hub version %T : %w", dst, hub, err) + } + + return nil +} + +// getHub returns an instance of the Hub for passed-in object's group/kind. +func (wh *webhook) getHub(obj runtime.Object) (conversion.Hub, error) { + gvks, err := objectGVKs(wh.scheme, obj) + if err != nil { + return nil, err + } + if len(gvks) == 0 { + return nil, fmt.Errorf("error retrieving gvks for object : %v", obj) + } + + var hub conversion.Hub + var hubFoundAlready bool + for _, gvk := range gvks { + instance, err := wh.scheme.New(gvk) + if err != nil { + return nil, fmt.Errorf("failed to allocate an instance for gvk %v: %w", gvk, err) + } + if val, isHub := instance.(conversion.Hub); isHub { + if hubFoundAlready { + return nil, fmt.Errorf("multiple hub version defined for %T", obj) + } + hubFoundAlready = true + hub = val + } + } + return hub, nil +} + +// allocateDstObject returns an instance for a given GVK. +func (wh *webhook) allocateDstObject(apiVersion, kind string) (runtime.Object, error) { + gvk := schema.FromAPIVersionAndKind(apiVersion, kind) + + obj, err := wh.scheme.New(gvk) + if err != nil { + return obj, err + } + + t, err := meta.TypeAccessor(obj) + if err != nil { + return obj, err + } + + t.SetAPIVersion(apiVersion) + t.SetKind(kind) + + return obj, nil +} + +// IsConvertible determines if given type is convertible or not. For a type +// to be convertible, the group-kind needs to have a Hub type defined and all +// non-hub types must be able to convert to/from Hub. +func IsConvertible(scheme *runtime.Scheme, obj runtime.Object) (bool, error) { + var hubs, spokes, nonSpokes []runtime.Object + + gvks, err := objectGVKs(scheme, obj) + if err != nil { + return false, err + } + if len(gvks) == 0 { + return false, fmt.Errorf("error retrieving gvks for object : %v", obj) + } + + for _, gvk := range gvks { + instance, err := scheme.New(gvk) + if err != nil { + return false, fmt.Errorf("failed to allocate an instance for gvk %v: %w", gvk, err) + } + + if isHub(instance) { + hubs = append(hubs, instance) + continue + } + + if !isConvertible(instance) { + nonSpokes = append(nonSpokes, instance) + continue + } + + spokes = append(spokes, instance) + } + + if len(gvks) == 1 { + return false, nil // single version + } + + if len(hubs) == 0 && len(spokes) == 0 { + // multiple version detected with no conversion implementation. This is + // true for multi-version built-in types. + return false, nil + } + + if len(hubs) == 1 && len(nonSpokes) == 0 { // convertible + return true, nil + } + + return false, PartialImplementationError{ + hubs: hubs, + nonSpokes: nonSpokes, + spokes: spokes, + } +} + +// objectGVKs returns all (Group,Version,Kind) for the Group/Kind of given object. +func objectGVKs(scheme *runtime.Scheme, obj runtime.Object) ([]schema.GroupVersionKind, error) { + // NB: we should not use `obj.GetObjectKind().GroupVersionKind()` to get the + // GVK here, since it is parsed from apiVersion and kind fields and it may + // return empty GVK if obj is an uninitialized object. + objGVKs, _, err := scheme.ObjectKinds(obj) + if err != nil { + return nil, err + } + if len(objGVKs) != 1 { + return nil, fmt.Errorf("expect to get only one GVK for %v", obj) + } + objGVK := objGVKs[0] + knownTypes := scheme.AllKnownTypes() + + var gvks []schema.GroupVersionKind + for gvk := range knownTypes { + if objGVK.GroupKind() == gvk.GroupKind() { + gvks = append(gvks, gvk) + } + } + return gvks, nil +} + +// PartialImplementationError represents an error due to partial conversion +// implementation such as hub without spokes, multiple hubs or spokes without hub. +type PartialImplementationError struct { + gvk schema.GroupVersionKind + hubs []runtime.Object + nonSpokes []runtime.Object + spokes []runtime.Object +} + +func (e PartialImplementationError) Error() string { + if len(e.hubs) == 0 { + return fmt.Sprintf("no hub defined for gvk %s", e.gvk) + } + if len(e.hubs) > 1 { + return fmt.Sprintf("multiple(%d) hubs defined for group-kind '%s' ", + len(e.hubs), e.gvk.GroupKind()) + } + if len(e.nonSpokes) > 0 { + return fmt.Sprintf("%d inconvertible types detected for group-kind '%s'", + len(e.nonSpokes), e.gvk.GroupKind()) + } + return "" +} + +// isHub determines if passed-in object is a Hub or not. +func isHub(obj runtime.Object) bool { + _, yes := obj.(conversion.Hub) + return yes +} + +// isConvertible determines if passed-in object is a convertible. +func isConvertible(obj runtime.Object) bool { + _, yes := obj.(conversion.Convertible) + return yes +} + +// helper to construct error response. +func errored(err error) *apix.ConversionResponse { + return &apix.ConversionResponse{ + Result: metav1.Status{ + Status: metav1.StatusFailure, + Message: err.Error(), + }, + } +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go new file mode 100644 index 00000000..b6bb8bd9 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/decoder.go @@ -0,0 +1,50 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package conversion + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// Decoder knows how to decode the contents of a CRD version conversion +// request into a concrete object. +// TODO(droot): consider reusing decoder from admission pkg for this. +type Decoder struct { + codecs serializer.CodecFactory +} + +// NewDecoder creates a Decoder given the runtime.Scheme +func NewDecoder(scheme *runtime.Scheme) *Decoder { + if scheme == nil { + panic("scheme should never be nil") + } + return &Decoder{codecs: serializer.NewCodecFactory(scheme)} +} + +// Decode decodes the inlined object. +func (d *Decoder) Decode(content []byte) (runtime.Object, *schema.GroupVersionKind, error) { + deserializer := d.codecs.UniversalDeserializer() + return deserializer.Decode(content, nil, nil) +} + +// DecodeInto decodes the inlined object in the into the passed-in runtime.Object. +func (d *Decoder) DecodeInto(content []byte, into runtime.Object) error { + deserializer := d.codecs.UniversalDeserializer() + return runtime.DecodeInto(deserializer, content, into) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/doc.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/doc.go new file mode 100644 index 00000000..2c93f0d9 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/doc.go @@ -0,0 +1,28 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +/* +Package webhook provides methods to build and bootstrap a webhook server. + +Currently, it only supports admission webhooks. It will support CRD conversion webhooks in the near future. +*/ +package webhook + +import ( + logf "sigs.k8s.io/controller-runtime/pkg/internal/log" +) + +var log = logf.RuntimeLog.WithName("webhook") diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics/metrics.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics/metrics.go new file mode 100644 index 00000000..55700490 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics/metrics.go @@ -0,0 +1,85 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package metrics + +import ( + "net/http" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + // RequestLatency is a prometheus metric which is a histogram of the latency + // of processing admission requests. + RequestLatency = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "controller_runtime_webhook_latency_seconds", + Help: "Histogram of the latency of processing admission requests", + }, + []string{"webhook"}, + ) + + // RequestTotal is a prometheus metric which is a counter of the total processed admission requests. + RequestTotal = func() *prometheus.CounterVec { + return prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "controller_runtime_webhook_requests_total", + Help: "Total number of admission requests by HTTP status code.", + }, + []string{"webhook", "code"}, + ) + }() + + // RequestInFlight is a prometheus metric which is a gauge of the in-flight admission requests. + RequestInFlight = func() *prometheus.GaugeVec { + return prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "controller_runtime_webhook_requests_in_flight", + Help: "Current number of admission requests being served.", + }, + []string{"webhook"}, + ) + }() +) + +func init() { + metrics.Registry.MustRegister(RequestLatency, RequestTotal, RequestInFlight) +} + +// InstrumentedHook adds some instrumentation on top of the given webhook. +func InstrumentedHook(path string, hookRaw http.Handler) http.Handler { + lbl := prometheus.Labels{"webhook": path} + + lat := RequestLatency.MustCurryWith(lbl) + cnt := RequestTotal.MustCurryWith(lbl) + gge := RequestInFlight.With(lbl) + + // Initialize the most likely HTTP status codes. + cnt.WithLabelValues("200") + cnt.WithLabelValues("500") + + return promhttp.InstrumentHandlerDuration( + lat, + promhttp.InstrumentHandlerCounter( + cnt, + promhttp.InstrumentHandlerInFlight(gge, hookRaw), + ), + ) +} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go new file mode 100644 index 00000000..f8820e8b --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go @@ -0,0 +1,302 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package webhook + +import ( + "context" + "crypto/tls" + "crypto/x509" + "fmt" + "net" + "net/http" + "os" + "path/filepath" + "strconv" + "sync" + "time" + + "sigs.k8s.io/controller-runtime/pkg/certwatcher" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/internal/httpserver" + "sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics" +) + +// DefaultPort is the default port that the webhook server serves. +var DefaultPort = 9443 + +// Server is an admission webhook server that can serve traffic and +// generates related k8s resources for deploying. +// +// TLS is required for a webhook to be accessed by kubernetes, so +// you must provide a CertName and KeyName or have valid cert/key +// at the default locations (tls.crt and tls.key). If you do not +// want to configure TLS (i.e for testing purposes) run an +// admission.StandaloneWebhook in your own server. +type Server interface { + // NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates + // the webhook server doesn't need leader election. + NeedLeaderElection() bool + + // Register marks the given webhook as being served at the given path. + // It panics if two hooks are registered on the same path. + Register(path string, hook http.Handler) + + // Start runs the server. + // It will install the webhook related resources depend on the server configuration. + Start(ctx context.Context) error + + // StartedChecker returns an healthz.Checker which is healthy after the + // server has been started. + StartedChecker() healthz.Checker + + // WebhookMux returns the servers WebhookMux + WebhookMux() *http.ServeMux +} + +// Options are all the available options for a webhook.Server +type Options struct { + // Host is the address that the server will listen on. + // Defaults to "" - all addresses. + Host string + + // Port is the port number that the server will serve. + // It will be defaulted to 9443 if unspecified. + Port int + + // CertDir is the directory that contains the server key and certificate. Defaults to + // /k8s-webhook-server/serving-certs. + CertDir string + + // CertName is the server certificate name. Defaults to tls.crt. + // + // Note: This option is only used when TLSOpts does not set GetCertificate. + CertName string + + // KeyName is the server key name. Defaults to tls.key. + // + // Note: This option is only used when TLSOpts does not set GetCertificate. + KeyName string + + // ClientCAName is the CA certificate name which server used to verify remote(client)'s certificate. + // Defaults to "", which means server does not verify client's certificate. + ClientCAName string + + // TLSOpts is used to allow configuring the TLS config used for the server. + // This also allows providing a certificate via GetCertificate. + TLSOpts []func(*tls.Config) + + // WebhookMux is the multiplexer that handles different webhooks. + WebhookMux *http.ServeMux +} + +// NewServer constructs a new webhook.Server from the provided options. +func NewServer(o Options) Server { + return &DefaultServer{ + Options: o, + } +} + +// DefaultServer is the default implementation used for Server. +type DefaultServer struct { + Options Options + + // webhooks keep track of all registered webhooks + webhooks map[string]http.Handler + + // defaultingOnce ensures that the default fields are only ever set once. + defaultingOnce sync.Once + + // started is set to true immediately before the server is started + // and thus can be used to check if the server has been started + started bool + + // mu protects access to the webhook map & setFields for Start, Register, etc + mu sync.Mutex + + webhookMux *http.ServeMux +} + +// setDefaults does defaulting for the Server. +func (o *Options) setDefaults() { + if o.WebhookMux == nil { + o.WebhookMux = http.NewServeMux() + } + + if o.Port <= 0 { + o.Port = DefaultPort + } + + if len(o.CertDir) == 0 { + o.CertDir = filepath.Join(os.TempDir(), "k8s-webhook-server", "serving-certs") + } + + if len(o.CertName) == 0 { + o.CertName = "tls.crt" + } + + if len(o.KeyName) == 0 { + o.KeyName = "tls.key" + } +} + +func (s *DefaultServer) setDefaults() { + s.webhooks = map[string]http.Handler{} + s.Options.setDefaults() + + s.webhookMux = s.Options.WebhookMux +} + +// NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates +// the webhook server doesn't need leader election. +func (*DefaultServer) NeedLeaderElection() bool { + return false +} + +// Register marks the given webhook as being served at the given path. +// It panics if two hooks are registered on the same path. +func (s *DefaultServer) Register(path string, hook http.Handler) { + s.mu.Lock() + defer s.mu.Unlock() + + s.defaultingOnce.Do(s.setDefaults) + if _, found := s.webhooks[path]; found { + panic(fmt.Errorf("can't register duplicate path: %v", path)) + } + s.webhooks[path] = hook + s.webhookMux.Handle(path, metrics.InstrumentedHook(path, hook)) + + regLog := log.WithValues("path", path) + regLog.Info("Registering webhook") +} + +// Start runs the server. +// It will install the webhook related resources depend on the server configuration. +func (s *DefaultServer) Start(ctx context.Context) error { + s.defaultingOnce.Do(s.setDefaults) + + log.Info("Starting webhook server") + + cfg := &tls.Config{ //nolint:gosec + NextProtos: []string{"h2"}, + } + // fallback TLS config ready, will now mutate if passer wants full control over it + for _, op := range s.Options.TLSOpts { + op(cfg) + } + + if cfg.GetCertificate == nil { + certPath := filepath.Join(s.Options.CertDir, s.Options.CertName) + keyPath := filepath.Join(s.Options.CertDir, s.Options.KeyName) + + // Create the certificate watcher and + // set the config's GetCertificate on the TLSConfig + certWatcher, err := certwatcher.New(certPath, keyPath) + if err != nil { + return err + } + cfg.GetCertificate = certWatcher.GetCertificate + + go func() { + if err := certWatcher.Start(ctx); err != nil { + log.Error(err, "certificate watcher error") + } + }() + } + + // Load CA to verify client certificate, if configured. + if s.Options.ClientCAName != "" { + certPool := x509.NewCertPool() + clientCABytes, err := os.ReadFile(filepath.Join(s.Options.CertDir, s.Options.ClientCAName)) + if err != nil { + return fmt.Errorf("failed to read client CA cert: %w", err) + } + + ok := certPool.AppendCertsFromPEM(clientCABytes) + if !ok { + return fmt.Errorf("failed to append client CA cert to CA pool") + } + + cfg.ClientCAs = certPool + cfg.ClientAuth = tls.RequireAndVerifyClientCert + } + + listener, err := tls.Listen("tcp", net.JoinHostPort(s.Options.Host, strconv.Itoa(s.Options.Port)), cfg) + if err != nil { + return err + } + + log.Info("Serving webhook server", "host", s.Options.Host, "port", s.Options.Port) + + srv := httpserver.New(s.webhookMux) + + idleConnsClosed := make(chan struct{}) + go func() { + <-ctx.Done() + log.Info("Shutting down webhook server with timeout of 1 minute") + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { + // Error from closing listeners, or context timeout + log.Error(err, "error shutting down the HTTP server") + } + close(idleConnsClosed) + }() + + s.mu.Lock() + s.started = true + s.mu.Unlock() + if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed { + return err + } + + <-idleConnsClosed + return nil +} + +// StartedChecker returns an healthz.Checker which is healthy after the +// server has been started. +func (s *DefaultServer) StartedChecker() healthz.Checker { + config := &tls.Config{ + InsecureSkipVerify: true, //nolint:gosec // config is used to connect to our own webhook port. + } + return func(req *http.Request) error { + s.mu.Lock() + defer s.mu.Unlock() + + if !s.started { + return fmt.Errorf("webhook server has not been started yet") + } + + d := &net.Dialer{Timeout: 10 * time.Second} + conn, err := tls.DialWithDialer(d, "tcp", net.JoinHostPort(s.Options.Host, strconv.Itoa(s.Options.Port)), config) + if err != nil { + return fmt.Errorf("webhook server is not reachable: %w", err) + } + + if err := conn.Close(); err != nil { + return fmt.Errorf("webhook server is not reachable: closing connection: %w", err) + } + + return nil + } +} + +// WebhookMux returns the servers WebhookMux +func (s *DefaultServer) WebhookMux() *http.ServeMux { + return s.webhookMux +} diff --git a/vendor/sigs.k8s.io/controller-tools/LICENSE b/vendor/sigs.k8s.io/controller-tools/LICENSE deleted file mode 100644 index 8dada3ed..00000000 --- a/vendor/sigs.k8s.io/controller-tools/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. diff --git a/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go b/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go deleted file mode 100644 index c27bcda4..00000000 --- a/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go +++ /dev/null @@ -1,263 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ -package main - -import ( - "encoding/json" - "fmt" - "io" - "os" - "strings" - - "github.com/spf13/cobra" - - "sigs.k8s.io/controller-tools/pkg/crd" - "sigs.k8s.io/controller-tools/pkg/deepcopy" - "sigs.k8s.io/controller-tools/pkg/genall" - "sigs.k8s.io/controller-tools/pkg/genall/help" - prettyhelp "sigs.k8s.io/controller-tools/pkg/genall/help/pretty" - "sigs.k8s.io/controller-tools/pkg/markers" - "sigs.k8s.io/controller-tools/pkg/rbac" - "sigs.k8s.io/controller-tools/pkg/schemapatcher" - "sigs.k8s.io/controller-tools/pkg/version" - "sigs.k8s.io/controller-tools/pkg/webhook" -) - -//go:generate go run ../helpgen/main.go paths=../../pkg/... generate:headerFile=../../boilerplate.go.txt,year=2019 - -// Options are specified to controller-gen by turning generators and output rules into -// markers, and then parsing them using the standard registry logic (without the "+"). -// Each marker and output rule should thus be usable as a marker target. - -var ( - // allGenerators maintains the list of all known generators, giving - // them names for use on the command line. - // each turns into a command line option, - // and has options for output forms. - allGenerators = map[string]genall.Generator{ - "crd": crd.Generator{}, - "rbac": rbac.Generator{}, - "object": deepcopy.Generator{}, - "webhook": webhook.Generator{}, - "schemapatch": schemapatcher.Generator{}, - } - - // allOutputRules defines the list of all known output rules, giving - // them names for use on the command line. - // Each output rule turns into two command line options: - // - output::
(per-generator output) - // - output: (default output) - allOutputRules = map[string]genall.OutputRule{ - "dir": genall.OutputToDirectory(""), - "none": genall.OutputToNothing, - "stdout": genall.OutputToStdout, - "artifacts": genall.OutputArtifacts{}, - } - - // optionsRegistry contains all the marker definitions used to process command line options - optionsRegistry = &markers.Registry{} -) - -func init() { - for genName, gen := range allGenerators { - // make the generator options marker itself - defn := markers.Must(markers.MakeDefinition(genName, markers.DescribesPackage, gen)) - if err := optionsRegistry.Register(defn); err != nil { - panic(err) - } - if helpGiver, hasHelp := gen.(genall.HasHelp); hasHelp { - if help := helpGiver.Help(); help != nil { - optionsRegistry.AddHelp(defn, help) - } - } - - // make per-generation output rule markers - for ruleName, rule := range allOutputRules { - ruleMarker := markers.Must(markers.MakeDefinition(fmt.Sprintf("output:%s:%s", genName, ruleName), markers.DescribesPackage, rule)) - if err := optionsRegistry.Register(ruleMarker); err != nil { - panic(err) - } - if helpGiver, hasHelp := rule.(genall.HasHelp); hasHelp { - if help := helpGiver.Help(); help != nil { - optionsRegistry.AddHelp(ruleMarker, help) - } - } - } - } - - // make "default output" output rule markers - for ruleName, rule := range allOutputRules { - ruleMarker := markers.Must(markers.MakeDefinition("output:"+ruleName, markers.DescribesPackage, rule)) - if err := optionsRegistry.Register(ruleMarker); err != nil { - panic(err) - } - if helpGiver, hasHelp := rule.(genall.HasHelp); hasHelp { - if help := helpGiver.Help(); help != nil { - optionsRegistry.AddHelp(ruleMarker, help) - } - } - } - - // add in the common options markers - if err := genall.RegisterOptionsMarkers(optionsRegistry); err != nil { - panic(err) - } -} - -// noUsageError suppresses usage printing when it occurs -// (since cobra doesn't provide a good way to avoid printing -// out usage in only certain situations). -type noUsageError struct{ error } - -func main() { - helpLevel := 0 - whichLevel := 0 - showVersion := false - - cmd := &cobra.Command{ - Use: "controller-gen", - Short: "Generate Kubernetes API extension resources and code.", - Long: "Generate Kubernetes API extension resources and code.", - Example: ` # Generate RBAC manifests and crds for all types under apis/, - # outputting crds to /tmp/crds and everything else to stdout - controller-gen rbac:roleName= crd paths=./apis/... output:crd:dir=/tmp/crds output:stdout - - # Generate deepcopy/runtime.Object implementations for a particular file - controller-gen object paths=./apis/v1beta1/some_types.go - - # Generate OpenAPI v3 schemas for API packages and merge them into existing CRD manifests - controller-gen schemapatch:manifests=./manifests output:dir=./manifests paths=./pkg/apis/... - - # Run all the generators for a given project - controller-gen paths=./apis/... - - # Explain the markers for generating CRDs, and their arguments - controller-gen crd -ww -`, - RunE: func(c *cobra.Command, rawOpts []string) error { - // print version if asked for it - if showVersion { - version.Print() - return nil - } - - // print the help if we asked for it (since we've got a different help flag :-/), then bail - if helpLevel > 0 { - return c.Usage() - } - - // print the marker docs if we asked for them, then bail - if whichLevel > 0 { - return printMarkerDocs(c, rawOpts, whichLevel) - } - - // otherwise, set up the runtime for actually running the generators - rt, err := genall.FromOptions(optionsRegistry, rawOpts) - if err != nil { - return err - } - if len(rt.Generators) == 0 { - return fmt.Errorf("no generators specified") - } - - if hadErrs := rt.Run(); hadErrs { - // don't obscure the actual error with a bunch of usage - return noUsageError{fmt.Errorf("not all generators ran successfully")} - } - return nil - }, - SilenceUsage: true, // silence the usage, then print it out ourselves if it wasn't suppressed - } - cmd.Flags().CountVarP(&whichLevel, "which-markers", "w", "print out all markers available with the requested generators\n(up to -www for the most detailed output, or -wwww for json output)") - cmd.Flags().CountVarP(&helpLevel, "detailed-help", "h", "print out more detailed help\n(up to -hhh for the most detailed output, or -hhhh for json output)") - cmd.Flags().BoolVar(&showVersion, "version", false, "show version") - cmd.Flags().Bool("help", false, "print out usage and a summary of options") - oldUsage := cmd.UsageFunc() - cmd.SetUsageFunc(func(c *cobra.Command) error { - if err := oldUsage(c); err != nil { - return err - } - if helpLevel == 0 { - helpLevel = summaryHelp - } - fmt.Fprintf(c.OutOrStderr(), "\n\nOptions\n\n") - return helpForLevels(c.OutOrStdout(), c.OutOrStderr(), helpLevel, optionsRegistry, help.SortByOption) - }) - - if err := cmd.Execute(); err != nil { - if _, noUsage := err.(noUsageError); !noUsage { - // print the usage unless we suppressed it - if err := cmd.Usage(); err != nil { - panic(err) - } - } - fmt.Fprintf(cmd.OutOrStderr(), "run `%[1]s %[2]s -w` to see all available markers, or `%[1]s %[2]s -h` for usage\n", cmd.CalledAs(), strings.Join(os.Args[1:], " ")) - os.Exit(1) - } -} - -// printMarkerDocs prints out marker help for the given generators specified in -// the rawOptions, at the given level. -func printMarkerDocs(c *cobra.Command, rawOptions []string, whichLevel int) error { - // just grab a registry so we don't lag while trying to load roots - // (like we'd do if we just constructed the full runtime). - reg, err := genall.RegistryFromOptions(optionsRegistry, rawOptions) - if err != nil { - return err - } - - return helpForLevels(c.OutOrStdout(), c.OutOrStderr(), whichLevel, reg, help.SortByCategory) -} - -func helpForLevels(mainOut io.Writer, errOut io.Writer, whichLevel int, reg *markers.Registry, sorter help.SortGroup) error { - helpInfo := help.ByCategory(reg, sorter) - switch whichLevel { - case jsonHelp: - if err := json.NewEncoder(mainOut).Encode(helpInfo); err != nil { - return err - } - case detailedHelp, fullHelp: - fullDetail := whichLevel == fullHelp - for _, cat := range helpInfo { - if cat.Category == "" { - continue - } - contents := prettyhelp.MarkersDetails(fullDetail, cat.Category, cat.Markers) - if err := contents.WriteTo(errOut); err != nil { - return err - } - } - case summaryHelp: - for _, cat := range helpInfo { - if cat.Category == "" { - continue - } - contents := prettyhelp.MarkersSummary(cat.Category, cat.Markers) - if err := contents.WriteTo(errOut); err != nil { - return err - } - } - } - return nil -} - -const ( - _ = iota - summaryHelp - detailedHelp - fullHelp - jsonHelp -) diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/conv.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/conv.go deleted file mode 100644 index 374e02c3..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/conv.go +++ /dev/null @@ -1,43 +0,0 @@ -package crd - -import ( - "fmt" - - apiextinternal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -var ( - conversionScheme = runtime.NewScheme() -) - -func init() { - if err := apiextinternal.AddToScheme(conversionScheme); err != nil { - panic("must be able to add internal apiextensions to the CRD conversion Scheme") - } - if err := apiext.AddToScheme(conversionScheme); err != nil { - panic("must be able to add apiextensions/v1 to the CRD conversion Scheme") - } -} - -// AsVersion converts a CRD from the canonical internal form (currently v1) to some external form. -func AsVersion(original apiext.CustomResourceDefinition, gv schema.GroupVersion) (runtime.Object, error) { - // TODO: Do we need to keep maintaining this conversion function - // post 1.22 when only CRDv1 is served by the apiserver? - if gv == apiextv1beta1.SchemeGroupVersion { - return nil, fmt.Errorf("apiVersion %q is not supported", gv.String()) - } - // We can use the internal versions an existing conversions from kubernetes, since they're not in k/k itself. - // This punts the problem of conversion down the road for a future maintainer (or future instance of @directxman12) - // when we have to support older versions that get removed, or when API machinery decides to yell at us for this - // questionable decision. - intVer, err := conversionScheme.ConvertToVersion(&original, apiextinternal.SchemeGroupVersion) - if err != nil { - return nil, fmt.Errorf("unable to convert to internal CRD version: %w", err) - } - - return conversionScheme.ConvertToVersion(intVer, gv) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/desc_visitor.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/desc_visitor.go deleted file mode 100644 index cba36c46..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/desc_visitor.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package crd - -import ( - "strings" - "unicode" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" -) - -// TruncateDescription truncates the description of fields in given schema if it -// exceeds maxLen. -// It tries to chop off the description at the closest sentence boundary. -func TruncateDescription(schema *apiext.JSONSchemaProps, maxLen int) { - EditSchema(schema, descVisitor{maxLen: maxLen}) -} - -// descVisitor recursively visits all fields in the schema and truncates the -// description of the fields to specified maxLen. -type descVisitor struct { - // maxLen is the maximum allowed length for decription of a field - maxLen int -} - -func (v descVisitor) Visit(schema *apiext.JSONSchemaProps) SchemaVisitor { - if schema == nil { - return v - } - if v.maxLen < 0 { - return nil /* no further work to be done for this schema */ - } - if v.maxLen == 0 { - schema.Description = "" - return v - } - if len(schema.Description) > v.maxLen { - schema.Description = truncateString(schema.Description, v.maxLen) - return v - } - return v -} - -// truncateString truncates given desc string if it exceeds maxLen. It may -// return string with length less than maxLen even in cases where original desc -// exceeds maxLen because it tries to chop off the desc at the closest sentence -// boundary to avoid incomplete sentences. -func truncateString(desc string, maxLen int) string { - desc = desc[0:maxLen] - - // Trying to chop off at closest sentence boundary. - if n := strings.LastIndexFunc(desc, isSentenceTerminal); n > 0 { - return desc[0 : n+1] - } - // TODO(droot): Improve the logic to chop off at closest word boundary - // or add elipses (...) to indicate that it's chopped incase no closest - // sentence found within maxLen. - return desc -} - -// helper function to determine if given rune is a sentence terminal or not. -func isSentenceTerminal(r rune) bool { - return unicode.Is(unicode.STerm, r) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/doc.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/doc.go deleted file mode 100644 index 914af94d..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/doc.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// Package crd contains utilities for generating CustomResourceDefinitions and -// their corresponding OpenAPI validation schemata. -// -// # Markers -// -// Markers live under the markers subpackage. Two types of markers exist: -// those that modify schema generation (for validation), and those that modify -// the rest of the CRD. See the subpackage for more information and all -// supported markers. -// -// # Collecting Types and Generating CRDs -// -// The Parser is the entrypoint for collecting the information required to -// generate CRDs. Like loader and collector, its methods are idemptotent, not -// doing extra work if called multiple times. -// -// Parser's method start with Need. Calling NeedXYZ indicates that XYZ should -// be made present in the eqivalent field in the Parser, where it can then be -// loaded from. Each Need method will in turn call Need on anything it needs. -// -// In general, root packages should first be loaded into the Parser with -// NeedPackage. Then, CRDs can be generated with NeedCRDFor. -// -// Errors are generally attached directly to the relevant Package with -// AddError. -// -// # Known Packages -// -// There are a few types from Kubernetes that have special meaning, but don't -// have validation markers attached. Those specific types have overrides -// listed in KnownPackages that can be added as overrides to any parser. -// -// # Flattening -// -// Once schemata are generated, they can be used directly by external tooling -// (like JSONSchema validators), but must first be "flattened" to not contain -// references before use in a CRD (Kubernetes doesn't allow references in the -// CRD's validation schema). -// -// The Flattener built in to the Parser takes care of flattening out references -// when requesting the CRDs, but can be invoked manually. It will not modify -// the input schemata. -// -// Flattened schemata may further be passed to FlattenEmbedded to remove the -// use of AllOf (which is used to describe embedded struct fields when -// references are in use). This done automatically when fetching CRDs. -package crd diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/flatten.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/flatten.go deleted file mode 100644 index 9224c26b..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/flatten.go +++ /dev/null @@ -1,445 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package crd - -import ( - "fmt" - "reflect" - "sort" - "strings" - "sync" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - - "sigs.k8s.io/controller-tools/pkg/loader" -) - -// ErrorRecorder knows how to record errors. It wraps the part of -// pkg/loader.Package that we need to record errors in places were it might not -// make sense to have a loader.Package -type ErrorRecorder interface { - // AddError records that the given error occurred. - // See the documentation on loader.Package.AddError for more information. - AddError(error) -} - -// isOrNil checks if val is nil if val is of a nillable type, otherwise, -// it compares val to valInt (which should probably be the zero value). -func isOrNil(val reflect.Value, valInt interface{}, zeroInt interface{}) bool { - switch valKind := val.Kind(); valKind { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return val.IsNil() - default: - return valInt == zeroInt - } -} - -// flattenAllOfInto copies properties from src to dst, then copies the properties -// of each item in src's allOf to dst's properties as well. -func flattenAllOfInto(dst *apiext.JSONSchemaProps, src apiext.JSONSchemaProps, errRec ErrorRecorder) { - if len(src.AllOf) > 0 { - for _, embedded := range src.AllOf { - flattenAllOfInto(dst, embedded, errRec) - } - } - - dstVal := reflect.Indirect(reflect.ValueOf(dst)) - srcVal := reflect.ValueOf(src) - typ := dstVal.Type() - - srcRemainder := apiext.JSONSchemaProps{} - srcRemVal := reflect.Indirect(reflect.ValueOf(&srcRemainder)) - dstRemainder := apiext.JSONSchemaProps{} - dstRemVal := reflect.Indirect(reflect.ValueOf(&dstRemainder)) - hoisted := false - - for i := 0; i < srcVal.NumField(); i++ { - fieldName := typ.Field(i).Name - switch fieldName { - case "AllOf": - // don't merge because we deal with it above - continue - case "Title", "Description", "Example", "ExternalDocs": - // don't merge because we pre-merge to properly preserve field docs - continue - } - srcField := srcVal.Field(i) - fldTyp := srcField.Type() - zeroVal := reflect.Zero(fldTyp) - zeroInt := zeroVal.Interface() - srcInt := srcField.Interface() - - if isOrNil(srcField, srcInt, zeroInt) { - // nothing to copy from src, continue - continue - } - - dstField := dstVal.Field(i) - dstInt := dstField.Interface() - if isOrNil(dstField, dstInt, zeroInt) { - // dst is empty, continue - dstField.Set(srcField) - continue - } - - if fldTyp.Comparable() && srcInt == dstInt { - // same value, continue - continue - } - - // resolve conflict - switch fieldName { - case "Properties": - // merge if possible, use all of otherwise - srcMap := srcInt.(map[string]apiext.JSONSchemaProps) - dstMap := dstInt.(map[string]apiext.JSONSchemaProps) - - for k, v := range srcMap { - dstProp, exists := dstMap[k] - if !exists { - dstMap[k] = v - continue - } - flattenAllOfInto(&dstProp, v, errRec) - dstMap[k] = dstProp - } - case "Required": - // merge - dstField.Set(reflect.AppendSlice(dstField, srcField)) - case "Type": - if srcInt != dstInt { - // TODO(directxman12): figure out how to attach this back to a useful point in the Go source or in the schema - errRec.AddError(fmt.Errorf("conflicting types in allOf branches in schema: %s vs %s", dstInt, srcInt)) - } - // keep the destination value, for now - // TODO(directxman12): Default -- use field? - // TODO(directxman12): - // - Dependencies: if field x is present, then either schema validates or all props are present - // - AdditionalItems: like AdditionalProperties - // - Definitions: common named validation sets that can be references (merge, bail if duplicate) - case "AdditionalProperties": - // as of the time of writing, `allows: false` is not allowed, so we don't have to handle it - srcProps := srcInt.(*apiext.JSONSchemaPropsOrBool) - if srcProps.Schema == nil { - // nothing to merge - continue - } - dstProps := dstInt.(*apiext.JSONSchemaPropsOrBool) - if dstProps.Schema == nil { - dstProps.Schema = &apiext.JSONSchemaProps{} - } - flattenAllOfInto(dstProps.Schema, *srcProps.Schema, errRec) - case "XPreserveUnknownFields": - dstField.Set(srcField) - case "XMapType": - dstField.Set(srcField) - // NB(directxman12): no need to explicitly handle nullable -- false is considered to be the zero value - // TODO(directxman12): src isn't necessarily the field value -- it's just the most recent allOf entry - default: - // hoist into allOf... - hoisted = true - - srcRemVal.Field(i).Set(srcField) - dstRemVal.Field(i).Set(dstField) - // ...and clear the original - dstField.Set(zeroVal) - } - } - - if hoisted { - dst.AllOf = append(dst.AllOf, dstRemainder, srcRemainder) - } - - // dedup required - if len(dst.Required) > 0 { - reqUniq := make(map[string]struct{}) - for _, req := range dst.Required { - reqUniq[req] = struct{}{} - } - dst.Required = make([]string, 0, len(reqUniq)) - for req := range reqUniq { - dst.Required = append(dst.Required, req) - } - // be deterministic - sort.Strings(dst.Required) - } -} - -// allOfVisitor recursively visits allOf fields in the schema, -// merging nested allOf properties into the root schema. -type allOfVisitor struct { - // errRec is used to record errors while flattening (like two conflicting - // field values used in an allOf) - errRec ErrorRecorder -} - -func (v *allOfVisitor) Visit(schema *apiext.JSONSchemaProps) SchemaVisitor { - if schema == nil { - return v - } - - // clear this now so that we can safely preserve edits made my flattenAllOfInto - origAllOf := schema.AllOf - schema.AllOf = nil - - for _, embedded := range origAllOf { - flattenAllOfInto(schema, embedded, v.errRec) - } - return v -} - -// NB(directxman12): FlattenEmbedded is separate from Flattener because -// some tooling wants to flatten out embedded fields, but only actually -// flatten a few specific types first. - -// FlattenEmbedded flattens embedded fields (represented via AllOf) which have -// already had their references resolved into simple properties in the containing -// schema. -func FlattenEmbedded(schema *apiext.JSONSchemaProps, errRec ErrorRecorder) *apiext.JSONSchemaProps { - outSchema := schema.DeepCopy() - EditSchema(outSchema, &allOfVisitor{errRec: errRec}) - return outSchema -} - -// Flattener knows how to take a root type, and flatten all references in it -// into a single, flat type. Flattened types are cached, so it's relatively -// cheap to make repeated calls with the same type. -type Flattener struct { - // Parser is used to lookup package and type details, and parse in new packages. - Parser *Parser - - LookupReference func(ref string, contextPkg *loader.Package) (TypeIdent, error) - - // flattenedTypes hold the flattened version of each seen type for later reuse. - flattenedTypes map[TypeIdent]apiext.JSONSchemaProps - initOnce sync.Once -} - -func (f *Flattener) init() { - f.initOnce.Do(func() { - f.flattenedTypes = make(map[TypeIdent]apiext.JSONSchemaProps) - if f.LookupReference == nil { - f.LookupReference = identFromRef - } - }) -} - -// cacheType saves the flattened version of the given type for later reuse -func (f *Flattener) cacheType(typ TypeIdent, schema apiext.JSONSchemaProps) { - f.init() - f.flattenedTypes[typ] = schema -} - -// loadUnflattenedSchema fetches a fresh, unflattened schema from the parser. -func (f *Flattener) loadUnflattenedSchema(typ TypeIdent) (*apiext.JSONSchemaProps, error) { - f.Parser.NeedSchemaFor(typ) - - baseSchema, found := f.Parser.Schemata[typ] - if !found { - return nil, fmt.Errorf("unable to locate schema for type %s", typ) - } - return &baseSchema, nil -} - -// FlattenType flattens the given pre-loaded type, removing any references from it. -// It deep-copies the schema first, so it won't affect the parser's version of the schema. -func (f *Flattener) FlattenType(typ TypeIdent) *apiext.JSONSchemaProps { - f.init() - if cachedSchema, isCached := f.flattenedTypes[typ]; isCached { - return &cachedSchema - } - baseSchema, err := f.loadUnflattenedSchema(typ) - if err != nil { - typ.Package.AddError(err) - return nil - } - resSchema := f.FlattenSchema(*baseSchema, typ.Package) - f.cacheType(typ, *resSchema) - return resSchema -} - -// FlattenSchema flattens the given schema, removing any references. -// It deep-copies the schema first, so the input schema won't be affected. -func (f *Flattener) FlattenSchema(baseSchema apiext.JSONSchemaProps, currentPackage *loader.Package) *apiext.JSONSchemaProps { - resSchema := baseSchema.DeepCopy() - EditSchema(resSchema, &flattenVisitor{ - Flattener: f, - currentPackage: currentPackage, - }) - - return resSchema -} - -// RefParts splits a reference produced by the schema generator into its component -// type name and package name (if it's a cross-package reference). Note that -// referenced packages *must* be looked up relative to the current package. -func RefParts(ref string) (typ string, pkgName string, err error) { - if !strings.HasPrefix(ref, defPrefix) { - return "", "", fmt.Errorf("non-standard reference link %q", ref) - } - ref = ref[len(defPrefix):] - // decode the json pointer encodings - ref = strings.Replace(ref, "~1", "/", -1) - ref = strings.Replace(ref, "~0", "~", -1) - nameParts := strings.SplitN(ref, "~", 2) - - if len(nameParts) == 1 { - // local reference - return nameParts[0], "", nil - } - // cross-package reference - return nameParts[1], nameParts[0], nil -} - -// identFromRef converts the given schema ref from the given package back -// into the TypeIdent that it represents. -func identFromRef(ref string, contextPkg *loader.Package) (TypeIdent, error) { - typ, pkgName, err := RefParts(ref) - if err != nil { - return TypeIdent{}, err - } - - if pkgName == "" { - // a local reference - return TypeIdent{ - Name: typ, - Package: contextPkg, - }, nil - } - - // an external reference - return TypeIdent{ - Name: typ, - Package: contextPkg.Imports()[pkgName], - }, nil -} - -// preserveFields copies documentation fields from src into dst, preserving -// field-level documentation when flattening, and preserving field-level validation -// as allOf entries. -func preserveFields(dst *apiext.JSONSchemaProps, src apiext.JSONSchemaProps) { - srcDesc := src.Description - srcTitle := src.Title - srcExDoc := src.ExternalDocs - srcEx := src.Example - - src.Description, src.Title, src.ExternalDocs, src.Example = "", "", nil, nil - - src.Ref = nil - *dst = apiext.JSONSchemaProps{ - AllOf: []apiext.JSONSchemaProps{*dst, src}, - - // keep these, in case the source field doesn't specify anything useful - Description: dst.Description, - Title: dst.Title, - ExternalDocs: dst.ExternalDocs, - Example: dst.Example, - } - - if srcDesc != "" { - dst.Description = srcDesc - } - if srcTitle != "" { - dst.Title = srcTitle - } - if srcExDoc != nil { - dst.ExternalDocs = srcExDoc - } - if srcEx != nil { - dst.Example = srcEx - } -} - -// flattenVisitor visits each node in the schema, recursively flattening references. -type flattenVisitor struct { - *Flattener - - currentPackage *loader.Package - currentType *TypeIdent - currentSchema *apiext.JSONSchemaProps - originalField apiext.JSONSchemaProps -} - -func (f *flattenVisitor) Visit(baseSchema *apiext.JSONSchemaProps) SchemaVisitor { - if baseSchema == nil { - // end-of-node marker, cache the results - if f.currentType != nil { - f.cacheType(*f.currentType, *f.currentSchema) - // preserve field information *after* caching so that we don't - // accidentally cache field-level information onto the schema for - // the type in general. - preserveFields(f.currentSchema, f.originalField) - } - return f - } - - // if we get a type that's just a ref, resolve it - if baseSchema.Ref != nil && len(*baseSchema.Ref) > 0 { - // resolve this ref - refIdent, err := f.LookupReference(*baseSchema.Ref, f.currentPackage) - if err != nil { - f.currentPackage.AddError(err) - return nil - } - - // load and potentially flatten the schema - - // check the cache first... - if refSchemaCached, isCached := f.flattenedTypes[refIdent]; isCached { - // shallow copy is fine, it's just to avoid overwriting the doc fields - preserveFields(&refSchemaCached, *baseSchema) - *baseSchema = refSchemaCached - return nil // don't recurse, we're done - } - - // ...otherwise, we need to flatten - refSchema, err := f.loadUnflattenedSchema(refIdent) - if err != nil { - f.currentPackage.AddError(err) - return nil - } - refSchema = refSchema.DeepCopy() - - // keep field around to preserve field-level validation, docs, etc - origField := *baseSchema - *baseSchema = *refSchema - - // avoid loops (which shouldn't exist, but just in case) - // by marking a nil cached pointer before we start recursing - f.cacheType(refIdent, apiext.JSONSchemaProps{}) - - return &flattenVisitor{ - Flattener: f.Flattener, - - currentPackage: refIdent.Package, - currentType: &refIdent, - currentSchema: baseSchema, - originalField: origField, - } - } - - // otherwise, continue recursing... - if f.currentType != nil { - // ...but don't accidentally end this node early (for caching purposes) - return &flattenVisitor{ - Flattener: f.Flattener, - currentPackage: f.currentPackage, - } - } - - return f -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/gen.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/gen.go deleted file mode 100644 index c6c5f88b..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/gen.go +++ /dev/null @@ -1,307 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -package crd - -import ( - "fmt" - "go/ast" - "go/types" - "sort" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - - crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers" - "sigs.k8s.io/controller-tools/pkg/genall" - "sigs.k8s.io/controller-tools/pkg/loader" - "sigs.k8s.io/controller-tools/pkg/markers" - "sigs.k8s.io/controller-tools/pkg/version" -) - -// The identifier for v1 CustomResourceDefinitions. -const v1 = "v1" - -// The default CustomResourceDefinition version to generate. -const defaultVersion = v1 - -// +controllertools:marker:generateHelp - -// Generator generates CustomResourceDefinition objects. -type Generator struct { - // IgnoreUnexportedFields indicates that we should skip unexported fields. - // - // Left unspecified, the default is false. - IgnoreUnexportedFields *bool `marker:",optional"` - - // AllowDangerousTypes allows types which are usually omitted from CRD generation - // because they are not recommended. - // - // Currently the following additional types are allowed when this is true: - // float32 - // float64 - // - // Left unspecified, the default is false - AllowDangerousTypes *bool `marker:",optional"` - - // MaxDescLen specifies the maximum description length for fields in CRD's OpenAPI schema. - // - // 0 indicates drop the description for all fields completely. - // n indicates limit the description to at most n characters and truncate the description to - // closest sentence boundary if it exceeds n characters. - MaxDescLen *int `marker:",optional"` - - // CRDVersions specifies the target API versions of the CRD type itself to - // generate. Defaults to v1. - // - // Currently, the only supported value is v1. - // - // The first version listed will be assumed to be the "default" version and - // will not get a version suffix in the output filename. - // - // You'll need to use "v1" to get support for features like defaulting, - // along with an API server that supports it (Kubernetes 1.16+). - CRDVersions []string `marker:"crdVersions,optional"` - - // GenerateEmbeddedObjectMeta specifies if any embedded ObjectMeta in the CRD should be generated - GenerateEmbeddedObjectMeta *bool `marker:",optional"` -} - -func (Generator) CheckFilter() loader.NodeFilter { - return filterTypesForCRDs -} -func (Generator) RegisterMarkers(into *markers.Registry) error { - return crdmarkers.Register(into) -} - -// transformRemoveCRDStatus ensures we do not write the CRD status field. -func transformRemoveCRDStatus(obj map[string]interface{}) error { - delete(obj, "status") - return nil -} - -func (g Generator) Generate(ctx *genall.GenerationContext) error { - parser := &Parser{ - Collector: ctx.Collector, - Checker: ctx.Checker, - // Perform defaulting here to avoid ambiguity later - IgnoreUnexportedFields: g.IgnoreUnexportedFields != nil && *g.IgnoreUnexportedFields == true, - AllowDangerousTypes: g.AllowDangerousTypes != nil && *g.AllowDangerousTypes == true, - // Indicates the parser on whether to register the ObjectMeta type or not - GenerateEmbeddedObjectMeta: g.GenerateEmbeddedObjectMeta != nil && *g.GenerateEmbeddedObjectMeta == true, - } - - AddKnownTypes(parser) - for _, root := range ctx.Roots { - parser.NeedPackage(root) - } - - metav1Pkg := FindMetav1(ctx.Roots) - if metav1Pkg == nil { - // no objects in the roots, since nothing imported metav1 - return nil - } - - // TODO: allow selecting a specific object - kubeKinds := FindKubeKinds(parser, metav1Pkg) - if len(kubeKinds) == 0 { - // no objects in the roots - return nil - } - - crdVersions := g.CRDVersions - - if len(crdVersions) == 0 { - crdVersions = []string{defaultVersion} - } - - for _, groupKind := range kubeKinds { - parser.NeedCRDFor(groupKind, g.MaxDescLen) - crdRaw := parser.CustomResourceDefinitions[groupKind] - addAttribution(&crdRaw) - - // Prevent the top level metadata for the CRD to be generate regardless of the intention in the arguments - FixTopLevelMetadata(crdRaw) - - versionedCRDs := make([]interface{}, len(crdVersions)) - for i, ver := range crdVersions { - conv, err := AsVersion(crdRaw, schema.GroupVersion{Group: apiext.SchemeGroupVersion.Group, Version: ver}) - if err != nil { - return err - } - versionedCRDs[i] = conv - } - - for i, crd := range versionedCRDs { - removeDescriptionFromMetadata(crd.(*apiext.CustomResourceDefinition)) - var fileName string - if i == 0 { - fileName = fmt.Sprintf("%s_%s.yaml", crdRaw.Spec.Group, crdRaw.Spec.Names.Plural) - } else { - fileName = fmt.Sprintf("%s_%s.%s.yaml", crdRaw.Spec.Group, crdRaw.Spec.Names.Plural, crdVersions[i]) - } - if err := ctx.WriteYAML(fileName, []interface{}{crd}, genall.WithTransform(transformRemoveCRDStatus)); err != nil { - return err - } - } - } - - return nil -} - -func removeDescriptionFromMetadata(crd *apiext.CustomResourceDefinition) { - for _, versionSpec := range crd.Spec.Versions { - if versionSpec.Schema != nil { - removeDescriptionFromMetadataProps(versionSpec.Schema.OpenAPIV3Schema) - } - } -} - -func removeDescriptionFromMetadataProps(v *apiext.JSONSchemaProps) { - if m, ok := v.Properties["metadata"]; ok { - meta := &m - if meta.Description != "" { - meta.Description = "" - v.Properties["metadata"] = m - - } - } -} - -// FixTopLevelMetadata resets the schema for the top-level metadata field which is needed for CRD validation -func FixTopLevelMetadata(crd apiext.CustomResourceDefinition) { - for _, v := range crd.Spec.Versions { - if v.Schema != nil && v.Schema.OpenAPIV3Schema != nil && v.Schema.OpenAPIV3Schema.Properties != nil { - schemaProperties := v.Schema.OpenAPIV3Schema.Properties - if _, ok := schemaProperties["metadata"]; ok { - schemaProperties["metadata"] = apiext.JSONSchemaProps{Type: "object"} - } - } - } -} - -// addAttribution adds attribution info to indicate controller-gen tool was used -// to generate this CRD definition along with the version info. -func addAttribution(crd *apiext.CustomResourceDefinition) { - if crd.ObjectMeta.Annotations == nil { - crd.ObjectMeta.Annotations = map[string]string{} - } - crd.ObjectMeta.Annotations["controller-gen.kubebuilder.io/version"] = version.Version() -} - -// FindMetav1 locates the actual package representing metav1 amongst -// the imports of the roots. -func FindMetav1(roots []*loader.Package) *loader.Package { - for _, root := range roots { - pkg := root.Imports()["k8s.io/apimachinery/pkg/apis/meta/v1"] - if pkg != nil { - return pkg - } - } - return nil -} - -// FindKubeKinds locates all types that contain TypeMeta and ObjectMeta -// (and thus may be a Kubernetes object), and returns the corresponding -// group-kinds. -func FindKubeKinds(parser *Parser, metav1Pkg *loader.Package) []schema.GroupKind { - // TODO(directxman12): technically, we should be finding metav1 per-package - kubeKinds := map[schema.GroupKind]struct{}{} - for typeIdent, info := range parser.Types { - hasObjectMeta := false - hasTypeMeta := false - - pkg := typeIdent.Package - pkg.NeedTypesInfo() - typesInfo := pkg.TypesInfo - - for _, field := range info.Fields { - if field.Name != "" { - // type and object meta are embedded, - // so they can't be this - continue - } - - fieldType := typesInfo.TypeOf(field.RawField.Type) - namedField, isNamed := fieldType.(*types.Named) - if !isNamed { - // ObjectMeta and TypeMeta are named types - continue - } - if namedField.Obj().Pkg() == nil { - // Embedded non-builtin universe type (specifically, it's probably `error`), - // so it can't be ObjectMeta or TypeMeta - continue - } - fieldPkgPath := loader.NonVendorPath(namedField.Obj().Pkg().Path()) - fieldPkg := pkg.Imports()[fieldPkgPath] - - // Compare the metav1 package by ID and not by the actual instance - // of the object. The objects in memory could be different due to - // loading from different root paths, even when they both refer to - // the same metav1 package. - if fieldPkg == nil || fieldPkg.ID != metav1Pkg.ID { - continue - } - - switch namedField.Obj().Name() { - case "ObjectMeta": - hasObjectMeta = true - case "TypeMeta": - hasTypeMeta = true - } - } - - if !hasObjectMeta || !hasTypeMeta { - continue - } - - groupKind := schema.GroupKind{ - Group: parser.GroupVersions[pkg].Group, - Kind: typeIdent.Name, - } - kubeKinds[groupKind] = struct{}{} - } - - groupKindList := make([]schema.GroupKind, 0, len(kubeKinds)) - for groupKind := range kubeKinds { - groupKindList = append(groupKindList, groupKind) - } - sort.Slice(groupKindList, func(i, j int) bool { - return groupKindList[i].String() < groupKindList[j].String() - }) - - return groupKindList -} - -// filterTypesForCRDs filters out all nodes that aren't used in CRD generation, -// like interfaces and struct fields without JSON tag. -func filterTypesForCRDs(node ast.Node) bool { - switch node := node.(type) { - case *ast.InterfaceType: - // skip interfaces, we never care about references in them - return false - case *ast.StructType: - return true - case *ast.Field: - _, hasTag := loader.ParseAstTag(node.Tag).Lookup("json") - // fields without JSON tags mean we have custom serialization, - // so only visit fields with tags. - return hasTag - default: - return true - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/known_types.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/known_types.go deleted file mode 100644 index 9e8decb2..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/known_types.go +++ /dev/null @@ -1,180 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ -package crd - -import ( - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - - "sigs.k8s.io/controller-tools/pkg/loader" -) - -// KnownPackages overrides types in some comment packages that have custom validation -// but don't have validation markers on them (since they're from core Kubernetes). -var KnownPackages = map[string]PackageOverride{ - "k8s.io/api/core/v1": func(p *Parser, pkg *loader.Package) { - // Explicit defaulting for the corev1.Protocol type in lieu of https://github.com/kubernetes/enhancements/pull/1928 - p.Schemata[TypeIdent{Name: "Protocol", Package: pkg}] = apiext.JSONSchemaProps{ - Type: "string", - Default: &apiext.JSON{Raw: []byte(`"TCP"`)}, - } - p.AddPackage(pkg) - }, - - "k8s.io/apimachinery/pkg/apis/meta/v1": func(p *Parser, pkg *loader.Package) { - p.Schemata[TypeIdent{Name: "ObjectMeta", Package: pkg}] = apiext.JSONSchemaProps{ - Type: "object", - } - p.Schemata[TypeIdent{Name: "Time", Package: pkg}] = apiext.JSONSchemaProps{ - Type: "string", - Format: "date-time", - } - p.Schemata[TypeIdent{Name: "MicroTime", Package: pkg}] = apiext.JSONSchemaProps{ - Type: "string", - Format: "date-time", - } - p.Schemata[TypeIdent{Name: "Duration", Package: pkg}] = apiext.JSONSchemaProps{ - // TODO(directxman12): regexp validation for this (or get kube to support it as a format value) - Type: "string", - } - p.Schemata[TypeIdent{Name: "Fields", Package: pkg}] = apiext.JSONSchemaProps{ - // this is a recursive structure that can't be flattened or, for that matter, properly generated. - // so just treat it as an arbitrary map - Type: "object", - AdditionalProperties: &apiext.JSONSchemaPropsOrBool{Allows: true}, - } - p.AddPackage(pkg) // get the rest of the types - }, - - "k8s.io/apimachinery/pkg/api/resource": func(p *Parser, pkg *loader.Package) { - p.Schemata[TypeIdent{Name: "Quantity", Package: pkg}] = apiext.JSONSchemaProps{ - // TODO(directxman12): regexp validation for this (or get kube to support it as a format value) - XIntOrString: true, - AnyOf: []apiext.JSONSchemaProps{ - {Type: "integer"}, - {Type: "string"}, - }, - Pattern: "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", - } - // No point in calling AddPackage, this is the sole inhabitant - }, - - "k8s.io/apimachinery/pkg/runtime": func(p *Parser, pkg *loader.Package) { - p.Schemata[TypeIdent{Name: "RawExtension", Package: pkg}] = apiext.JSONSchemaProps{ - // TODO(directxman12): regexp validation for this (or get kube to support it as a format value) - Type: "object", - XPreserveUnknownFields: boolPtr(true), - } - p.AddPackage(pkg) // get the rest of the types - }, - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured": func(p *Parser, pkg *loader.Package) { - p.Schemata[TypeIdent{Name: "Unstructured", Package: pkg}] = apiext.JSONSchemaProps{ - Type: "object", - } - p.AddPackage(pkg) // get the rest of the types - }, - - "k8s.io/apimachinery/pkg/util/intstr": func(p *Parser, pkg *loader.Package) { - p.Schemata[TypeIdent{Name: "IntOrString", Package: pkg}] = apiext.JSONSchemaProps{ - XIntOrString: true, - AnyOf: []apiext.JSONSchemaProps{ - {Type: "integer"}, - {Type: "string"}, - }, - } - // No point in calling AddPackage, this is the sole inhabitant - }, - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1": func(p *Parser, pkg *loader.Package) { - p.Schemata[TypeIdent{Name: "JSON", Package: pkg}] = apiext.JSONSchemaProps{ - XPreserveUnknownFields: boolPtr(true), - } - p.AddPackage(pkg) // get the rest of the types - }, - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1": func(p *Parser, pkg *loader.Package) { - p.Schemata[TypeIdent{Name: "JSON", Package: pkg}] = apiext.JSONSchemaProps{ - XPreserveUnknownFields: boolPtr(true), - } - p.AddPackage(pkg) // get the rest of the types - }, -} - -// ObjectMetaPackages overrides the ObjectMeta in all types -var ObjectMetaPackages = map[string]PackageOverride{ - "k8s.io/apimachinery/pkg/apis/meta/v1": func(p *Parser, pkg *loader.Package) { - // execute the KnowPackages for `k8s.io/apimachinery/pkg/apis/meta/v1` if any - if f, ok := KnownPackages["k8s.io/apimachinery/pkg/apis/meta/v1"]; ok { - f(p, pkg) - } - // This is an allow-listed set of properties of ObjectMeta, other runtime properties are not part of this list - // See more discussion: https://github.com/kubernetes-sigs/controller-tools/pull/395#issuecomment-691919433 - p.Schemata[TypeIdent{Name: "ObjectMeta", Package: pkg}] = apiext.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiext.JSONSchemaProps{ - "name": { - Type: "string", - }, - "namespace": { - Type: "string", - }, - "annotations": { - Type: "object", - AdditionalProperties: &apiext.JSONSchemaPropsOrBool{ - Schema: &apiext.JSONSchemaProps{ - Type: "string", - }, - }, - }, - "labels": { - Type: "object", - AdditionalProperties: &apiext.JSONSchemaPropsOrBool{ - Schema: &apiext.JSONSchemaProps{ - Type: "string", - }, - }, - }, - "finalizers": { - Type: "array", - Items: &apiext.JSONSchemaPropsOrArray{ - Schema: &apiext.JSONSchemaProps{ - Type: "string", - }, - }, - }, - }, - } - }, -} - -func boolPtr(b bool) *bool { - return &b -} - -// AddKnownTypes registers the packages overrides in KnownPackages with the given parser. -func AddKnownTypes(parser *Parser) { - // ensure everything is there before adding to PackageOverrides - // TODO(directxman12): this is a bit of a hack, maybe just use constructors? - parser.init() - for pkgName, override := range KnownPackages { - parser.PackageOverrides[pkgName] = override - } - // if we want to generate the embedded ObjectMeta in the CRD we need to add the ObjectMetaPackages - if parser.GenerateEmbeddedObjectMeta { - for pkgName, override := range ObjectMetaPackages { - parser.PackageOverrides[pkgName] = override - } - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/crd.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/crd.go deleted file mode 100644 index 5e99256c..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/crd.go +++ /dev/null @@ -1,347 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "fmt" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// CRDMarkers lists all markers that directly modify the CRD (not validation -// schemas). -var CRDMarkers = []*definitionWithHelp{ - // TODO(directxman12): more detailed help - must(markers.MakeDefinition("kubebuilder:subresource:status", markers.DescribesType, SubresourceStatus{})). - WithHelp(SubresourceStatus{}.Help()), - - must(markers.MakeDefinition("kubebuilder:subresource:scale", markers.DescribesType, SubresourceScale{})). - WithHelp(SubresourceScale{}.Help()), - - must(markers.MakeDefinition("kubebuilder:printcolumn", markers.DescribesType, PrintColumn{})). - WithHelp(PrintColumn{}.Help()), - - must(markers.MakeDefinition("kubebuilder:resource", markers.DescribesType, Resource{})). - WithHelp(Resource{}.Help()), - - must(markers.MakeDefinition("kubebuilder:storageversion", markers.DescribesType, StorageVersion{})). - WithHelp(StorageVersion{}.Help()), - - must(markers.MakeDefinition("kubebuilder:skipversion", markers.DescribesType, SkipVersion{})). - WithHelp(SkipVersion{}.Help()), - - must(markers.MakeDefinition("kubebuilder:unservedversion", markers.DescribesType, UnservedVersion{})). - WithHelp(UnservedVersion{}.Help()), - - must(markers.MakeDefinition("kubebuilder:deprecatedversion", markers.DescribesType, DeprecatedVersion{})). - WithHelp(DeprecatedVersion{}.Help()), -} - -// TODO: categories and singular used to be annotations types -// TODO: doc - -func init() { - AllDefinitions = append(AllDefinitions, CRDMarkers...) -} - -// +controllertools:marker:generateHelp:category=CRD - -// SubresourceStatus enables the "/status" subresource on a CRD. -type SubresourceStatus struct{} - -func (s SubresourceStatus) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error { - var subresources *apiext.CustomResourceSubresources - for i := range crd.Versions { - ver := &crd.Versions[i] - if ver.Name != version { - continue - } - if ver.Subresources == nil { - ver.Subresources = &apiext.CustomResourceSubresources{} - } - subresources = ver.Subresources - break - } - if subresources == nil { - return fmt.Errorf("status subresource applied to version %q not in CRD", version) - } - subresources.Status = &apiext.CustomResourceSubresourceStatus{} - return nil -} - -// +controllertools:marker:generateHelp:category=CRD - -// SubresourceScale enables the "/scale" subresource on a CRD. -type SubresourceScale struct { - // marker names are leftover legacy cruft - - // SpecPath specifies the jsonpath to the replicas field for the scale's spec. - SpecPath string `marker:"specpath"` - - // StatusPath specifies the jsonpath to the replicas field for the scale's status. - StatusPath string `marker:"statuspath"` - - // SelectorPath specifies the jsonpath to the pod label selector field for the scale's status. - // - // The selector field must be the *string* form (serialized form) of a selector. - // Setting a pod label selector is necessary for your type to work with the HorizontalPodAutoscaler. - SelectorPath *string `marker:"selectorpath"` -} - -func (s SubresourceScale) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error { - var subresources *apiext.CustomResourceSubresources - for i := range crd.Versions { - ver := &crd.Versions[i] - if ver.Name != version { - continue - } - if ver.Subresources == nil { - ver.Subresources = &apiext.CustomResourceSubresources{} - } - subresources = ver.Subresources - break - } - if subresources == nil { - return fmt.Errorf("scale subresource applied to version %q not in CRD", version) - } - subresources.Scale = &apiext.CustomResourceSubresourceScale{ - SpecReplicasPath: s.SpecPath, - StatusReplicasPath: s.StatusPath, - LabelSelectorPath: s.SelectorPath, - } - return nil -} - -// +controllertools:marker:generateHelp:category=CRD - -// StorageVersion marks this version as the "storage version" for the CRD for conversion. -// -// When conversion is enabled for a CRD (i.e. it's not a trivial-versions/single-version CRD), -// one version is set as the "storage version" to be stored in etcd. Attempting to store any -// other version will result in conversion to the storage version via a conversion webhook. -type StorageVersion struct{} - -func (s StorageVersion) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error { - if version == "" { - // single-version, do nothing - return nil - } - // multi-version - for i := range crd.Versions { - ver := &crd.Versions[i] - if ver.Name != version { - continue - } - ver.Storage = true - break - } - return nil -} - -// +controllertools:marker:generateHelp:category=CRD - -// SkipVersion removes the particular version of the CRD from the CRDs spec. -// -// This is useful if you need to skip generating and listing version entries -// for 'internal' resource versions, which typically exist if using the -// Kubernetes upstream conversion-gen tool. -type SkipVersion struct{} - -func (s SkipVersion) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error { - if version == "" { - // single-version, this is an invalid state - return fmt.Errorf("cannot skip a version if there is only a single version") - } - var versions []apiext.CustomResourceDefinitionVersion - // multi-version - for i := range crd.Versions { - ver := crd.Versions[i] - if ver.Name == version { - // skip the skipped version - continue - } - versions = append(versions, ver) - } - crd.Versions = versions - return nil -} - -// +controllertools:marker:generateHelp:category=CRD - -// PrintColumn adds a column to "kubectl get" output for this CRD. -type PrintColumn struct { - // Name specifies the name of the column. - Name string - - // Type indicates the type of the column. - // - // It may be any OpenAPI data type listed at - // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types. - Type string - - // JSONPath specifies the jsonpath expression used to extract the value of the column. - JSONPath string `marker:"JSONPath"` // legacy cruft - - // Description specifies the help/description for this column. - Description string `marker:",optional"` - - // Format specifies the format of the column. - // - // It may be any OpenAPI data format corresponding to the type, listed at - // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types. - Format string `marker:",optional"` - - // Priority indicates how important it is that this column be displayed. - // - // Lower priority (*higher* numbered) columns will be hidden if the terminal - // width is too small. - Priority int32 `marker:",optional"` -} - -func (s PrintColumn) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error { - var columns *[]apiext.CustomResourceColumnDefinition - for i := range crd.Versions { - ver := &crd.Versions[i] - if ver.Name != version { - continue - } - if ver.Subresources == nil { - ver.Subresources = &apiext.CustomResourceSubresources{} - } - columns = &ver.AdditionalPrinterColumns - break - } - if columns == nil { - return fmt.Errorf("printer columns applied to version %q not in CRD", version) - } - - *columns = append(*columns, apiext.CustomResourceColumnDefinition{ - Name: s.Name, - Type: s.Type, - JSONPath: s.JSONPath, - Description: s.Description, - Format: s.Format, - Priority: s.Priority, - }) - - return nil -} - -// +controllertools:marker:generateHelp:category=CRD - -// Resource configures naming and scope for a CRD. -type Resource struct { - // Path specifies the plural "resource" for this CRD. - // - // It generally corresponds to a plural, lower-cased version of the Kind. - // See https://book.kubebuilder.io/cronjob-tutorial/gvks.html. - Path string `marker:",optional"` - - // ShortName specifies aliases for this CRD. - // - // Short names are often used when people have work with your resource - // over and over again. For instance, "rs" for "replicaset" or - // "crd" for customresourcedefinition. - ShortName []string `marker:",optional"` - - // Categories specifies which group aliases this resource is part of. - // - // Group aliases are used to work with groups of resources at once. - // The most common one is "all" which covers about a third of the base - // resources in Kubernetes, and is generally used for "user-facing" resources. - Categories []string `marker:",optional"` - - // Singular overrides the singular form of your resource. - // - // The singular form is otherwise defaulted off the plural (path). - Singular string `marker:",optional"` - - // Scope overrides the scope of the CRD (Cluster vs Namespaced). - // - // Scope defaults to "Namespaced". Cluster-scoped ("Cluster") resources - // don't exist in namespaces. - Scope string `marker:",optional"` -} - -func (s Resource) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error { - if s.Path != "" { - crd.Names.Plural = s.Path - } - if s.Singular != "" { - crd.Names.Singular = s.Singular - } - crd.Names.ShortNames = s.ShortName - crd.Names.Categories = s.Categories - - switch s.Scope { - case "": - crd.Scope = apiext.NamespaceScoped - default: - crd.Scope = apiext.ResourceScope(s.Scope) - } - - return nil -} - -// +controllertools:marker:generateHelp:category=CRD - -// UnservedVersion does not serve this version. -// -// This is useful if you need to drop support for a version in favor of a newer version. -type UnservedVersion struct{} - -func (s UnservedVersion) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error { - for i := range crd.Versions { - ver := &crd.Versions[i] - if ver.Name != version { - continue - } - ver.Served = false - break - } - return nil -} - -// NB(directxman12): singular was historically distinct, so we keep it here for backwards compat - -// +controllertools:marker:generateHelp:category=CRD - -// DeprecatedVersion marks this version as deprecated. -type DeprecatedVersion struct { - // Warning message to be shown on the deprecated version - Warning *string `marker:",optional"` -} - -func (s DeprecatedVersion) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error { - if version == "" { - // single-version, do nothing - return nil - } - // multi-version - for i := range crd.Versions { - ver := &crd.Versions[i] - if ver.Name != version { - continue - } - ver.Deprecated = true - ver.DeprecationWarning = s.Warning - break - } - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/doc.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/doc.go deleted file mode 100644 index 995af44b..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/doc.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// Package markers defines markers for generating schema valiation -// and CRD structure. -// -// All markers related to CRD generation live in AllDefinitions. -// -// # Validation Markers -// -// Validation markers have values that implement ApplyToSchema -// (crd.SchemaMarker). Any marker implementing this will automatically -// be run after the rest of a given schema node has been generated. -// Markers that need to be run before any other markers can also -// implement ApplyFirst, but this is discouraged and may change -// in the future. -// -// All validation markers start with "+kubebuilder:validation", and -// have the same name as their type name. -// -// # CRD Markers -// -// Markers that modify anything in the CRD itself *except* for the schema -// implement ApplyToCRD (crd.CRDMarker). They are expected to detect whether -// they should apply themselves to a specific version in the CRD (as passed to -// them), or to the root-level CRD for legacy cases. They are applied *after* -// the rest of the CRD is computed. -// -// # Misc -// -// This package also defines the "+groupName" and "+versionName" package-level -// markers, for defining package<->group-version mappings. -package markers diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/package.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/package.go deleted file mode 100644 index cebe8fa4..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/package.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "sigs.k8s.io/controller-tools/pkg/markers" -) - -func init() { - AllDefinitions = append(AllDefinitions, - must(markers.MakeDefinition("groupName", markers.DescribesPackage, "")). - WithHelp(markers.SimpleHelp("CRD", "specifies the API group name for this package.")), - - must(markers.MakeDefinition("versionName", markers.DescribesPackage, "")). - WithHelp(markers.SimpleHelp("CRD", "overrides the API group version for this package (defaults to the package name).")), - - must(markers.MakeDefinition("kubebuilder:validation:Optional", markers.DescribesPackage, struct{}{})). - WithHelp(markers.SimpleHelp("CRD validation", "specifies that all fields in this package are optional by default.")), - - must(markers.MakeDefinition("kubebuilder:validation:Required", markers.DescribesPackage, struct{}{})). - WithHelp(markers.SimpleHelp("CRD validation", "specifies that all fields in this package are required by default.")), - - must(markers.MakeDefinition("kubebuilder:skip", markers.DescribesPackage, struct{}{})). - WithHelp(markers.SimpleHelp("CRD", "don't consider this package as an API version.")), - ) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/register.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/register.go deleted file mode 100644 index 0e7c4269..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/register.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "reflect" - - "sigs.k8s.io/controller-tools/pkg/markers" -) - -type definitionWithHelp struct { - *markers.Definition - Help *markers.DefinitionHelp -} - -func (d *definitionWithHelp) WithHelp(help *markers.DefinitionHelp) *definitionWithHelp { - d.Help = help - return d -} - -func (d *definitionWithHelp) Register(reg *markers.Registry) error { - if err := reg.Register(d.Definition); err != nil { - return err - } - if d.Help != nil { - reg.AddHelp(d.Definition, d.Help) - } - return nil -} - -func must(def *markers.Definition, err error) *definitionWithHelp { - return &definitionWithHelp{ - Definition: markers.Must(def, err), - } -} - -// AllDefinitions contains all marker definitions for this package. -var AllDefinitions []*definitionWithHelp - -type hasHelp interface { - Help() *markers.DefinitionHelp -} - -// mustMakeAllWithPrefix converts each object into a marker definition using -// the object's type's with the prefix to form the marker name. -func mustMakeAllWithPrefix(prefix string, target markers.TargetType, objs ...interface{}) []*definitionWithHelp { - defs := make([]*definitionWithHelp, len(objs)) - for i, obj := range objs { - name := prefix + ":" + reflect.TypeOf(obj).Name() - def, err := markers.MakeDefinition(name, target, obj) - if err != nil { - panic(err) - } - defs[i] = &definitionWithHelp{Definition: def, Help: obj.(hasHelp).Help()} - } - - return defs -} - -// Register registers all definitions for CRD generation to the given registry. -func Register(reg *markers.Registry) error { - for _, def := range AllDefinitions { - if err := def.Register(reg); err != nil { - return err - } - } - - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/topology.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/topology.go deleted file mode 100644 index a92995c8..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/topology.go +++ /dev/null @@ -1,163 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "fmt" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// TopologyMarkers specify topology markers (i.e. markers that describe if a -// list behaves as an associative-list or a set, if a map is atomic or not). -var TopologyMarkers = []*definitionWithHelp{ - must(markers.MakeDefinition("listMapKey", markers.DescribesField, ListMapKey(""))). - WithHelp(ListMapKey("").Help()), - must(markers.MakeDefinition("listMapKey", markers.DescribesType, ListMapKey(""))). - WithHelp(ListMapKey("").Help()), - must(markers.MakeDefinition("listType", markers.DescribesField, ListType(""))). - WithHelp(ListType("").Help()), - must(markers.MakeDefinition("listType", markers.DescribesType, ListType(""))). - WithHelp(ListType("").Help()), - must(markers.MakeDefinition("mapType", markers.DescribesField, MapType(""))). - WithHelp(MapType("").Help()), - must(markers.MakeDefinition("mapType", markers.DescribesType, MapType(""))). - WithHelp(MapType("").Help()), - must(markers.MakeDefinition("structType", markers.DescribesField, StructType(""))). - WithHelp(StructType("").Help()), - must(markers.MakeDefinition("structType", markers.DescribesType, StructType(""))). - WithHelp(StructType("").Help()), -} - -func init() { - AllDefinitions = append(AllDefinitions, TopologyMarkers...) -} - -// +controllertools:marker:generateHelp:category="CRD processing" - -// ListType specifies the type of data-structure that the list -// represents (map, set, atomic). -// -// Possible data-structure types of a list are: -// -// - "map": it needs to have a key field, which will be used to build an -// associative list. A typical example is a the pod container list, -// which is indexed by the container name. -// -// - "set": Fields need to be "scalar", and there can be only one -// occurrence of each. -// -// - "atomic": All the fields in the list are treated as a single value, -// are typically manipulated together by the same actor. -type ListType string - -// +controllertools:marker:generateHelp:category="CRD processing" - -// ListMapKey specifies the keys to map listTypes. -// -// It indicates the index of a map list. They can be repeated if multiple keys -// must be used. It can only be used when ListType is set to map, and the keys -// should be scalar types. -type ListMapKey string - -// +controllertools:marker:generateHelp:category="CRD processing" - -// MapType specifies the level of atomicity of the map; -// i.e. whether each item in the map is independent of the others, -// or all fields are treated as a single unit. -// -// Possible values: -// -// - "granular": items in the map are independent of each other, -// and can be manipulated by different actors. -// This is the default behavior. -// -// - "atomic": all fields are treated as one unit. -// Any changes have to replace the entire map. -type MapType string - -// +controllertools:marker:generateHelp:category="CRD processing" - -// StructType specifies the level of atomicity of the struct; -// i.e. whether each field in the struct is independent of the others, -// or all fields are treated as a single unit. -// -// Possible values: -// -// - "granular": fields in the struct are independent of each other, -// and can be manipulated by different actors. -// This is the default behavior. -// -// - "atomic": all fields are treated as one unit. -// Any changes have to replace the entire struct. -type StructType string - -func (l ListType) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "array" { - return fmt.Errorf("must apply listType to an array, found %s", schema.Type) - } - if l != "map" && l != "atomic" && l != "set" { - return fmt.Errorf(`ListType must be either "map", "set" or "atomic"`) - } - p := string(l) - schema.XListType = &p - return nil -} - -func (l ListType) ApplyFirst() {} - -func (l ListMapKey) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "array" { - return fmt.Errorf("must apply listMapKey to an array, found %s", schema.Type) - } - if schema.XListType == nil || *schema.XListType != "map" { - return fmt.Errorf("must apply listMapKey to an associative-list") - } - schema.XListMapKeys = append(schema.XListMapKeys, string(l)) - return nil -} - -func (m MapType) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "object" { - return fmt.Errorf("must apply mapType to an object") - } - - if m != "atomic" && m != "granular" { - return fmt.Errorf(`MapType must be either "granular" or "atomic"`) - } - - p := string(m) - schema.XMapType = &p - - return nil -} - -func (s StructType) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "object" && schema.Type != "" { - return fmt.Errorf("must apply structType to an object; either explicitly set or defaulted through an empty schema type") - } - - if s != "atomic" && s != "granular" { - return fmt.Errorf(`StructType must be either "granular" or "atomic"`) - } - - p := string(s) - schema.XMapType = &p - - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/validation.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/validation.go deleted file mode 100644 index 5d149618..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/validation.go +++ /dev/null @@ -1,495 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "encoding/json" - "fmt" - "math" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - - "sigs.k8s.io/controller-tools/pkg/markers" -) - -const ( - SchemalessName = "kubebuilder:validation:Schemaless" -) - -// ValidationMarkers lists all available markers that affect CRD schema generation, -// except for the few that don't make sense as type-level markers (see FieldOnlyMarkers). -// All markers start with `+kubebuilder:validation:`, and continue with their type name. -// A copy is produced of all markers that describes types as well, for making types -// reusable and writing complex validations on slice items. -var ValidationMarkers = mustMakeAllWithPrefix("kubebuilder:validation", markers.DescribesField, - - // numeric markers - - Maximum(0), - Minimum(0), - ExclusiveMaximum(false), - ExclusiveMinimum(false), - MultipleOf(0), - MinProperties(0), - MaxProperties(0), - - // string markers - - MaxLength(0), - MinLength(0), - Pattern(""), - - // slice markers - - MaxItems(0), - MinItems(0), - UniqueItems(false), - - // general markers - - Enum(nil), - Format(""), - Type(""), - XPreserveUnknownFields{}, - XEmbeddedResource{}, - XIntOrString{}, - XValidation{}, -) - -// FieldOnlyMarkers list field-specific validation markers (i.e. those markers that don't make -// sense on a type, and thus aren't in ValidationMarkers). -var FieldOnlyMarkers = []*definitionWithHelp{ - must(markers.MakeDefinition("kubebuilder:validation:Required", markers.DescribesField, struct{}{})). - WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is required, if fields are optional by default.")), - must(markers.MakeDefinition("kubebuilder:validation:Optional", markers.DescribesField, struct{}{})). - WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is optional, if fields are required by default.")), - must(markers.MakeDefinition("optional", markers.DescribesField, struct{}{})). - WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is optional, if fields are required by default.")), - - must(markers.MakeDefinition("nullable", markers.DescribesField, Nullable{})). - WithHelp(Nullable{}.Help()), - - must(markers.MakeAnyTypeDefinition("kubebuilder:default", markers.DescribesField, Default{})). - WithHelp(Default{}.Help()), - - must(markers.MakeDefinition("kubebuilder:validation:EmbeddedResource", markers.DescribesField, XEmbeddedResource{})). - WithHelp(XEmbeddedResource{}.Help()), - - must(markers.MakeDefinition(SchemalessName, markers.DescribesField, Schemaless{})). - WithHelp(Schemaless{}.Help()), -} - -// ValidationIshMarkers are field-and-type markers that don't fall under the -// :validation: prefix, and/or don't have a name that directly matches their -// type. -var ValidationIshMarkers = []*definitionWithHelp{ - must(markers.MakeDefinition("kubebuilder:pruning:PreserveUnknownFields", markers.DescribesField, XPreserveUnknownFields{})). - WithHelp(XPreserveUnknownFields{}.Help()), - must(markers.MakeDefinition("kubebuilder:pruning:PreserveUnknownFields", markers.DescribesType, XPreserveUnknownFields{})). - WithHelp(XPreserveUnknownFields{}.Help()), -} - -func init() { - AllDefinitions = append(AllDefinitions, ValidationMarkers...) - - for _, def := range ValidationMarkers { - newDef := *def.Definition - // copy both parts so we don't change the definition - typDef := definitionWithHelp{ - Definition: &newDef, - Help: def.Help, - } - typDef.Target = markers.DescribesType - AllDefinitions = append(AllDefinitions, &typDef) - } - - AllDefinitions = append(AllDefinitions, FieldOnlyMarkers...) - AllDefinitions = append(AllDefinitions, ValidationIshMarkers...) -} - -// +controllertools:marker:generateHelp:category="CRD validation" -// Maximum specifies the maximum numeric value that this field can have. -type Maximum float64 - -func (m Maximum) Value() float64 { - return float64(m) -} - -// +controllertools:marker:generateHelp:category="CRD validation" -// Minimum specifies the minimum numeric value that this field can have. Negative numbers are supported. -type Minimum float64 - -func (m Minimum) Value() float64 { - return float64(m) -} - -// +controllertools:marker:generateHelp:category="CRD validation" -// ExclusiveMinimum indicates that the minimum is "up to" but not including that value. -type ExclusiveMinimum bool - -// +controllertools:marker:generateHelp:category="CRD validation" -// ExclusiveMaximum indicates that the maximum is "up to" but not including that value. -type ExclusiveMaximum bool - -// +controllertools:marker:generateHelp:category="CRD validation" -// MultipleOf specifies that this field must have a numeric value that's a multiple of this one. -type MultipleOf float64 - -func (m MultipleOf) Value() float64 { - return float64(m) -} - -// +controllertools:marker:generateHelp:category="CRD validation" -// MaxLength specifies the maximum length for this string. -type MaxLength int - -// +controllertools:marker:generateHelp:category="CRD validation" -// MinLength specifies the minimum length for this string. -type MinLength int - -// +controllertools:marker:generateHelp:category="CRD validation" -// Pattern specifies that this string must match the given regular expression. -type Pattern string - -// +controllertools:marker:generateHelp:category="CRD validation" -// MaxItems specifies the maximum length for this list. -type MaxItems int - -// +controllertools:marker:generateHelp:category="CRD validation" -// MinItems specifies the minimun length for this list. -type MinItems int - -// +controllertools:marker:generateHelp:category="CRD validation" -// UniqueItems specifies that all items in this list must be unique. -type UniqueItems bool - -// +controllertools:marker:generateHelp:category="CRD validation" -// MaxProperties restricts the number of keys in an object -type MaxProperties int - -// +controllertools:marker:generateHelp:category="CRD validation" -// MinProperties restricts the number of keys in an object -type MinProperties int - -// +controllertools:marker:generateHelp:category="CRD validation" -// Enum specifies that this (scalar) field is restricted to the *exact* values specified here. -type Enum []interface{} - -// +controllertools:marker:generateHelp:category="CRD validation" -// Format specifies additional "complex" formatting for this field. -// -// For example, a date-time field would be marked as "type: string" and -// "format: date-time". -type Format string - -// +controllertools:marker:generateHelp:category="CRD validation" -// Type overrides the type for this field (which defaults to the equivalent of the Go type). -// -// This generally must be paired with custom serialization. For example, the -// metav1.Time field would be marked as "type: string" and "format: date-time". -type Type string - -// +controllertools:marker:generateHelp:category="CRD validation" -// Nullable marks this field as allowing the "null" value. -// -// This is often not necessary, but may be helpful with custom serialization. -type Nullable struct{} - -// +controllertools:marker:generateHelp:category="CRD validation" -// Default sets the default value for this field. -// -// A default value will be accepted as any value valid for the -// field. Formatting for common types include: boolean: `true`, string: -// `Cluster`, numerical: `1.24`, array: `{1,2}`, object: `{policy: -// "delete"}`). Defaults should be defined in pruned form, and only best-effort -// validation will be performed. Full validation of a default requires -// submission of the containing CRD to an apiserver. -type Default struct { - Value interface{} -} - -// +controllertools:marker:generateHelp:category="CRD processing" -// PreserveUnknownFields stops the apiserver from pruning fields which are not specified. -// -// By default the apiserver drops unknown fields from the request payload -// during the decoding step. This marker stops the API server from doing so. -// It affects fields recursively, but switches back to normal pruning behaviour -// if nested properties or additionalProperties are specified in the schema. -// This can either be true or undefined. False -// is forbidden. -// -// NB: The kubebuilder:validation:XPreserveUnknownFields variant is deprecated -// in favor of the kubebuilder:pruning:PreserveUnknownFields variant. They function -// identically. -type XPreserveUnknownFields struct{} - -// +controllertools:marker:generateHelp:category="CRD validation" -// EmbeddedResource marks a fields as an embedded resource with apiVersion, kind and metadata fields. -// -// An embedded resource is a value that has apiVersion, kind and metadata fields. -// They are validated implicitly according to the semantics of the currently -// running apiserver. It is not necessary to add any additional schema for these -// field, yet it is possible. This can be combined with PreserveUnknownFields. -type XEmbeddedResource struct{} - -// +controllertools:marker:generateHelp:category="CRD validation" -// IntOrString marks a fields as an IntOrString. -// -// This is required when applying patterns or other validations to an IntOrString -// field. Knwon information about the type is applied during the collapse phase -// and as such is not normally available during marker application. -type XIntOrString struct{} - -// +controllertools:marker:generateHelp:category="CRD validation" -// Schemaless marks a field as being a schemaless object. -// -// Schemaless objects are not introspected, so you must provide -// any type and validation information yourself. One use for this -// tag is for embedding fields that hold JSONSchema typed objects. -// Because this field disables all type checking, it is recommended -// to be used only as a last resort. -type Schemaless struct{} - -func hasNumericType(schema *apiext.JSONSchemaProps) bool { - return schema.Type == "integer" || schema.Type == "number" -} - -func isIntegral(value float64) bool { - return value == math.Trunc(value) && !math.IsNaN(value) && !math.IsInf(value, 0) -} - -// +controllertools:marker:generateHelp:category="CRD validation" -// XValidation marks a field as requiring a value for which a given -// expression evaluates to true. -// -// This marker may be repeated to specify multiple expressions, all of -// which must evaluate to true. -type XValidation struct { - Rule string - Message string `marker:",optional"` -} - -func (m Maximum) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if !hasNumericType(schema) { - return fmt.Errorf("must apply maximum to a numeric value, found %s", schema.Type) - } - - if schema.Type == "integer" && !isIntegral(m.Value()) { - return fmt.Errorf("cannot apply non-integral maximum validation (%v) to integer value", m.Value()) - } - - val := m.Value() - schema.Maximum = &val - return nil -} - -func (m Minimum) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if !hasNumericType(schema) { - return fmt.Errorf("must apply minimum to a numeric value, found %s", schema.Type) - } - - if schema.Type == "integer" && !isIntegral(m.Value()) { - return fmt.Errorf("cannot apply non-integral minimum validation (%v) to integer value", m.Value()) - } - - val := m.Value() - schema.Minimum = &val - return nil -} - -func (m ExclusiveMaximum) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if !hasNumericType(schema) { - return fmt.Errorf("must apply exclusivemaximum to a numeric value, found %s", schema.Type) - } - schema.ExclusiveMaximum = bool(m) - return nil -} - -func (m ExclusiveMinimum) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if !hasNumericType(schema) { - return fmt.Errorf("must apply exclusiveminimum to a numeric value, found %s", schema.Type) - } - - schema.ExclusiveMinimum = bool(m) - return nil -} - -func (m MultipleOf) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if !hasNumericType(schema) { - return fmt.Errorf("must apply multipleof to a numeric value, found %s", schema.Type) - } - - if schema.Type == "integer" && !isIntegral(m.Value()) { - return fmt.Errorf("cannot apply non-integral multipleof validation (%v) to integer value", m.Value()) - } - - val := m.Value() - schema.MultipleOf = &val - return nil -} - -func (m MaxLength) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "string" { - return fmt.Errorf("must apply maxlength to a string") - } - val := int64(m) - schema.MaxLength = &val - return nil -} - -func (m MinLength) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "string" { - return fmt.Errorf("must apply minlength to a string") - } - val := int64(m) - schema.MinLength = &val - return nil -} - -func (m Pattern) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - // Allow string types or IntOrStrings. An IntOrString will still - // apply the pattern validation when a string is detected, the pattern - // will not apply to ints though. - if schema.Type != "string" && !schema.XIntOrString { - return fmt.Errorf("must apply pattern to a `string` or `IntOrString`") - } - schema.Pattern = string(m) - return nil -} - -func (m MaxItems) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "array" { - return fmt.Errorf("must apply maxitem to an array") - } - val := int64(m) - schema.MaxItems = &val - return nil -} - -func (m MinItems) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "array" { - return fmt.Errorf("must apply minitems to an array") - } - val := int64(m) - schema.MinItems = &val - return nil -} - -func (m UniqueItems) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "array" { - return fmt.Errorf("must apply uniqueitems to an array") - } - schema.UniqueItems = bool(m) - return nil -} - -func (m MinProperties) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "object" { - return fmt.Errorf("must apply minproperties to an object") - } - val := int64(m) - schema.MinProperties = &val - return nil -} - -func (m MaxProperties) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - if schema.Type != "object" { - return fmt.Errorf("must apply maxproperties to an object") - } - val := int64(m) - schema.MaxProperties = &val - return nil -} - -func (m Enum) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - // TODO(directxman12): this is a bit hacky -- we should - // probably support AnyType better + using the schema structure - vals := make([]apiext.JSON, len(m)) - for i, val := range m { - // TODO(directxman12): check actual type with schema type? - // if we're expecting a string, marshal the string properly... - // NB(directxman12): we use json.Marshal to ensure we handle JSON escaping properly - valMarshalled, err := json.Marshal(val) - if err != nil { - return err - } - vals[i] = apiext.JSON{Raw: valMarshalled} - } - schema.Enum = vals - return nil -} - -func (m Format) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - schema.Format = string(m) - return nil -} - -// NB(directxman12): we "typecheck" on target schema properties here, -// which means the "Type" marker *must* be applied first. -// TODO(directxman12): find a less hacky way to do this -// (we could preserve ordering of markers, but that feels bad in its own right). - -func (m Type) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - schema.Type = string(m) - return nil -} - -func (m Type) ApplyFirst() {} - -func (m Nullable) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - schema.Nullable = true - return nil -} - -// Defaults are only valid CRDs created with the v1 API -func (m Default) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - marshalledDefault, err := json.Marshal(m.Value) - if err != nil { - return err - } - schema.Default = &apiext.JSON{Raw: marshalledDefault} - return nil -} - -func (m XPreserveUnknownFields) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - defTrue := true - schema.XPreserveUnknownFields = &defTrue - return nil -} - -func (m XEmbeddedResource) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - schema.XEmbeddedResource = true - return nil -} - -// NB(JoelSpeed): we use this property in other markers here, -// which means the "XIntOrString" marker *must* be applied first. - -func (m XIntOrString) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - schema.XIntOrString = true - return nil -} - -func (m XIntOrString) ApplyFirst() {} - -func (m XValidation) ApplyToSchema(schema *apiext.JSONSchemaProps) error { - schema.XValidations = append(schema.XValidations, apiext.ValidationRule{ - Rule: m.Rule, - Message: m.Message, - }) - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/zz_generated.markerhelp.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/zz_generated.markerhelp.go deleted file mode 100644 index a3c05474..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/zz_generated.markerhelp.go +++ /dev/null @@ -1,489 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright2019 The Kubernetes Authors. - -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. -*/ - -// Code generated by helpgen. DO NOT EDIT. - -package markers - -import ( - "sigs.k8s.io/controller-tools/pkg/markers" -) - -func (Default) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "sets the default value for this field. ", - Details: "A default value will be accepted as any value valid for the field. Formatting for common types include: boolean: `true`, string: `Cluster`, numerical: `1.24`, array: `{1,2}`, object: `{policy: \"delete\"}`). Defaults should be defined in pruned form, and only best-effort validation will be performed. Full validation of a default requires submission of the containing CRD to an apiserver.", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "Value": { - Summary: "", - Details: "", - }, - }, - } -} - -func (DeprecatedVersion) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD", - DetailedHelp: markers.DetailedHelp{ - Summary: "marks this version as deprecated.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "Warning": { - Summary: "message to be shown on the deprecated version", - Details: "", - }, - }, - } -} - -func (Enum) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies that this (scalar) field is restricted to the *exact* values specified here.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (ExclusiveMaximum) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "indicates that the maximum is \"up to\" but not including that value.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (ExclusiveMinimum) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "indicates that the minimum is \"up to\" but not including that value.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (Format) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies additional \"complex\" formatting for this field. ", - Details: "For example, a date-time field would be marked as \"type: string\" and \"format: date-time\".", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (ListMapKey) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD processing", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the keys to map listTypes. ", - Details: "It indicates the index of a map list. They can be repeated if multiple keys must be used. It can only be used when ListType is set to map, and the keys should be scalar types.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (ListType) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD processing", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the type of data-structure that the list represents (map, set, atomic). ", - Details: "Possible data-structure types of a list are: \n - \"map\": it needs to have a key field, which will be used to build an associative list. A typical example is a the pod container list, which is indexed by the container name. \n - \"set\": Fields need to be \"scalar\", and there can be only one occurrence of each. \n - \"atomic\": All the fields in the list are treated as a single value, are typically manipulated together by the same actor.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (MapType) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD processing", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the level of atomicity of the map; i.e. whether each item in the map is independent of the others, or all fields are treated as a single unit. ", - Details: "Possible values: \n - \"granular\": items in the map are independent of each other, and can be manipulated by different actors. This is the default behavior. \n - \"atomic\": all fields are treated as one unit. Any changes have to replace the entire map.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (MaxItems) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the maximum length for this list.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (MaxLength) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the maximum length for this string.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (MaxProperties) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "restricts the number of keys in an object", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (Maximum) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the maximum numeric value that this field can have.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (MinItems) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the minimun length for this list.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (MinLength) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the minimum length for this string.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (MinProperties) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "restricts the number of keys in an object", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (Minimum) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the minimum numeric value that this field can have. Negative numbers are supported.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (MultipleOf) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies that this field must have a numeric value that's a multiple of this one.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (Nullable) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "marks this field as allowing the \"null\" value. ", - Details: "This is often not necessary, but may be helpful with custom serialization.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (Pattern) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies that this string must match the given regular expression.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (PrintColumn) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD", - DetailedHelp: markers.DetailedHelp{ - Summary: "adds a column to \"kubectl get\" output for this CRD.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "Name": { - Summary: "specifies the name of the column.", - Details: "", - }, - "Type": { - Summary: "indicates the type of the column. ", - Details: "It may be any OpenAPI data type listed at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types.", - }, - "JSONPath": { - Summary: "specifies the jsonpath expression used to extract the value of the column.", - Details: "", - }, - "Description": { - Summary: "specifies the help/description for this column.", - Details: "", - }, - "Format": { - Summary: "specifies the format of the column. ", - Details: "It may be any OpenAPI data format corresponding to the type, listed at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types.", - }, - "Priority": { - Summary: "indicates how important it is that this column be displayed. ", - Details: "Lower priority (*higher* numbered) columns will be hidden if the terminal width is too small.", - }, - }, - } -} - -func (Resource) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD", - DetailedHelp: markers.DetailedHelp{ - Summary: "configures naming and scope for a CRD.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "Path": { - Summary: "specifies the plural \"resource\" for this CRD. ", - Details: "It generally corresponds to a plural, lower-cased version of the Kind. See https://book.kubebuilder.io/cronjob-tutorial/gvks.html.", - }, - "ShortName": { - Summary: "specifies aliases for this CRD. ", - Details: "Short names are often used when people have work with your resource over and over again. For instance, \"rs\" for \"replicaset\" or \"crd\" for customresourcedefinition.", - }, - "Categories": { - Summary: "specifies which group aliases this resource is part of. ", - Details: "Group aliases are used to work with groups of resources at once. The most common one is \"all\" which covers about a third of the base resources in Kubernetes, and is generally used for \"user-facing\" resources.", - }, - "Singular": { - Summary: "overrides the singular form of your resource. ", - Details: "The singular form is otherwise defaulted off the plural (path).", - }, - "Scope": { - Summary: "overrides the scope of the CRD (Cluster vs Namespaced). ", - Details: "Scope defaults to \"Namespaced\". Cluster-scoped (\"Cluster\") resources don't exist in namespaces.", - }, - }, - } -} - -func (Schemaless) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "marks a field as being a schemaless object. ", - Details: "Schemaless objects are not introspected, so you must provide any type and validation information yourself. One use for this tag is for embedding fields that hold JSONSchema typed objects. Because this field disables all type checking, it is recommended to be used only as a last resort.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (SkipVersion) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD", - DetailedHelp: markers.DetailedHelp{ - Summary: "removes the particular version of the CRD from the CRDs spec. ", - Details: "This is useful if you need to skip generating and listing version entries for 'internal' resource versions, which typically exist if using the Kubernetes upstream conversion-gen tool.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (StorageVersion) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD", - DetailedHelp: markers.DetailedHelp{ - Summary: "marks this version as the \"storage version\" for the CRD for conversion. ", - Details: "When conversion is enabled for a CRD (i.e. it's not a trivial-versions/single-version CRD), one version is set as the \"storage version\" to be stored in etcd. Attempting to store any other version will result in conversion to the storage version via a conversion webhook.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (StructType) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD processing", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies the level of atomicity of the struct; i.e. whether each field in the struct is independent of the others, or all fields are treated as a single unit. ", - Details: "Possible values: \n - \"granular\": fields in the struct are independent of each other, and can be manipulated by different actors. This is the default behavior. \n - \"atomic\": all fields are treated as one unit. Any changes have to replace the entire struct.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (SubresourceScale) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD", - DetailedHelp: markers.DetailedHelp{ - Summary: "enables the \"/scale\" subresource on a CRD.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "SpecPath": { - Summary: "specifies the jsonpath to the replicas field for the scale's spec.", - Details: "", - }, - "StatusPath": { - Summary: "specifies the jsonpath to the replicas field for the scale's status.", - Details: "", - }, - "SelectorPath": { - Summary: "specifies the jsonpath to the pod label selector field for the scale's status. ", - Details: "The selector field must be the *string* form (serialized form) of a selector. Setting a pod label selector is necessary for your type to work with the HorizontalPodAutoscaler.", - }, - }, - } -} - -func (SubresourceStatus) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD", - DetailedHelp: markers.DetailedHelp{ - Summary: "enables the \"/status\" subresource on a CRD.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (Type) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "overrides the type for this field (which defaults to the equivalent of the Go type). ", - Details: "This generally must be paired with custom serialization. For example, the metav1.Time field would be marked as \"type: string\" and \"format: date-time\".", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (UniqueItems) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies that all items in this list must be unique.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (UnservedVersion) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD", - DetailedHelp: markers.DetailedHelp{ - Summary: "does not serve this version. ", - Details: "This is useful if you need to drop support for a version in favor of a newer version.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (XEmbeddedResource) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "EmbeddedResource marks a fields as an embedded resource with apiVersion, kind and metadata fields. ", - Details: "An embedded resource is a value that has apiVersion, kind and metadata fields. They are validated implicitly according to the semantics of the currently running apiserver. It is not necessary to add any additional schema for these field, yet it is possible. This can be combined with PreserveUnknownFields.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (XIntOrString) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "IntOrString marks a fields as an IntOrString. ", - Details: "This is required when applying patterns or other validations to an IntOrString field. Knwon information about the type is applied during the collapse phase and as such is not normally available during marker application.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (XPreserveUnknownFields) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD processing", - DetailedHelp: markers.DetailedHelp{ - Summary: "PreserveUnknownFields stops the apiserver from pruning fields which are not specified. ", - Details: "By default the apiserver drops unknown fields from the request payload during the decoding step. This marker stops the API server from doing so. It affects fields recursively, but switches back to normal pruning behaviour if nested properties or additionalProperties are specified in the schema. This can either be true or undefined. False is forbidden. \n NB: The kubebuilder:validation:XPreserveUnknownFields variant is deprecated in favor of the kubebuilder:pruning:PreserveUnknownFields variant. They function identically.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (XValidation) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "CRD validation", - DetailedHelp: markers.DetailedHelp{ - Summary: "marks a field as requiring a value for which a given expression evaluates to true. ", - Details: "This marker may be repeated to specify multiple expressions, all of which must evaluate to true.", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "Rule": { - Summary: "", - Details: "", - }, - "Message": { - Summary: "", - Details: "", - }, - }, - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/parser.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/parser.go deleted file mode 100644 index 4c15de90..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/parser.go +++ /dev/null @@ -1,243 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package crd - -import ( - "fmt" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - - "sigs.k8s.io/controller-tools/pkg/loader" - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// TypeIdent represents some type in a Package. -type TypeIdent struct { - Package *loader.Package - Name string -} - -func (t TypeIdent) String() string { - return fmt.Sprintf("%q.%s", t.Package.ID, t.Name) -} - -// PackageOverride overrides the loading of some package -// (potentially setting custom schemata, etc). It must -// call AddPackage if it wants to continue with the default -// loading behavior. -type PackageOverride func(p *Parser, pkg *loader.Package) - -// Parser knows how to parse out CRD information and generate -// OpenAPI schemata from some collection of types and markers. -// Most methods on Parser cache their results automatically, -// and thus may be called any number of times. -type Parser struct { - Collector *markers.Collector - - // Types contains the known TypeInfo for this parser. - Types map[TypeIdent]*markers.TypeInfo - // Schemata contains the known OpenAPI JSONSchemata for this parser. - Schemata map[TypeIdent]apiext.JSONSchemaProps - // GroupVersions contains the known group-versions of each package in this parser. - GroupVersions map[*loader.Package]schema.GroupVersion - // CustomResourceDefinitions contains the known CustomResourceDefinitions for types in this parser. - CustomResourceDefinitions map[schema.GroupKind]apiext.CustomResourceDefinition - // FlattenedSchemata contains fully flattened schemata for use in building - // CustomResourceDefinition validation. Each schema has been flattened by the flattener, - // and then embedded fields have been flattened with FlattenEmbedded. - FlattenedSchemata map[TypeIdent]apiext.JSONSchemaProps - - // PackageOverrides indicates that the loading of any package with - // the given path should be handled by the given overrider. - PackageOverrides map[string]PackageOverride - - // checker stores persistent partial type-checking/reference-traversal information. - Checker *loader.TypeChecker - // packages marks packages as loaded, to avoid re-loading them. - packages map[*loader.Package]struct{} - - flattener *Flattener - - // AllowDangerousTypes controls the handling of non-recommended types such as float. If - // false (the default), these types are not supported. - // There is a continuum here: - // 1. Types that are always supported. - // 2. Types that are allowed by default, but not recommended (warning emitted when they are encountered as per PR #443). - // Possibly they are allowed by default for historical reasons and may even be "on their way out" at some point in the future. - // 3. Types that are not allowed by default, not recommended, but there are some legitimate reasons to need them in certain corner cases. - // Possibly these types should also emit a warning as per PR #443 even when they are "switched on" (an integration point between - // this feature and #443 if desired). This is the category that this flag deals with. - // 4. Types that are not allowed and will not be allowed, possibly because it just "doesn't make sense" or possibly - // because the implementation is too difficult/clunky to promote them to category 3. - // TODO: Should we have a more formal mechanism for putting "type patterns" in each of the above categories? - AllowDangerousTypes bool - - // IgnoreUnexportedFields specifies if unexported fields on the struct should be skipped - IgnoreUnexportedFields bool - - // GenerateEmbeddedObjectMeta specifies if any embedded ObjectMeta should be generated - GenerateEmbeddedObjectMeta bool -} - -func (p *Parser) init() { - if p.packages == nil { - p.packages = make(map[*loader.Package]struct{}) - } - if p.flattener == nil { - p.flattener = &Flattener{ - Parser: p, - } - } - if p.Schemata == nil { - p.Schemata = make(map[TypeIdent]apiext.JSONSchemaProps) - } - if p.Types == nil { - p.Types = make(map[TypeIdent]*markers.TypeInfo) - } - if p.PackageOverrides == nil { - p.PackageOverrides = make(map[string]PackageOverride) - } - if p.GroupVersions == nil { - p.GroupVersions = make(map[*loader.Package]schema.GroupVersion) - } - if p.CustomResourceDefinitions == nil { - p.CustomResourceDefinitions = make(map[schema.GroupKind]apiext.CustomResourceDefinition) - } - if p.FlattenedSchemata == nil { - p.FlattenedSchemata = make(map[TypeIdent]apiext.JSONSchemaProps) - } -} - -// indexTypes loads all types in the package into Types. -func (p *Parser) indexTypes(pkg *loader.Package) { - // autodetect - pkgMarkers, err := markers.PackageMarkers(p.Collector, pkg) - if err != nil { - pkg.AddError(err) - } else { - if skipPkg := pkgMarkers.Get("kubebuilder:skip"); skipPkg != nil { - return - } - if nameVal := pkgMarkers.Get("groupName"); nameVal != nil { - versionVal := pkg.Name // a reasonable guess - if versionMarker := pkgMarkers.Get("versionName"); versionMarker != nil { - versionVal = versionMarker.(string) - } - - p.GroupVersions[pkg] = schema.GroupVersion{ - Version: versionVal, - Group: nameVal.(string), - } - } - } - - if err := markers.EachType(p.Collector, pkg, func(info *markers.TypeInfo) { - ident := TypeIdent{ - Package: pkg, - Name: info.Name, - } - - p.Types[ident] = info - }); err != nil { - pkg.AddError(err) - } -} - -// LookupType fetches type info from Types. -func (p *Parser) LookupType(pkg *loader.Package, name string) *markers.TypeInfo { - return p.Types[TypeIdent{Package: pkg, Name: name}] -} - -// NeedSchemaFor indicates that a schema should be generated for the given type. -func (p *Parser) NeedSchemaFor(typ TypeIdent) { - p.init() - - p.NeedPackage(typ.Package) - if _, knownSchema := p.Schemata[typ]; knownSchema { - return - } - - info, knownInfo := p.Types[typ] - if !knownInfo { - typ.Package.AddError(fmt.Errorf("unknown type %s", typ)) - return - } - - // avoid tripping recursive schemata, like ManagedFields, by adding an empty WIP schema - p.Schemata[typ] = apiext.JSONSchemaProps{} - - schemaCtx := newSchemaContext(typ.Package, p, p.AllowDangerousTypes, p.IgnoreUnexportedFields) - ctxForInfo := schemaCtx.ForInfo(info) - - pkgMarkers, err := markers.PackageMarkers(p.Collector, typ.Package) - if err != nil { - typ.Package.AddError(err) - } - ctxForInfo.PackageMarkers = pkgMarkers - - schema := infoToSchema(ctxForInfo) - - p.Schemata[typ] = *schema -} - -func (p *Parser) NeedFlattenedSchemaFor(typ TypeIdent) { - p.init() - - if _, knownSchema := p.FlattenedSchemata[typ]; knownSchema { - return - } - - p.NeedSchemaFor(typ) - partialFlattened := p.flattener.FlattenType(typ) - fullyFlattened := FlattenEmbedded(partialFlattened, typ.Package) - - p.FlattenedSchemata[typ] = *fullyFlattened -} - -// NeedCRDFor lives off in spec.go - -// AddPackage indicates that types and type-checking information is needed -// for the the given package, *ignoring* overrides. -// Generally, consumers should call NeedPackage, while PackageOverrides should -// call AddPackage to continue with the normal loading procedure. -func (p *Parser) AddPackage(pkg *loader.Package) { - p.init() - if _, checked := p.packages[pkg]; checked { - return - } - p.indexTypes(pkg) - p.Checker.Check(pkg) - p.packages[pkg] = struct{}{} -} - -// NeedPackage indicates that types and type-checking information -// is needed for the given package. -func (p *Parser) NeedPackage(pkg *loader.Package) { - p.init() - if _, checked := p.packages[pkg]; checked { - return - } - // overrides are going to be written without vendor. This is why we index by the actual - // object when we can. - if override, overridden := p.PackageOverrides[loader.NonVendorPath(pkg.PkgPath)]; overridden { - override(p, pkg) - p.packages[pkg] = struct{}{} - return - } - p.AddPackage(pkg) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/schema.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/schema.go deleted file mode 100644 index e76d3ea8..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/schema.go +++ /dev/null @@ -1,464 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package crd - -import ( - "errors" - "fmt" - "go/ast" - "go/token" - "go/types" - "strings" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers" - - "sigs.k8s.io/controller-tools/pkg/loader" - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// Schema flattening is done in a recursive mapping method. -// Start reading at infoToSchema. - -const ( - // defPrefix is the prefix used to link to definitions in the OpenAPI schema. - defPrefix = "#/definitions/" -) - -// byteType is the types.Type for byte (see the types documention -// for why we need to look this up in the Universe), saved -// for quick comparison. -var byteType = types.Universe.Lookup("byte").Type() - -// SchemaMarker is any marker that needs to modify the schema of the underlying type or field. -type SchemaMarker interface { - // ApplyToSchema is called after the rest of the schema for a given type - // or field is generated, to modify the schema appropriately. - ApplyToSchema(*apiext.JSONSchemaProps) error -} - -// applyFirstMarker is applied before any other markers. It's a bit of a hack. -type applyFirstMarker interface { - ApplyFirst() -} - -// schemaRequester knows how to marker that another schema (e.g. via an external reference) is necessary. -type schemaRequester interface { - NeedSchemaFor(typ TypeIdent) -} - -// schemaContext stores and provides information across a hierarchy of schema generation. -type schemaContext struct { - pkg *loader.Package - info *markers.TypeInfo - - schemaRequester schemaRequester - PackageMarkers markers.MarkerValues - - allowDangerousTypes bool - ignoreUnexportedFields bool -} - -// newSchemaContext constructs a new schemaContext for the given package and schema requester. -// It must have type info added before use via ForInfo. -func newSchemaContext(pkg *loader.Package, req schemaRequester, allowDangerousTypes, ignoreUnexportedFields bool) *schemaContext { - pkg.NeedTypesInfo() - return &schemaContext{ - pkg: pkg, - schemaRequester: req, - allowDangerousTypes: allowDangerousTypes, - ignoreUnexportedFields: ignoreUnexportedFields, - } -} - -// ForInfo produces a new schemaContext with containing the same information -// as this one, except with the given type information. -func (c *schemaContext) ForInfo(info *markers.TypeInfo) *schemaContext { - return &schemaContext{ - pkg: c.pkg, - info: info, - schemaRequester: c.schemaRequester, - allowDangerousTypes: c.allowDangerousTypes, - ignoreUnexportedFields: c.ignoreUnexportedFields, - } -} - -// requestSchema asks for the schema for a type in the package with the -// given import path. -func (c *schemaContext) requestSchema(pkgPath, typeName string) { - pkg := c.pkg - if pkgPath != "" { - pkg = c.pkg.Imports()[pkgPath] - } - c.schemaRequester.NeedSchemaFor(TypeIdent{ - Package: pkg, - Name: typeName, - }) -} - -// infoToSchema creates a schema for the type in the given set of type information. -func infoToSchema(ctx *schemaContext) *apiext.JSONSchemaProps { - // If the obj implements a JSON marshaler and has a marker, use the markers value and do not traverse as - // the marshaler could be doing anything. If there is no marker, fall back to traversing. - if obj := ctx.pkg.Types.Scope().Lookup(ctx.info.Name); obj != nil && implementsJSONMarshaler(obj.Type()) { - schema := &apiext.JSONSchemaProps{} - applyMarkers(ctx, ctx.info.Markers, schema, ctx.info.RawSpec.Type) - if schema.Type != "" { - return schema - } - } - return typeToSchema(ctx, ctx.info.RawSpec.Type) -} - -// applyMarkers applies schema markers to the given schema, respecting "apply first" markers. -func applyMarkers(ctx *schemaContext, markerSet markers.MarkerValues, props *apiext.JSONSchemaProps, node ast.Node) { - // apply "apply first" markers first... - for _, markerValues := range markerSet { - for _, markerValue := range markerValues { - if _, isApplyFirst := markerValue.(applyFirstMarker); !isApplyFirst { - continue - } - - schemaMarker, isSchemaMarker := markerValue.(SchemaMarker) - if !isSchemaMarker { - continue - } - - if err := schemaMarker.ApplyToSchema(props); err != nil { - ctx.pkg.AddError(loader.ErrFromNode(err /* an okay guess */, node)) - } - } - } - - // ...then the rest of the markers - for _, markerValues := range markerSet { - for _, markerValue := range markerValues { - if _, isApplyFirst := markerValue.(applyFirstMarker); isApplyFirst { - // skip apply-first markers, which were already applied - continue - } - - schemaMarker, isSchemaMarker := markerValue.(SchemaMarker) - if !isSchemaMarker { - continue - } - if err := schemaMarker.ApplyToSchema(props); err != nil { - ctx.pkg.AddError(loader.ErrFromNode(err /* an okay guess */, node)) - } - } - } -} - -// typeToSchema creates a schema for the given AST type. -func typeToSchema(ctx *schemaContext, rawType ast.Expr) *apiext.JSONSchemaProps { - var props *apiext.JSONSchemaProps - switch expr := rawType.(type) { - case *ast.Ident: - props = localNamedToSchema(ctx, expr) - case *ast.SelectorExpr: - props = namedToSchema(ctx, expr) - case *ast.ArrayType: - props = arrayToSchema(ctx, expr) - case *ast.MapType: - props = mapToSchema(ctx, expr) - case *ast.StarExpr: - props = typeToSchema(ctx, expr.X) - case *ast.StructType: - props = structToSchema(ctx, expr) - default: - ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("unsupported AST kind %T", expr), rawType)) - // NB(directxman12): we explicitly don't handle interfaces - return &apiext.JSONSchemaProps{} - } - - props.Description = ctx.info.Doc - - applyMarkers(ctx, ctx.info.Markers, props, rawType) - - return props -} - -// qualifiedName constructs a JSONSchema-safe qualified name for a type -// (`` or `~0`, where `` -// is the package path with `/` replaced by `~1`, according to JSONPointer -// escapes). -func qualifiedName(pkgName, typeName string) string { - if pkgName != "" { - return strings.Replace(pkgName, "/", "~1", -1) + "~0" + typeName - } - return typeName -} - -// TypeRefLink creates a definition link for the given type and package. -func TypeRefLink(pkgName, typeName string) string { - return defPrefix + qualifiedName(pkgName, typeName) -} - -// localNamedToSchema creates a schema (ref) for a *potentially* local type reference -// (could be external from a dot-import). -func localNamedToSchema(ctx *schemaContext, ident *ast.Ident) *apiext.JSONSchemaProps { - typeInfo := ctx.pkg.TypesInfo.TypeOf(ident) - if typeInfo == types.Typ[types.Invalid] { - ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("unknown type %s", ident.Name), ident)) - return &apiext.JSONSchemaProps{} - } - if basicInfo, isBasic := typeInfo.(*types.Basic); isBasic { - typ, fmt, err := builtinToType(basicInfo, ctx.allowDangerousTypes) - if err != nil { - ctx.pkg.AddError(loader.ErrFromNode(err, ident)) - } - return &apiext.JSONSchemaProps{ - Type: typ, - Format: fmt, - } - } - // NB(directxman12): if there are dot imports, this might be an external reference, - // so use typechecking info to get the actual object - typeNameInfo := typeInfo.(*types.Named).Obj() - pkg := typeNameInfo.Pkg() - pkgPath := loader.NonVendorPath(pkg.Path()) - if pkg == ctx.pkg.Types { - pkgPath = "" - } - ctx.requestSchema(pkgPath, typeNameInfo.Name()) - link := TypeRefLink(pkgPath, typeNameInfo.Name()) - return &apiext.JSONSchemaProps{ - Ref: &link, - } -} - -// namedSchema creates a schema (ref) for an explicitly external type reference. -func namedToSchema(ctx *schemaContext, named *ast.SelectorExpr) *apiext.JSONSchemaProps { - typeInfoRaw := ctx.pkg.TypesInfo.TypeOf(named) - if typeInfoRaw == types.Typ[types.Invalid] { - ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("unknown type %v.%s", named.X, named.Sel.Name), named)) - return &apiext.JSONSchemaProps{} - } - typeInfo := typeInfoRaw.(*types.Named) - typeNameInfo := typeInfo.Obj() - nonVendorPath := loader.NonVendorPath(typeNameInfo.Pkg().Path()) - ctx.requestSchema(nonVendorPath, typeNameInfo.Name()) - link := TypeRefLink(nonVendorPath, typeNameInfo.Name()) - return &apiext.JSONSchemaProps{ - Ref: &link, - } - // NB(directxman12): we special-case things like resource.Quantity during the "collapse" phase. -} - -// arrayToSchema creates a schema for the items of the given array, dealing appropriately -// with the special `[]byte` type (according to OpenAPI standards). -func arrayToSchema(ctx *schemaContext, array *ast.ArrayType) *apiext.JSONSchemaProps { - eltType := ctx.pkg.TypesInfo.TypeOf(array.Elt) - if eltType == byteType && array.Len == nil { - // byte slices are represented as base64-encoded strings - // (the format is defined in OpenAPI v3, but not JSON Schema) - return &apiext.JSONSchemaProps{ - Type: "string", - Format: "byte", - } - } - // TODO(directxman12): backwards-compat would require access to markers from base info - items := typeToSchema(ctx.ForInfo(&markers.TypeInfo{}), array.Elt) - - return &apiext.JSONSchemaProps{ - Type: "array", - Items: &apiext.JSONSchemaPropsOrArray{Schema: items}, - } -} - -// mapToSchema creates a schema for items of the given map. Key types must eventually resolve -// to string (other types aren't allowed by JSON, and thus the kubernetes API standards). -func mapToSchema(ctx *schemaContext, mapType *ast.MapType) *apiext.JSONSchemaProps { - keyInfo := ctx.pkg.TypesInfo.TypeOf(mapType.Key) - // check that we've got a type that actually corresponds to a string - for keyInfo != nil { - switch typedKey := keyInfo.(type) { - case *types.Basic: - if typedKey.Info()&types.IsString == 0 { - ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("map keys must be strings, not %s", keyInfo.String()), mapType.Key)) - return &apiext.JSONSchemaProps{} - } - keyInfo = nil // stop iterating - case *types.Named: - keyInfo = typedKey.Underlying() - default: - ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("map keys must be strings, not %s", keyInfo.String()), mapType.Key)) - return &apiext.JSONSchemaProps{} - } - } - - // TODO(directxman12): backwards-compat would require access to markers from base info - var valSchema *apiext.JSONSchemaProps - switch val := mapType.Value.(type) { - case *ast.Ident: - valSchema = localNamedToSchema(ctx.ForInfo(&markers.TypeInfo{}), val) - case *ast.SelectorExpr: - valSchema = namedToSchema(ctx.ForInfo(&markers.TypeInfo{}), val) - case *ast.ArrayType: - valSchema = arrayToSchema(ctx.ForInfo(&markers.TypeInfo{}), val) - case *ast.StarExpr: - valSchema = typeToSchema(ctx.ForInfo(&markers.TypeInfo{}), val) - case *ast.MapType: - valSchema = typeToSchema(ctx.ForInfo(&markers.TypeInfo{}), val) - default: - ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("not a supported map value type: %T", mapType.Value), mapType.Value)) - return &apiext.JSONSchemaProps{} - } - - return &apiext.JSONSchemaProps{ - Type: "object", - AdditionalProperties: &apiext.JSONSchemaPropsOrBool{ - Schema: valSchema, - Allows: true, /* set automatically by serialization, but useful for testing */ - }, - } -} - -// structToSchema creates a schema for the given struct. Embedded fields are placed in AllOf, -// and can be flattened later with a Flattener. -func structToSchema(ctx *schemaContext, structType *ast.StructType) *apiext.JSONSchemaProps { - props := &apiext.JSONSchemaProps{ - Type: "object", - Properties: make(map[string]apiext.JSONSchemaProps), - } - - if ctx.info.RawSpec.Type != structType { - ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("encountered non-top-level struct (possibly embedded), those aren't allowed"), structType)) - return props - } - - for _, field := range ctx.info.Fields { - // Skip if the field is not an inline field, ignoreUnexportedFields is true, and the field is not exported - if field.Name != "" && ctx.ignoreUnexportedFields && !ast.IsExported(field.Name) { - continue - } - - jsonTag, hasTag := field.Tag.Lookup("json") - if !hasTag { - // if the field doesn't have a JSON tag, it doesn't belong in output (and shouldn't exist in a serialized type) - ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("encountered struct field %q without JSON tag in type %q", field.Name, ctx.info.Name), field.RawField)) - continue - } - jsonOpts := strings.Split(jsonTag, ",") - if len(jsonOpts) == 1 && jsonOpts[0] == "-" { - // skipped fields have the tag "-" (note that "-," means the field is named "-") - continue - } - - inline := false - omitEmpty := false - for _, opt := range jsonOpts[1:] { - switch opt { - case "inline": - inline = true - case "omitempty": - omitEmpty = true - } - } - fieldName := jsonOpts[0] - inline = inline || fieldName == "" // anonymous fields are inline fields in YAML/JSON - - // if no default required mode is set, default to required - defaultMode := "required" - if ctx.PackageMarkers.Get("kubebuilder:validation:Optional") != nil { - defaultMode = "optional" - } - - switch defaultMode { - // if this package isn't set to optional default... - case "required": - // ...everything that's not inline, omitempty, or explicitly optional is required - if !inline && !omitEmpty && field.Markers.Get("kubebuilder:validation:Optional") == nil && field.Markers.Get("optional") == nil { - props.Required = append(props.Required, fieldName) - } - - // if this package isn't set to required default... - case "optional": - // ...everything that isn't explicitly required is optional - if field.Markers.Get("kubebuilder:validation:Required") != nil { - props.Required = append(props.Required, fieldName) - } - } - - var propSchema *apiext.JSONSchemaProps - if field.Markers.Get(crdmarkers.SchemalessName) != nil { - propSchema = &apiext.JSONSchemaProps{} - } else { - propSchema = typeToSchema(ctx.ForInfo(&markers.TypeInfo{}), field.RawField.Type) - } - propSchema.Description = field.Doc - - applyMarkers(ctx, field.Markers, propSchema, field.RawField) - - if inline { - props.AllOf = append(props.AllOf, *propSchema) - continue - } - - props.Properties[fieldName] = *propSchema - } - - return props -} - -// builtinToType converts builtin basic types to their equivalent JSON schema form. -// It *only* handles types allowed by the kubernetes API standards. Floats are not -// allowed unless allowDangerousTypes is true -func builtinToType(basic *types.Basic, allowDangerousTypes bool) (typ string, format string, err error) { - // NB(directxman12): formats from OpenAPI v3 are slightly different than those defined - // in JSONSchema. This'll use the OpenAPI v3 ones, since they're useful for bounding our - // non-string types. - basicInfo := basic.Info() - switch { - case basicInfo&types.IsBoolean != 0: - typ = "boolean" - case basicInfo&types.IsString != 0: - typ = "string" - case basicInfo&types.IsInteger != 0: - typ = "integer" - case basicInfo&types.IsFloat != 0: - if allowDangerousTypes { - typ = "number" - } else { - return "", "", errors.New("found float, the usage of which is highly discouraged, as support for them varies across languages. Please consider serializing your float as string instead. If you are really sure you want to use them, re-run with crd:allowDangerousTypes=true") - } - default: - return "", "", fmt.Errorf("unsupported type %q", basic.String()) - } - - switch basic.Kind() { - case types.Int32, types.Uint32: - format = "int32" - case types.Int64, types.Uint64: - format = "int64" - } - - return typ, format, nil -} - -// Open coded go/types representation of encoding/json.Marshaller -var jsonMarshaler = types.NewInterfaceType([]*types.Func{ - types.NewFunc(token.NoPos, nil, "MarshalJSON", - types.NewSignature(nil, nil, - types.NewTuple( - types.NewVar(token.NoPos, nil, "", types.NewSlice(types.Universe.Lookup("byte").Type())), - types.NewVar(token.NoPos, nil, "", types.Universe.Lookup("error").Type())), false)), -}, nil).Complete() - -func implementsJSONMarshaler(typ types.Type) bool { - return types.Implements(typ, jsonMarshaler) || types.Implements(types.NewPointer(typ), jsonMarshaler) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/schema_visitor.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/schema_visitor.go deleted file mode 100644 index 2604d739..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/schema_visitor.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package crd - -import ( - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" -) - -// SchemaVisitor walks the nodes of a schema. -type SchemaVisitor interface { - // Visit is called for each schema node. If it returns a visitor, - // the visitor will be called on each direct child node, and then - // this visitor will be called again with `nil` to indicate that - // all children have been visited. If a nil visitor is returned, - // children are not visited. - // - // It is *NOT* safe to save references to the given schema. - // Make deepcopies if you need to keep things around beyond - // the lifetime of the call. - Visit(schema *apiext.JSONSchemaProps) SchemaVisitor -} - -// EditSchema walks the given schema using the given visitor. Actual -// pointers to each schema node are passed to the visitor, so any changes -// made by the visitor will be reflected to the passed-in schema. -func EditSchema(schema *apiext.JSONSchemaProps, visitor SchemaVisitor) { - walker := schemaWalker{visitor: visitor} - walker.walkSchema(schema) -} - -// schemaWalker knows how to walk the schema, saving modifications -// made by the given visitor. -type schemaWalker struct { - visitor SchemaVisitor -} - -// walkSchema walks the given schema, saving modifications made by the visitor -// (this is as simple as passing a pointer in most cases, but special care -// needs to be taken to persist with maps). It also visits referenced -// schemata, dealing with circular references appropriately. The returned -// visitor will be used to visit all "children" of the current schema, followed -// by a nil schema with the returned visitor to mark completion. If a nil visitor -// is returned, traversal will no continue into the children of the current schema. -func (w schemaWalker) walkSchema(schema *apiext.JSONSchemaProps) { - // Walk a potential chain of schema references, keeping track of seen - // references to avoid circular references - subVisitor := w.visitor - seenRefs := map[string]bool{} - if schema.Ref != nil { - seenRefs[*schema.Ref] = true - } - for { - subVisitor = subVisitor.Visit(schema) - if subVisitor == nil { - return - } - // mark completion of the visitor - defer subVisitor.Visit(nil) - - // Break if schema is not a reference or a cycle is detected - if schema.Ref == nil || len(*schema.Ref) == 0 || seenRefs[*schema.Ref] { - break - } - seenRefs[*schema.Ref] = true - } - - // walk sub-schemata - subWalker := schemaWalker{visitor: subVisitor} - if schema.Items != nil { - subWalker.walkPtr(schema.Items.Schema) - subWalker.walkSlice(schema.Items.JSONSchemas) - } - subWalker.walkSlice(schema.AllOf) - subWalker.walkSlice(schema.OneOf) - subWalker.walkSlice(schema.AnyOf) - subWalker.walkPtr(schema.Not) - subWalker.walkMap(schema.Properties) - if schema.AdditionalProperties != nil { - subWalker.walkPtr(schema.AdditionalProperties.Schema) - } - subWalker.walkMap(schema.PatternProperties) - for name, dep := range schema.Dependencies { - subWalker.walkPtr(dep.Schema) - schema.Dependencies[name] = dep - } - if schema.AdditionalItems != nil { - subWalker.walkPtr(schema.AdditionalItems.Schema) - } - subWalker.walkMap(schema.Definitions) -} - -// walkMap walks over values of the given map, saving changes to them. -func (w schemaWalker) walkMap(defs map[string]apiext.JSONSchemaProps) { - for name, def := range defs { - // this is iter var reference is because we immediately preseve it below - //nolint:gosec - w.walkSchema(&def) - // make sure the edits actually go through since we can't - // take a reference to the value in the map - defs[name] = def - } -} - -// walkSlice walks over items of the given slice. -func (w schemaWalker) walkSlice(defs []apiext.JSONSchemaProps) { - for i := range defs { - w.walkSchema(&defs[i]) - } -} - -// walkPtr walks over the contents of the given pointer, if it's not nil. -func (w schemaWalker) walkPtr(def *apiext.JSONSchemaProps) { - if def == nil { - return - } - w.walkSchema(def) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/spec.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/spec.go deleted file mode 100644 index d7c1e4c2..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/spec.go +++ /dev/null @@ -1,168 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ -package crd - -import ( - "fmt" - "sort" - "strings" - - "github.com/gobuffalo/flect" - - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - - "sigs.k8s.io/controller-tools/pkg/loader" -) - -// SpecMarker is a marker that knows how to apply itself to a particular -// version in a CRD. -type SpecMarker interface { - // ApplyToCRD applies this marker to the given CRD, in the given version - // within that CRD. It's called after everything else in the CRD is populated. - ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error -} - -// NeedCRDFor requests the full CRD for the given group-kind. It requires -// that the packages containing the Go structs for that CRD have already -// been loaded with NeedPackage. -func (p *Parser) NeedCRDFor(groupKind schema.GroupKind, maxDescLen *int) { - p.init() - - if _, exists := p.CustomResourceDefinitions[groupKind]; exists { - return - } - - var packages []*loader.Package - for pkg, gv := range p.GroupVersions { - if gv.Group != groupKind.Group { - continue - } - packages = append(packages, pkg) - } - - defaultPlural := strings.ToLower(flect.Pluralize(groupKind.Kind)) - crd := apiext.CustomResourceDefinition{ - TypeMeta: metav1.TypeMeta{ - APIVersion: apiext.SchemeGroupVersion.String(), - Kind: "CustomResourceDefinition", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: defaultPlural + "." + groupKind.Group, - }, - Spec: apiext.CustomResourceDefinitionSpec{ - Group: groupKind.Group, - Names: apiext.CustomResourceDefinitionNames{ - Kind: groupKind.Kind, - ListKind: groupKind.Kind + "List", - Plural: defaultPlural, - Singular: strings.ToLower(groupKind.Kind), - }, - Scope: apiext.NamespaceScoped, - }, - } - - for _, pkg := range packages { - typeIdent := TypeIdent{Package: pkg, Name: groupKind.Kind} - typeInfo := p.Types[typeIdent] - if typeInfo == nil { - continue - } - p.NeedFlattenedSchemaFor(typeIdent) - fullSchema := p.FlattenedSchemata[typeIdent] - fullSchema = *fullSchema.DeepCopy() // don't mutate the cache (we might be truncating description, etc) - if maxDescLen != nil { - TruncateDescription(&fullSchema, *maxDescLen) - } - ver := apiext.CustomResourceDefinitionVersion{ - Name: p.GroupVersions[pkg].Version, - Served: true, - Schema: &apiext.CustomResourceValidation{ - OpenAPIV3Schema: &fullSchema, // fine to take a reference since we deepcopy above - }, - } - crd.Spec.Versions = append(crd.Spec.Versions, ver) - } - - // markers are applied *after* initial generation of objects - for _, pkg := range packages { - typeIdent := TypeIdent{Package: pkg, Name: groupKind.Kind} - typeInfo := p.Types[typeIdent] - if typeInfo == nil { - continue - } - ver := p.GroupVersions[pkg].Version - - for _, markerVals := range typeInfo.Markers { - for _, val := range markerVals { - crdMarker, isCrdMarker := val.(SpecMarker) - if !isCrdMarker { - continue - } - if err := crdMarker.ApplyToCRD(&crd.Spec, ver); err != nil { - pkg.AddError(loader.ErrFromNode(err /* an okay guess */, typeInfo.RawSpec)) - } - } - } - } - - // fix the name if the plural was changed (this is the form the name *has* to take, so no harm in changing it). - crd.Name = crd.Spec.Names.Plural + "." + groupKind.Group - - // nothing to actually write - if len(crd.Spec.Versions) == 0 { - return - } - - // it is necessary to make sure the order of CRD versions in crd.Spec.Versions is stable and explicitly set crd.Spec.Version. - // Otherwise, crd.Spec.Version may point to different CRD versions across different runs. - sort.Slice(crd.Spec.Versions, func(i, j int) bool { return crd.Spec.Versions[i].Name < crd.Spec.Versions[j].Name }) - - // make sure we have *a* storage version - // (default it if we only have one, otherwise, bail) - if len(crd.Spec.Versions) == 1 { - crd.Spec.Versions[0].Storage = true - } - - hasStorage := false - for _, ver := range crd.Spec.Versions { - if ver.Storage { - hasStorage = true - break - } - } - if !hasStorage { - // just add the error to the first relevant package for this CRD, - // since there's no specific error location - packages[0].AddError(fmt.Errorf("CRD for %s has no storage version", groupKind)) - } - - served := false - for _, ver := range crd.Spec.Versions { - if ver.Served { - served = true - break - } - } - if !served { - // just add the error to the first relevant package for this CRD, - // since there's no specific error location - packages[0].AddError(fmt.Errorf("CRD for %s with version(s) %v does not serve any version", groupKind, crd.Spec.Versions)) - } - - p.CustomResourceDefinitions[groupKind] = crd -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/zz_generated.markerhelp.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/zz_generated.markerhelp.go deleted file mode 100644 index fee8de4b..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/zz_generated.markerhelp.go +++ /dev/null @@ -1,58 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright2019 The Kubernetes Authors. - -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. -*/ - -// Code generated by helpgen. DO NOT EDIT. - -package crd - -import ( - "sigs.k8s.io/controller-tools/pkg/markers" -) - -func (Generator) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "generates CustomResourceDefinition objects.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "IgnoreUnexportedFields": { - Summary: "indicates that we should skip unexported fields. ", - Details: "Left unspecified, the default is false.", - }, - "AllowDangerousTypes": { - Summary: "allows types which are usually omitted from CRD generation because they are not recommended. ", - Details: "Currently the following additional types are allowed when this is true: float32 float64 \n Left unspecified, the default is false", - }, - "MaxDescLen": { - Summary: "specifies the maximum description length for fields in CRD's OpenAPI schema. ", - Details: "0 indicates drop the description for all fields completely. n indicates limit the description to at most n characters and truncate the description to closest sentence boundary if it exceeds n characters.", - }, - "CRDVersions": { - Summary: "specifies the target API versions of the CRD type itself to generate. Defaults to v1. ", - Details: "Currently, the only supported value is v1. \n The first version listed will be assumed to be the \"default\" version and will not get a version suffix in the output filename. \n You'll need to use \"v1\" to get support for features like defaulting, along with an API server that supports it (Kubernetes 1.16+).", - }, - "GenerateEmbeddedObjectMeta": { - Summary: "specifies if any embedded ObjectMeta in the CRD should be generated", - Details: "", - }, - }, - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/gen.go b/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/gen.go deleted file mode 100644 index 7e674a80..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/gen.go +++ /dev/null @@ -1,305 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package deepcopy - -import ( - "bytes" - "fmt" - "go/ast" - "go/format" - "io" - "sort" - "strings" - - "sigs.k8s.io/controller-tools/pkg/genall" - "sigs.k8s.io/controller-tools/pkg/loader" - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// NB(directxman12): markers.LoadRoots ignores autogenerated code via a build tag -// so any time we check for existing deepcopy functions, we only seen manually written ones. - -const ( - runtimeObjPath = "k8s.io/apimachinery/pkg/runtime.Object" -) - -var ( - enablePkgMarker = markers.Must(markers.MakeDefinition("kubebuilder:object:generate", markers.DescribesPackage, false)) - enableTypeMarker = markers.Must(markers.MakeDefinition("kubebuilder:object:generate", markers.DescribesType, false)) - isObjectMarker = markers.Must(markers.MakeDefinition("kubebuilder:object:root", markers.DescribesType, false)) - - legacyEnablePkgMarker = markers.Must(markers.MakeDefinition("k8s:deepcopy-gen", markers.DescribesPackage, markers.RawArguments(nil))) - legacyEnableTypeMarker = markers.Must(markers.MakeDefinition("k8s:deepcopy-gen", markers.DescribesType, markers.RawArguments(nil))) - legacyIsObjectMarker = markers.Must(markers.MakeDefinition("k8s:deepcopy-gen:interfaces", markers.DescribesType, "")) -) - -// +controllertools:marker:generateHelp - -// Generator generates code containing DeepCopy, DeepCopyInto, and -// DeepCopyObject method implementations. -type Generator struct { - // HeaderFile specifies the header text (e.g. license) to prepend to generated files. - HeaderFile string `marker:",optional"` - // Year specifies the year to substitute for " YEAR" in the header file. - Year string `marker:",optional"` -} - -func (Generator) CheckFilter() loader.NodeFilter { - return func(node ast.Node) bool { - // ignore interfaces - _, isIface := node.(*ast.InterfaceType) - return !isIface - } -} - -func (Generator) RegisterMarkers(into *markers.Registry) error { - if err := markers.RegisterAll(into, - enablePkgMarker, legacyEnablePkgMarker, enableTypeMarker, - legacyEnableTypeMarker, isObjectMarker, legacyIsObjectMarker); err != nil { - return err - } - into.AddHelp(enablePkgMarker, - markers.SimpleHelp("object", "enables or disables object interface & deepcopy implementation generation for this package")) - into.AddHelp( - enableTypeMarker, markers.SimpleHelp("object", "overrides enabling or disabling deepcopy generation for this type")) - into.AddHelp(isObjectMarker, - markers.SimpleHelp("object", "enables object interface implementation generation for this type")) - - into.AddHelp(legacyEnablePkgMarker, - markers.DeprecatedHelp(enablePkgMarker.Name, "object", "enables or disables object interface & deepcopy implementation generation for this package")) - into.AddHelp(legacyEnableTypeMarker, - markers.DeprecatedHelp(enableTypeMarker.Name, "object", "overrides enabling or disabling deepcopy generation for this type")) - into.AddHelp(legacyIsObjectMarker, - markers.DeprecatedHelp(isObjectMarker.Name, "object", "enables object interface implementation generation for this type")) - return nil -} - -func enabledOnPackage(col *markers.Collector, pkg *loader.Package) (bool, error) { - pkgMarkers, err := markers.PackageMarkers(col, pkg) - if err != nil { - return false, err - } - pkgMarker := pkgMarkers.Get(enablePkgMarker.Name) - if pkgMarker != nil { - return pkgMarker.(bool), nil - } - legacyMarker := pkgMarkers.Get(legacyEnablePkgMarker.Name) - if legacyMarker != nil { - legacyMarkerVal := string(legacyMarker.(markers.RawArguments)) - firstArg := strings.Split(legacyMarkerVal, ",")[0] - return firstArg == "package", nil - } - - return false, nil -} - -func enabledOnType(allTypes bool, info *markers.TypeInfo) bool { - if typeMarker := info.Markers.Get(enableTypeMarker.Name); typeMarker != nil { - return typeMarker.(bool) - } - legacyMarker := info.Markers.Get(legacyEnableTypeMarker.Name) - if legacyMarker != nil { - legacyMarkerVal := string(legacyMarker.(markers.RawArguments)) - return legacyMarkerVal == "true" - } - return allTypes || genObjectInterface(info) -} - -func genObjectInterface(info *markers.TypeInfo) bool { - objectEnabled := info.Markers.Get(isObjectMarker.Name) - if objectEnabled != nil { - return objectEnabled.(bool) - } - - for _, legacyEnabled := range info.Markers[legacyIsObjectMarker.Name] { - if legacyEnabled == runtimeObjPath { - return true - } - } - return false -} - -func (d Generator) Generate(ctx *genall.GenerationContext) error { - var headerText string - - if d.HeaderFile != "" { - headerBytes, err := ctx.ReadFile(d.HeaderFile) - if err != nil { - return err - } - headerText = string(headerBytes) - } - headerText = strings.ReplaceAll(headerText, " YEAR", " "+d.Year) - - objGenCtx := ObjectGenCtx{ - Collector: ctx.Collector, - Checker: ctx.Checker, - HeaderText: headerText, - } - - for _, root := range ctx.Roots { - outContents := objGenCtx.generateForPackage(root) - if outContents == nil { - continue - } - - writeOut(ctx, root, outContents) - } - - return nil -} - -// ObjectGenCtx contains the common info for generating deepcopy implementations. -// It mostly exists so that generating for a package can be easily tested without -// requiring a full set of output rules, etc. -type ObjectGenCtx struct { - Collector *markers.Collector - Checker *loader.TypeChecker - HeaderText string -} - -// writeHeader writes out the build tag, package declaration, and imports -func writeHeader(pkg *loader.Package, out io.Writer, packageName string, imports *importsList, headerText string) { - // NB(directxman12): blank line after build tags to distinguish them from comments - _, err := fmt.Fprintf(out, `//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -%[3]s - -// Code generated by controller-gen. DO NOT EDIT. - -package %[1]s - -import ( -%[2]s -) - -`, packageName, strings.Join(imports.ImportSpecs(), "\n"), headerText) - if err != nil { - pkg.AddError(err) - } - -} - -// generateForPackage generates DeepCopy and runtime.Object implementations for -// types in the given package, writing the formatted result to given writer. -// May return nil if source could not be generated. -func (ctx *ObjectGenCtx) generateForPackage(root *loader.Package) []byte { - allTypes, err := enabledOnPackage(ctx.Collector, root) - if err != nil { - root.AddError(err) - return nil - } - - ctx.Checker.Check(root) - - root.NeedTypesInfo() - - byType := make(map[string][]byte) - imports := &importsList{ - byPath: make(map[string]string), - byAlias: make(map[string]string), - pkg: root, - } - // avoid confusing aliases by "reserving" the root package's name as an alias - imports.byAlias[root.Name] = "" - - if err := markers.EachType(ctx.Collector, root, func(info *markers.TypeInfo) { - outContent := new(bytes.Buffer) - - // copy when nabled for all types and not disabled, or enabled - // specifically on this type - if !enabledOnType(allTypes, info) { - return - } - - // avoid copying non-exported types, etc - if !shouldBeCopied(root, info) { - return - } - - copyCtx := ©MethodMaker{ - pkg: root, - importsList: imports, - codeWriter: &codeWriter{out: outContent}, - } - - copyCtx.GenerateMethodsFor(root, info) - - outBytes := outContent.Bytes() - if len(outBytes) > 0 { - byType[info.Name] = outBytes - } - }); err != nil { - root.AddError(err) - return nil - } - - if len(byType) == 0 { - return nil - } - - outContent := new(bytes.Buffer) - writeHeader(root, outContent, root.Name, imports, ctx.HeaderText) - writeMethods(root, outContent, byType) - - outBytes := outContent.Bytes() - formattedBytes, err := format.Source(outBytes) - if err != nil { - root.AddError(err) - // we still write the invalid source to disk to figure out what went wrong - } else { - outBytes = formattedBytes - } - - return outBytes -} - -// writeMethods writes each method to the file, sorted by type name. -func writeMethods(pkg *loader.Package, out io.Writer, byType map[string][]byte) { - sortedNames := make([]string, 0, len(byType)) - for name := range byType { - sortedNames = append(sortedNames, name) - } - sort.Strings(sortedNames) - - for _, name := range sortedNames { - _, err := out.Write(byType[name]) - if err != nil { - pkg.AddError(err) - } - } -} - -// writeFormatted outputs the given code, after gofmt-ing it. If we couldn't gofmt, -// we write the unformatted code for debugging purposes. -func writeOut(ctx *genall.GenerationContext, root *loader.Package, outBytes []byte) { - outputFile, err := ctx.Open(root, "zz_generated.deepcopy.go") - if err != nil { - root.AddError(err) - return - } - defer outputFile.Close() - n, err := outputFile.Write(outBytes) - if err != nil { - root.AddError(err) - return - } - if n < len(outBytes) { - root.AddError(io.ErrShortWrite) - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/traverse.go b/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/traverse.go deleted file mode 100644 index 3a751757..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/traverse.go +++ /dev/null @@ -1,829 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package deepcopy - -import ( - "fmt" - "go/ast" - "go/types" - "io" - "path" - "strings" - "unicode" - "unicode/utf8" - - "sigs.k8s.io/controller-tools/pkg/loader" - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// NB(directxman12): This code is a bit of a byzantine mess. -// I've tried to clean it up a bit from the original in deepcopy-gen, -// but parts remain a bit convoluted. Exercise caution when changing. -// It's perhaps a tad over-commented now, but better safe than sorry. -// It also seriously needs auditing for sanity -- there's parts where we -// copy the original deepcopy-gen's output just to be safe, but some of that -// could be simplified away if we're careful. - -// codeWriter assists in writing out Go code lines and blocks to a writer. -type codeWriter struct { - out io.Writer -} - -// Line writes a single line. -func (c *codeWriter) Line(line string) { - fmt.Fprintln(c.out, line) -} - -// Linef writes a single line with formatting (as per fmt.Sprintf). -func (c *codeWriter) Linef(line string, args ...interface{}) { - fmt.Fprintf(c.out, line+"\n", args...) -} - -// If writes an if statement with the given setup/condition clause, executing -// the given function to write the contents of the block. -func (c *codeWriter) If(setup string, block func()) { - c.Linef("if %s {", setup) - block() - c.Line("}") -} - -// If writes if and else statements with the given setup/condition clause, executing -// the given functions to write the contents of the blocks. -func (c *codeWriter) IfElse(setup string, ifBlock func(), elseBlock func()) { - c.Linef("if %s {", setup) - ifBlock() - c.Line("} else {") - elseBlock() - c.Line("}") -} - -// For writes an for statement with the given setup/condition clause, executing -// the given function to write the contents of the block. -func (c *codeWriter) For(setup string, block func()) { - c.Linef("for %s {", setup) - block() - c.Line("}") -} - -// importsList keeps track of required imports, automatically assigning aliases -// to import statement. -type importsList struct { - byPath map[string]string - byAlias map[string]string - - pkg *loader.Package -} - -// NeedImport marks that the given package is needed in the list of imports, -// returning the ident (import alias) that should be used to reference the package. -func (l *importsList) NeedImport(importPath string) string { - // we get an actual path from Package, which might include venddored - // packages if running on a package in vendor. - if ind := strings.LastIndex(importPath, "/vendor/"); ind != -1 { - importPath = importPath[ind+8: /* len("/vendor/") */] - } - - // check to see if we've already assigned an alias, and just return that. - alias, exists := l.byPath[importPath] - if exists { - return alias - } - - // otherwise, calculate an import alias by joining path parts till we get something unique - restPath, nextWord := path.Split(importPath) - - for otherPath, exists := "", true; exists && otherPath != importPath; otherPath, exists = l.byAlias[alias] { - if restPath == "" { - // do something else to disambiguate if we're run out of parts and - // still have duplicates, somehow - alias += "x" - } - - // can't have a first digit, per Go identifier rules, so just skip them - for firstRune, runeLen := utf8.DecodeRuneInString(nextWord); unicode.IsDigit(firstRune); firstRune, runeLen = utf8.DecodeRuneInString(nextWord) { - nextWord = nextWord[runeLen:] - } - - // make a valid identifier by replacing "bad" characters with underscores - nextWord = strings.Map(func(r rune) rune { - if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { - return r - } - return '_' - }, nextWord) - - alias = nextWord + alias - if len(restPath) > 0 { - restPath, nextWord = path.Split(restPath[:len(restPath)-1] /* chop off final slash */) - } - } - - l.byPath[importPath] = alias - l.byAlias[alias] = importPath - return alias -} - -// ImportSpecs returns a string form of each import spec -// (i.e. `alias "path/to/import"). Aliases are only present -// when they don't match the package name. -func (l *importsList) ImportSpecs() []string { - res := make([]string, 0, len(l.byPath)) - for importPath, alias := range l.byPath { - pkg := l.pkg.Imports()[importPath] - if pkg != nil && pkg.Name == alias { - // don't print if alias is the same as package name - // (we've already taken care of duplicates). - res = append(res, fmt.Sprintf("%q", importPath)) - } else { - res = append(res, fmt.Sprintf("%s %q", alias, importPath)) - } - } - return res -} - -// namingInfo holds package and syntax for referencing a field, type, -// etc. It's used to allow lazily marking import usage. -// You should generally retrieve the syntax using Syntax. -type namingInfo struct { - // typeInfo is the type being named. - typeInfo types.Type - nameOverride string -} - -// Syntax calculates the code representation of the given type or name, -// and marks that is used (potentially marking an import as used). -func (n *namingInfo) Syntax(basePkg *loader.Package, imports *importsList) string { - if n.nameOverride != "" { - return n.nameOverride - } - - // NB(directxman12): typeInfo.String gets us most of the way there, - // but fails (for us) on named imports, since it uses the full package path. - switch typeInfo := n.typeInfo.(type) { - case *types.Named: - // register that we need an import for this type, - // so we can get the appropriate alias to use. - typeName := typeInfo.Obj() - otherPkg := typeName.Pkg() - if otherPkg == basePkg.Types { - // local import - return typeName.Name() - } - alias := imports.NeedImport(loader.NonVendorPath(otherPkg.Path())) - return alias + "." + typeName.Name() - case *types.Basic: - return typeInfo.String() - case *types.Pointer: - return "*" + (&namingInfo{typeInfo: typeInfo.Elem()}).Syntax(basePkg, imports) - case *types.Slice: - return "[]" + (&namingInfo{typeInfo: typeInfo.Elem()}).Syntax(basePkg, imports) - case *types.Map: - return fmt.Sprintf( - "map[%s]%s", - (&namingInfo{typeInfo: typeInfo.Key()}).Syntax(basePkg, imports), - (&namingInfo{typeInfo: typeInfo.Elem()}).Syntax(basePkg, imports)) - default: - basePkg.AddError(fmt.Errorf("name requested for invalid type: %s", typeInfo)) - return typeInfo.String() - } -} - -// copyMethodMakers makes DeepCopy (and related) methods for Go types, -// writing them to its codeWriter. -type copyMethodMaker struct { - pkg *loader.Package - *importsList - *codeWriter -} - -// GenerateMethodsFor makes DeepCopy, DeepCopyInto, and DeepCopyObject methods -// for the given type, when appropriate -func (c *copyMethodMaker) GenerateMethodsFor(root *loader.Package, info *markers.TypeInfo) { - typeInfo := root.TypesInfo.TypeOf(info.RawSpec.Name) - if typeInfo == types.Typ[types.Invalid] { - root.AddError(loader.ErrFromNode(fmt.Errorf("unknown type: %s", info.Name), info.RawSpec)) - } - - // figure out if we need to use a pointer receiver -- most types get a pointer receiver, - // except those that are aliases to types that are already pass-by-reference (pointers, - // interfaces. maps, slices). - ptrReceiver := usePtrReceiver(typeInfo) - - hasManualDeepCopyInto := hasDeepCopyIntoMethod(root, typeInfo) - hasManualDeepCopy, deepCopyOnPtr := hasDeepCopyMethod(root, typeInfo) - - // only generate each method if it hasn't been implemented. - if !hasManualDeepCopyInto { - c.Line("// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.") - if ptrReceiver { - c.Linef("func (in *%s) DeepCopyInto(out *%s) {", info.Name, info.Name) - } else { - c.Linef("func (in %s) DeepCopyInto(out *%s) {", info.Name, info.Name) - c.Line("{in := &in") // add an extra block so that we can redefine `in` without type issues - } - - // just wrap the existing deepcopy if present - if hasManualDeepCopy { - if deepCopyOnPtr { - c.Line("clone := in.DeepCopy()") - c.Line("*out = *clone") - } else { - c.Line("*out = in.DeepCopy()") - } - } else { - c.genDeepCopyIntoBlock(&namingInfo{nameOverride: info.Name}, typeInfo) - } - - if !ptrReceiver { - c.Line("}") // close our extra "in redefinition" block - } - c.Line("}") - } - - if !hasManualDeepCopy { - // these are both straightforward, so we just template them out. - if ptrReceiver { - c.Linef(ptrDeepCopy, info.Name) - } else { - c.Linef(bareDeepCopy, info.Name) - } - - // maybe also generate DeepCopyObject, if asked. - if genObjectInterface(info) { - // we always need runtime.Object for DeepCopyObject - runtimeAlias := c.NeedImport("k8s.io/apimachinery/pkg/runtime") - if ptrReceiver { - c.Linef(ptrDeepCopyObj, info.Name, runtimeAlias) - } else { - c.Linef(bareDeepCopyObj, info.Name, runtimeAlias) - } - } - } -} - -// genDeepCopyBody generates a DeepCopyInto block for the given type. The -// block is *not* wrapped in curly braces. -func (c *copyMethodMaker) genDeepCopyIntoBlock(actualName *namingInfo, typeInfo types.Type) { - // we calculate *how* we should copy mostly based on the "eventual" type of - // a given type (i.e. the type that results from following all aliases) - last := eventualUnderlyingType(typeInfo) - - // we might hit a type that has a manual deepcopy method written on non-root types - // (this case is handled for root types in GenerateMethodFor). - // In that case (when we're not dealing with a pointer, since those need special handling - // to match 1-to-1 with k8s deepcopy-gen), just use that. - if _, isPtr := last.(*types.Pointer); !isPtr && hasAnyDeepCopyMethod(c.pkg, typeInfo) { - c.Line("*out = in.DeepCopy()") - return - } - - switch last := last.(type) { - case *types.Basic: - switch last.Kind() { - case types.Invalid, types.UnsafePointer: - c.pkg.AddError(fmt.Errorf("invalid type: %s", last)) - default: - // basic types themselves can be "shallow" copied, so all we need - // to do is check if our *actual* type (not the underlying one) has - // a custom method implemented. - if hasMethod, _ := hasDeepCopyMethod(c.pkg, typeInfo); hasMethod { - c.Line("*out = in.DeepCopy()") - } - c.Line("*out = *in") - } - case *types.Map: - c.genMapDeepCopy(actualName, last) - case *types.Slice: - c.genSliceDeepCopy(actualName, last) - case *types.Struct: - c.genStructDeepCopy(actualName, last) - case *types.Pointer: - c.genPointerDeepCopy(actualName, last) - case *types.Named: - // handled via the above loop, should never happen - c.pkg.AddError(fmt.Errorf("interface type %s encountered directly, invalid condition", last)) - default: - c.pkg.AddError(fmt.Errorf("invalid type: %s", last)) - } -} - -// genMapDeepCopy generates DeepCopy code for the given named type whose eventual -// type is the given map type. -func (c *copyMethodMaker) genMapDeepCopy(actualName *namingInfo, mapType *types.Map) { - // maps *must* have shallow-copiable types, since we just iterate - // through the keys, only trying to deepcopy the values. - if !fineToShallowCopy(mapType.Key()) { - c.pkg.AddError(fmt.Errorf("invalid map key type: %s", mapType.Key())) - return - } - - // make our actual type (not the underlying one)... - c.Linef("*out = make(%[1]s, len(*in))", actualName.Syntax(c.pkg, c.importsList)) - - // ...and copy each element appropriately - c.For("key, val := range *in", func() { - // check if we have manually written methods, - // in which case we'll just try and use those - hasDeepCopy, copyOnPtr := hasDeepCopyMethod(c.pkg, mapType.Elem()) - hasDeepCopyInto := hasDeepCopyIntoMethod(c.pkg, mapType.Elem()) - switch { - case hasDeepCopyInto || hasDeepCopy: - // use the manually-written methods - _, fieldIsPtr := mapType.Elem().(*types.Pointer) // is "out" actually a pointer - inIsPtr := resultWillBePointer(mapType.Elem(), hasDeepCopy, copyOnPtr) // does copying "in" produce a pointer - if hasDeepCopy { - // If we're calling DeepCopy, check if it's receiver needs a pointer - inIsPtr = copyOnPtr - } - if inIsPtr == fieldIsPtr { - c.Line("(*out)[key] = val.DeepCopy()") - } else if fieldIsPtr { - c.Line("{") // use a block because we use `x` as a temporary - c.Line("x := val.DeepCopy()") - c.Line("(*out)[key] = &x") - c.Line("}") - } else { - c.Line("(*out)[key] = *val.DeepCopy()") - } - case fineToShallowCopy(mapType.Elem()): - // just shallow copy types for which it's safe to do so - c.Line("(*out)[key] = val") - default: - // otherwise, we've got some kind-specific actions, - // based on the element's eventual type. - - underlyingElem := eventualUnderlyingType(mapType.Elem()) - - // if it passes by reference, let the main switch handle it - if passesByReference(underlyingElem) { - c.Linef("var outVal %[1]s", (&namingInfo{typeInfo: underlyingElem}).Syntax(c.pkg, c.importsList)) - c.IfElse("val == nil", func() { - c.Line("(*out)[key] = nil") - }, func() { - c.Line("in, out := &val, &outVal") - c.genDeepCopyIntoBlock(&namingInfo{typeInfo: mapType.Elem()}, mapType.Elem()) - }) - c.Line("(*out)[key] = outVal") - - return - } - - // otherwise... - switch underlyingElem := underlyingElem.(type) { - case *types.Struct: - // structs will have deepcopy generated for them, so use that - c.Line("(*out)[key] = *val.DeepCopy()") - default: - c.pkg.AddError(fmt.Errorf("invalid map value type: %s", underlyingElem)) - return - } - } - }) -} - -// genSliceDeepCopy generates DeepCopy code for the given named type whose -// underlying type is the given slice. -func (c *copyMethodMaker) genSliceDeepCopy(actualName *namingInfo, sliceType *types.Slice) { - underlyingElem := eventualUnderlyingType(sliceType.Elem()) - - // make the actual type (not the underlying) - c.Linef("*out = make(%[1]s, len(*in))", actualName.Syntax(c.pkg, c.importsList)) - - // check if we need to do anything special, or just copy each element appropriately - switch { - case hasAnyDeepCopyMethod(c.pkg, sliceType.Elem()): - // just use deepcopy if it's present (deepcopyinto will be filled in by our code) - c.For("i := range *in", func() { - c.Line("(*in)[i].DeepCopyInto(&(*out)[i])") - }) - case fineToShallowCopy(underlyingElem): - // shallow copy if ok - c.Line("copy(*out, *in)") - default: - // copy each element appropriately - c.For("i := range *in", func() { - // fall back to normal code for reference types or those with custom logic - if passesByReference(underlyingElem) || hasAnyDeepCopyMethod(c.pkg, sliceType.Elem()) { - c.If("(*in)[i] != nil", func() { - c.Line("in, out := &(*in)[i], &(*out)[i]") - c.genDeepCopyIntoBlock(&namingInfo{typeInfo: sliceType.Elem()}, sliceType.Elem()) - }) - return - } - - switch underlyingElem.(type) { - case *types.Struct: - // structs will always have deepcopy - c.Linef("(*in)[i].DeepCopyInto(&(*out)[i])") - default: - c.pkg.AddError(fmt.Errorf("invalid slice element type: %s", underlyingElem)) - } - }) - } -} - -// genStructDeepCopy generates DeepCopy code for the given named type whose -// underlying type is the given struct. -func (c *copyMethodMaker) genStructDeepCopy(_ *namingInfo, structType *types.Struct) { - c.Line("*out = *in") - - for i := 0; i < structType.NumFields(); i++ { - field := structType.Field(i) - - // if we have a manual deepcopy, use that - hasDeepCopy, copyOnPtr := hasDeepCopyMethod(c.pkg, field.Type()) - hasDeepCopyInto := hasDeepCopyIntoMethod(c.pkg, field.Type()) - if hasDeepCopyInto || hasDeepCopy { - // NB(directxman12): yes, I know this is kind-of weird that we - // have all this special-casing here, but it's nice for testing - // purposes to be 1-to-1 with deepcopy-gen, which does all sorts of - // stuff like this (I'm pretty sure I found some codepaths that - // never execute there, because they're pretty clearly invalid - // syntax). - - _, fieldIsPtr := field.Type().(*types.Pointer) - inIsPtr := resultWillBePointer(field.Type(), hasDeepCopy, copyOnPtr) - if fieldIsPtr { - // we'll need a if block to check for nilness - // we'll let genDeepCopyIntoBlock handle the details, we just needed the setup - c.If(fmt.Sprintf("in.%s != nil", field.Name()), func() { - c.Linef("in, out := &in.%[1]s, &out.%[1]s", field.Name()) - c.genDeepCopyIntoBlock(&namingInfo{typeInfo: field.Type()}, field.Type()) - }) - } else { - // special-case for compatibility with deepcopy-gen - if inIsPtr == fieldIsPtr { - c.Linef("out.%[1]s = in.%[1]s.DeepCopy()", field.Name()) - } else { - c.Linef("in.%[1]s.DeepCopyInto(&out.%[1]s)", field.Name()) - } - } - continue - } - - // pass-by-reference fields get delegated to the main type - underlyingField := eventualUnderlyingType(field.Type()) - if passesByReference(underlyingField) { - c.If(fmt.Sprintf("in.%s != nil", field.Name()), func() { - c.Linef("in, out := &in.%[1]s, &out.%[1]s", field.Name()) - c.genDeepCopyIntoBlock(&namingInfo{typeInfo: field.Type()}, field.Type()) - }) - continue - } - - // otherwise... - switch underlyingField := underlyingField.(type) { - case *types.Basic: - switch underlyingField.Kind() { - case types.Invalid, types.UnsafePointer: - c.pkg.AddError(loader.ErrFromNode(fmt.Errorf("invalid field type: %s", underlyingField), field)) - return - default: - // nothing to do, initial assignment copied this - } - case *types.Struct: - if fineToShallowCopy(field.Type()) { - c.Linef("out.%[1]s = in.%[1]s", field.Name()) - } else { - c.Linef("in.%[1]s.DeepCopyInto(&out.%[1]s)", field.Name()) - } - default: - c.pkg.AddError(loader.ErrFromNode(fmt.Errorf("invalid field type: %s", underlyingField), field)) - return - } - } -} - -// genPointerDeepCopy generates DeepCopy code for the given named type whose -// underlying type is the given struct. -func (c *copyMethodMaker) genPointerDeepCopy(_ *namingInfo, pointerType *types.Pointer) { - underlyingElem := eventualUnderlyingType(pointerType.Elem()) - - // if we have a manually written deepcopy, just use that - hasDeepCopy, copyOnPtr := hasDeepCopyMethod(c.pkg, pointerType.Elem()) - hasDeepCopyInto := hasDeepCopyIntoMethod(c.pkg, pointerType.Elem()) - if hasDeepCopyInto || hasDeepCopy { - outNeedsPtr := resultWillBePointer(pointerType.Elem(), hasDeepCopy, copyOnPtr) - if hasDeepCopy { - outNeedsPtr = copyOnPtr - } - if outNeedsPtr { - c.Line("*out = (*in).DeepCopy()") - } else { - c.Line("x := (*in).DeepCopy()") - c.Line("*out = &x") - } - return - } - - // shallow-copiable types are pretty easy - if fineToShallowCopy(underlyingElem) { - c.Linef("*out = new(%[1]s)", (&namingInfo{typeInfo: pointerType.Elem()}).Syntax(c.pkg, c.importsList)) - c.Line("**out = **in") - return - } - - // pass-by-reference types get delegated to the main switch - if passesByReference(underlyingElem) { - c.Linef("*out = new(%s)", (&namingInfo{typeInfo: underlyingElem}).Syntax(c.pkg, c.importsList)) - c.If("**in != nil", func() { - c.Line("in, out := *in, *out") - c.genDeepCopyIntoBlock(&namingInfo{typeInfo: underlyingElem}, eventualUnderlyingType(underlyingElem)) - }) - return - } - - // otherwise... - switch underlyingElem := underlyingElem.(type) { - case *types.Struct: - c.Linef("*out = new(%[1]s)", (&namingInfo{typeInfo: pointerType.Elem()}).Syntax(c.pkg, c.importsList)) - c.Line("(*in).DeepCopyInto(*out)") - default: - c.pkg.AddError(fmt.Errorf("invalid pointer element type: %s", underlyingElem)) - return - } -} - -// usePtrReceiver checks if we need a pointer receiver on methods for the given type -// Pass-by-reference types don't get pointer receivers. -func usePtrReceiver(typeInfo types.Type) bool { - switch typeInfo.(type) { - case *types.Pointer: - return false - case *types.Map: - return false - case *types.Slice: - return false - case *types.Named: - return usePtrReceiver(typeInfo.Underlying()) - default: - return true - } -} - -func resultWillBePointer(typeInfo types.Type, hasDeepCopy, deepCopyOnPtr bool) bool { - // if we have a manual deepcopy, we can just check what that returns - if hasDeepCopy { - return deepCopyOnPtr - } - - // otherwise, we'll need to check its type - switch typeInfo := typeInfo.(type) { - case *types.Pointer: - // NB(directxman12): we don't have to worry about the elem having a deepcopy, - // since hasManualDeepCopy would've caught that. - - // we'll be calling on the elem, so check that - return resultWillBePointer(typeInfo.Elem(), false, false) - case *types.Map: - return false - case *types.Slice: - return false - case *types.Named: - return resultWillBePointer(typeInfo.Underlying(), false, false) - default: - return true - } -} - -// shouldBeCopied checks if we're supposed to make deepcopy methods the given type. -// -// This is the case if it's exported *and* either: -// - has a partial manual DeepCopy implementation (in which case we fill in the rest) -// - aliases to a non-basic type eventually -// - is a struct -func shouldBeCopied(pkg *loader.Package, info *markers.TypeInfo) bool { - if !ast.IsExported(info.Name) { - return false - } - - typeInfo := pkg.TypesInfo.TypeOf(info.RawSpec.Name) - if typeInfo == types.Typ[types.Invalid] { - pkg.AddError(loader.ErrFromNode(fmt.Errorf("unknown type: %s", info.Name), info.RawSpec)) - return false - } - - // according to gengo, everything named is an alias, except for an alias to a pointer, - // which is just a pointer, afaict. Just roll with it. - if asPtr, isPtr := typeInfo.(*types.Named).Underlying().(*types.Pointer); isPtr { - typeInfo = asPtr - } - - lastType := typeInfo - if _, isNamed := typeInfo.(*types.Named); isNamed { - // if it has a manual deepcopy or deepcopyinto, we're fine - if hasAnyDeepCopyMethod(pkg, typeInfo) { - return true - } - - for underlyingType := typeInfo.Underlying(); underlyingType != lastType; lastType, underlyingType = underlyingType, underlyingType.Underlying() { - // if it has a manual deepcopy or deepcopyinto, we're fine - if hasAnyDeepCopyMethod(pkg, underlyingType) { - return true - } - - // aliases to other things besides basics need copy methods - // (basics can be straight-up shallow-copied) - if _, isBasic := underlyingType.(*types.Basic); !isBasic { - return true - } - } - } - - // structs are the only thing that's not a basic that's copiable by default - _, isStruct := lastType.(*types.Struct) - return isStruct -} - -// hasDeepCopyMethod checks if this type has a manual DeepCopy method and if -// the method has a pointer receiver. -func hasDeepCopyMethod(pkg *loader.Package, typeInfo types.Type) (bool, bool) { - deepCopyMethod, ind, _ := types.LookupFieldOrMethod(typeInfo, true /* check pointers too */, pkg.Types, "DeepCopy") - if len(ind) != 1 { - // ignore embedded methods - return false, false - } - if deepCopyMethod == nil { - return false, false - } - - methodSig := deepCopyMethod.Type().(*types.Signature) - if methodSig.Params() != nil && methodSig.Params().Len() != 0 { - return false, false - } - if methodSig.Results() == nil || methodSig.Results().Len() != 1 { - return false, false - } - - recvAsPtr, recvIsPtr := methodSig.Recv().Type().(*types.Pointer) - if recvIsPtr { - // NB(directxman12): the pointer type returned here isn't comparable even though they - // have the same underlying type, for some reason (probably that - // LookupFieldOrMethod calls types.NewPointer for us), so check the - // underlying values. - - resultPtr, resultIsPtr := methodSig.Results().At(0).Type().(*types.Pointer) - if !resultIsPtr { - // pointer vs non-pointer are different types - return false, false - } - - if recvAsPtr.Elem() != resultPtr.Elem() { - return false, false - } - } else if methodSig.Results().At(0).Type() != methodSig.Recv().Type() { - return false, false - } - - return true, recvIsPtr -} - -// hasDeepCopyIntoMethod checks if this type has a manual DeepCopyInto method. -func hasDeepCopyIntoMethod(pkg *loader.Package, typeInfo types.Type) bool { - deepCopyMethod, ind, _ := types.LookupFieldOrMethod(typeInfo, true /* check pointers too */, pkg.Types, "DeepCopyInto") - if len(ind) != 1 { - // ignore embedded methods - return false - } - if deepCopyMethod == nil { - return false - } - - methodSig := deepCopyMethod.Type().(*types.Signature) - if methodSig.Params() == nil || methodSig.Params().Len() != 1 { - return false - } - paramPtr, isPtr := methodSig.Params().At(0).Type().(*types.Pointer) - if !isPtr { - return false - } - if methodSig.Results() != nil && methodSig.Results().Len() != 0 { - return false - } - - if recvPtr, recvIsPtr := methodSig.Recv().Type().(*types.Pointer); recvIsPtr { - // NB(directxman12): the pointer type returned here isn't comparable even though they - // have the same underlying type, for some reason (probably that - // LookupFieldOrMethod calls types.NewPointer for us), so check the - // underlying values. - return paramPtr.Elem() == recvPtr.Elem() - } - return methodSig.Recv().Type() == paramPtr.Elem() -} - -// hasAnyDeepCopyMethod checks if the given method has DeepCopy or DeepCopyInto -// (either of which implies the other will exist eventually). -func hasAnyDeepCopyMethod(pkg *loader.Package, typeInfo types.Type) bool { - hasDeepCopy, _ := hasDeepCopyMethod(pkg, typeInfo) - return hasDeepCopy || hasDeepCopyIntoMethod(pkg, typeInfo) -} - -// eventualUnderlyingType gets the "final" type in a sequence of named aliases. -// It's effectively a shortcut for calling Underlying in a loop. -func eventualUnderlyingType(typeInfo types.Type) types.Type { - last := typeInfo - for underlying := typeInfo.Underlying(); underlying != last; last, underlying = underlying, underlying.Underlying() { - // get the actual underlying type - } - return last -} - -// fineToShallowCopy checks if a shallow-copying a type is equivalent to deepcopy-ing it. -func fineToShallowCopy(typeInfo types.Type) bool { - switch typeInfo := typeInfo.(type) { - case *types.Basic: - // basic types (int, string, etc) are always fine to shallow-copy, - // except for Invalid and UnsafePointer, which can't be copied at all. - switch typeInfo.Kind() { - case types.Invalid, types.UnsafePointer: - return false - default: - return true - } - case *types.Named: - // aliases are fine to shallow-copy as long as they resolve to a shallow-copyable type - return fineToShallowCopy(typeInfo.Underlying()) - case *types.Struct: - // structs are fine to shallow-copy if they have all shallow-copyable fields - for i := 0; i < typeInfo.NumFields(); i++ { - field := typeInfo.Field(i) - if !fineToShallowCopy(field.Type()) { - return false - } - } - return true - default: - return false - } -} - -// passesByReference checks if the given type passesByReference -// (except for interfaces, which are handled separately). -func passesByReference(typeInfo types.Type) bool { - switch typeInfo.(type) { - case *types.Slice: - return true - case *types.Map: - return true - case *types.Pointer: - return true - default: - return false - } -} - -var ( - // ptrDeepCopy is a DeepCopy for a type with an existing DeepCopyInto and a pointer receiver. - ptrDeepCopy = ` -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new %[1]s. -func (in *%[1]s) DeepCopy() *%[1]s { - if in == nil { return nil } - out := new(%[1]s) - in.DeepCopyInto(out) - return out -} -` - - // ptrDeepCopy is a DeepCopy for a type with an existing DeepCopyInto and a non-pointer receiver. - bareDeepCopy = ` -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new %[1]s. -func (in %[1]s) DeepCopy() %[1]s { - if in == nil { return nil } - out := new(%[1]s) - in.DeepCopyInto(out) - return *out -} -` - - // ptrDeepCopy is a DeepCopyObject for a type with an existing DeepCopyInto and a pointer receiver. - ptrDeepCopyObj = ` -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *%[1]s) DeepCopyObject() %[2]s.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} -` - // ptrDeepCopy is a DeepCopyObject for a type with an existing DeepCopyInto and a non-pointer receiver. - bareDeepCopyObj = ` -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in %[1]s) DeepCopyObject() %[2]s.Object { - return in.DeepCopy() -} -` -) diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/zz_generated.markerhelp.go b/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/zz_generated.markerhelp.go deleted file mode 100644 index 913bc1fb..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/zz_generated.markerhelp.go +++ /dev/null @@ -1,46 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright2019 The Kubernetes Authors. - -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. -*/ - -// Code generated by helpgen. DO NOT EDIT. - -package deepcopy - -import ( - "sigs.k8s.io/controller-tools/pkg/markers" -) - -func (Generator) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "generates code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "HeaderFile": { - Summary: "specifies the header text (e.g. license) to prepend to generated files.", - Details: "", - }, - "Year": { - Summary: "specifies the year to substitute for \" YEAR\" in the header file.", - Details: "", - }, - }, - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/doc.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/doc.go deleted file mode 100644 index af67402e..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/doc.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// Package genall defines entrypoints for generation tools to hook into and -// share the same set of parsing, typechecking, and marker information. -// -// # Generators -// -// Each Generator knows how to register its markers into a central Registry, -// and then how to generate output using a Collector and some root packages. -// Each generator can be considered to be the output type of a marker, for easy -// command line parsing. -// -// # Output and Input -// -// Generators output artifacts via an OutputRule. OutputRules know how to -// write output for different package-associated (code) files, as well as -// config files. Each OutputRule should also be considered to be the output -// type as a marker, for easy command-line parsing. -// -// OutputRules groups together an OutputRule per generator, plus a default -// output rule for any not explicitly specified. -// -// OutputRules are defined for stdout, file writing, and sending to /dev/null -// (useful for doing "type-checking" without actually saving the results). -// -// InputRule defines custom input loading, but its shared across all -// Generators. There's currently only a filesystem implementation. -// -// # Runtime and Context -// -// Runtime maps together Generators, and constructs "contexts" which provide -// the common collector and roots, plus the output rule for that generator, and -// a handle for reading files (like boilerplate headers). -// -// It will run all associated generators, printing errors and automatically -// skipping type-checking errors (since those are commonly caused by the -// partial type-checking of loader.TypeChecker). -// -// # Options -// -// The FromOptions (and associated helpers) function makes it easy to use generators -// and output rules as markers that can be parsed from the command line, producing -// a registry from command line args. -package genall diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/genall.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/genall.go deleted file mode 100644 index 63afbac0..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/genall.go +++ /dev/null @@ -1,269 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package genall - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "os" - - "golang.org/x/tools/go/packages" - rawyaml "gopkg.in/yaml.v2" - - "sigs.k8s.io/controller-tools/pkg/loader" - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// Generators are a list of Generators. -// NB(directxman12): this is a pointer so that we can uniquely identify each -// instance of a generator, even if it's not hashable. Different *instances* -// of a generator are treated differently. -type Generators []*Generator - -// RegisterMarkers registers all markers defined by each of the Generators in -// this list into the given registry. -func (g Generators) RegisterMarkers(reg *markers.Registry) error { - for _, gen := range g { - if err := (*gen).RegisterMarkers(reg); err != nil { - return err - } - } - return nil -} - -// CheckFilters returns the set of NodeFilters for all Generators that -// implement NeedsTypeChecking. -func (g Generators) CheckFilters() []loader.NodeFilter { - var filters []loader.NodeFilter - for _, gen := range g { - withFilter, needsChecking := (*gen).(NeedsTypeChecking) - if !needsChecking { - continue - } - filters = append(filters, withFilter.CheckFilter()) - } - return filters -} - -// NeedsTypeChecking indicates that a particular generator needs & has opinions -// on typechecking. If this is not implemented, a generator will be given a -// context with a nil typechecker. -type NeedsTypeChecking interface { - // CheckFilter indicates the loader.NodeFilter (if any) that should be used - // to prune out unused types/packages when type-checking (nodes for which - // the filter returns true are considered "interesting"). This filter acts - // as a baseline -- all types the pass through this filter will be checked, - // but more than that may also be checked due to other generators' filters. - CheckFilter() loader.NodeFilter -} - -// Generator knows how to register some set of markers, and then produce -// output artifacts based on loaded code containing those markers, -// sharing common loaded data. -type Generator interface { - // RegisterMarkers registers all markers needed by this Generator - // into the given registry. - RegisterMarkers(into *markers.Registry) error - // Generate generates artifacts produced by this marker. - // It's called *after* RegisterMarkers has been called. - Generate(*GenerationContext) error -} - -// HasHelp is some Generator, OutputRule, etc with a help method. -type HasHelp interface { - // Help returns help for this generator. - Help() *markers.DefinitionHelp -} - -// Runtime collects generators, loaded program data (Collector, root Packages), -// and I/O rules, running them together. -type Runtime struct { - // Generators are the Generators to be run by this Runtime. - Generators Generators - // GenerationContext is the base generation context that's copied - // to produce the context for each Generator. - GenerationContext - // OutputRules defines how to output artifacts for each Generator. - OutputRules OutputRules - // ErrorWriter defines where to write error messages. - ErrorWriter io.Writer -} - -// GenerationContext defines the common information needed for each Generator -// to run. -type GenerationContext struct { - // Collector is the shared marker collector. - Collector *markers.Collector - // Roots are the base packages to be processed. - Roots []*loader.Package - // Checker is the shared partial type-checker. - Checker *loader.TypeChecker - // OutputRule describes how to output artifacts. - OutputRule - // InputRule describes how to load associated boilerplate artifacts. - // It should *not* be used to load source files. - InputRule -} - -// WriteYAMLOptions implements the Options Pattern for WriteYAML. -type WriteYAMLOptions struct { - transform func(obj map[string]interface{}) error -} - -// WithTransform applies a transformation to objects just before writing them. -func WithTransform(transform func(obj map[string]interface{}) error) *WriteYAMLOptions { - return &WriteYAMLOptions{ - transform: transform, - } -} - -// WriteYAML writes the given objects out, serialized as YAML, using the -// context's OutputRule. Objects are written as separate documents, separated -// from each other by `---` (as per the YAML spec). -func (g GenerationContext) WriteYAML(itemPath string, objs []interface{}, options ...*WriteYAMLOptions) error { - out, err := g.Open(nil, itemPath) - if err != nil { - return err - } - defer out.Close() - - for _, obj := range objs { - yamlContent, err := yamlMarshal(obj, options...) - if err != nil { - return err - } - n, err := out.Write(append([]byte("---\n"), yamlContent...)) - if err != nil { - return err - } - if n < len(yamlContent) { - return io.ErrShortWrite - } - } - - return nil -} - -// yamlMarshal is based on sigs.k8s.io/yaml.Marshal, but allows for transforming the final data before writing. -func yamlMarshal(o interface{}, options ...*WriteYAMLOptions) ([]byte, error) { - j, err := json.Marshal(o) - if err != nil { - return nil, fmt.Errorf("error marshaling into JSON: %v", err) - } - - return yamlJSONToYAMLWithFilter(j, options...) -} - -// yamlJSONToYAMLWithFilter is based on sigs.k8s.io/yaml.JSONToYAML, but allows for transforming the final data before writing. -func yamlJSONToYAMLWithFilter(j []byte, options ...*WriteYAMLOptions) ([]byte, error) { - // Convert the JSON to an object. - var jsonObj map[string]interface{} - // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the - // Go JSON library doesn't try to pick the right number type (int, float, - // etc.) when unmarshalling to interface{}, it just picks float64 - // universally. go-yaml does go through the effort of picking the right - // number type, so we can preserve number type throughout this process. - if err := rawyaml.Unmarshal(j, &jsonObj); err != nil { - return nil, err - } - - for _, option := range options { - if option.transform != nil { - if err := option.transform(jsonObj); err != nil { - return nil, err - } - } - } - - // Marshal this object into YAML. - return rawyaml.Marshal(jsonObj) -} - -// ReadFile reads the given boilerplate artifact using the context's InputRule. -func (g GenerationContext) ReadFile(path string) ([]byte, error) { - file, err := g.OpenForRead(path) - if err != nil { - return nil, err - } - defer file.Close() - return ioutil.ReadAll(file) -} - -// ForRoots produces a Runtime to run the given generators against the -// given packages. It outputs to /dev/null by default. -func (g Generators) ForRoots(rootPaths ...string) (*Runtime, error) { - roots, err := loader.LoadRoots(rootPaths...) - if err != nil { - return nil, err - } - rt := &Runtime{ - Generators: g, - GenerationContext: GenerationContext{ - Collector: &markers.Collector{ - Registry: &markers.Registry{}, - }, - Roots: roots, - InputRule: InputFromFileSystem, - Checker: &loader.TypeChecker{ - NodeFilters: g.CheckFilters(), - }, - }, - OutputRules: OutputRules{Default: OutputToNothing}, - } - if err := rt.Generators.RegisterMarkers(rt.Collector.Registry); err != nil { - return nil, err - } - return rt, nil -} - -// Run runs the Generators in this Runtime against its packages, printing -// errors (except type errors, which common result from using TypeChecker with -// filters), returning true if errors were found. -func (r *Runtime) Run() bool { - // TODO(directxman12): we could make this parallel, - // but we'd need to ensure all underlying machinery is threadsafe - - if r.ErrorWriter == nil { - r.ErrorWriter = os.Stderr - } - if len(r.Generators) == 0 { - fmt.Fprintln(r.ErrorWriter, "no generators to run") - return true - } - - hadErrs := false - for _, gen := range r.Generators { - ctx := r.GenerationContext // make a shallow copy - ctx.OutputRule = r.OutputRules.ForGenerator(gen) - - // don't pass a typechecker to generators that don't provide a filter - // to avoid accidents - if _, needsChecking := (*gen).(NeedsTypeChecking); !needsChecking { - ctx.Checker = nil - } - - if err := (*gen).Generate(&ctx); err != nil { - fmt.Fprintln(r.ErrorWriter, err) - hadErrs = true - } - } - - // skip TypeErrors -- they're probably just from partial typechecking in crd-gen - return loader.PrintErrors(r.Roots, packages.TypeError) || hadErrs -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/doc.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/doc.go deleted file mode 100644 index d84d1798..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/doc.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// Package help contains utilities for actually writing out marker help. -// -// Namely, it contains a series of structs (and helpers for producing them) -// that represent a merged view of marker definition and help that can be used -// for consumption by the pretty subpackage (for terminal help) or serialized -// as JSON (e.g. for generating HTML help). -package help diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/doc.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/doc.go deleted file mode 100644 index bc99e9ba..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/doc.go +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// Package pretty contains utilities for formatting terminal help output, -// and a use of those to display marker help. -// -// # Terminal Output -// -// The Span interface and Table struct allow you to construct tables with -// colored formatting, without causing ANSI formatting characters to mess up width -// calculations. -// -// # Marker Help -// -// The MarkersSummary prints a summary table for marker help, while the MarkersDetails -// prints out more detailed information, with explainations of the individual marker fields. -package pretty diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/help.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/help.go deleted file mode 100644 index 3e34cc0d..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/help.go +++ /dev/null @@ -1,171 +0,0 @@ -package pretty - -import ( - "fmt" - "io" - - "sigs.k8s.io/controller-tools/pkg/genall/help" - - "github.com/fatih/color" -) - -var ( - headingStyle = Decoration(*color.New(color.Bold, color.Underline)) - markerNameStyle = Decoration(*color.New(color.Bold)) - fieldSummaryStyle = Decoration(*color.New(color.FgGreen, color.Italic)) - markerTargetStyle = Decoration(*color.New(color.Faint)) - fieldDetailStyle = Decoration(*color.New(color.Italic, color.FgGreen)) - deprecatedStyle = Decoration(*color.New(color.CrossedOut)) -) - -// MarkersSummary returns a condensed summary of help for the given markers. -func MarkersSummary(groupName string, markers []help.MarkerDoc) Span { - out := new(SpanWriter) - - out.Print(Text("\n")) - out.Print(headingStyle.Containing(Text(groupName))) - out.Print(Text("\n\n")) - - table := &Table{Sizing: &TableCalculator{Padding: 2}} - for _, marker := range markers { - table.StartRow() - table.Column(MarkerSyntaxHelp(marker)) - table.Column(markerTargetStyle.Containing(Text(marker.Target))) - - summary := new(SpanWriter) - if marker.DeprecatedInFavorOf != nil && len(*marker.DeprecatedInFavorOf) > 0 { - summary.Print(markerNameStyle.Containing(Text("(use "))) - summary.Print(markerNameStyle.Containing(Text(*marker.DeprecatedInFavorOf))) - summary.Print(markerNameStyle.Containing(Text(") "))) - } - summary.Print(Text(marker.Summary)) - table.Column(summary) - - table.EndRow() - } - out.Print(table) - - out.Print(Text("\n")) - - return out -} - -// MarkersDetails returns detailed help for the given markers, including detailed field help. -func MarkersDetails(fullDetail bool, groupName string, markers []help.MarkerDoc) Span { - out := new(SpanWriter) - - out.Print(Line(headingStyle.Containing(Text(groupName)))) - out.Print(Newlines(2)) - - for _, marker := range markers { - out.Print(Line(markerName(marker))) - out.Print(Text(" ")) - out.Print(markerTargetStyle.Containing(Text(marker.Target))) - - summary := new(SpanWriter) - if marker.DeprecatedInFavorOf != nil && len(*marker.DeprecatedInFavorOf) > 0 { - summary.Print(markerNameStyle.Containing(Text("(use "))) - summary.Print(markerNameStyle.Containing(Text(*marker.DeprecatedInFavorOf))) - summary.Print(markerNameStyle.Containing(Text(") "))) - } - summary.Print(Text(marker.Summary)) - - if !marker.AnonymousField() { - out.Print(Indented(1, Line(summary))) - if len(marker.Details) > 0 && fullDetail { - out.Print(Indented(1, Line(Text(marker.Details)))) - } - } - - if marker.AnonymousField() { - out.Print(Indented(1, Line(fieldDetailStyle.Containing(FieldSyntaxHelp(marker.Fields[0]))))) - out.Print(Text(" ")) - out.Print(summary) - if len(marker.Details) > 0 && fullDetail { - out.Print(Indented(2, Line(Text(marker.Details)))) - } - out.Print(Newlines(1)) - } else if !marker.Empty() { - out.Print(Newlines(1)) - if fullDetail { - for _, arg := range marker.Fields { - out.Print(Indented(1, Line(fieldDetailStyle.Containing(FieldSyntaxHelp(arg))))) - out.Print(Indented(2, Line(Text(arg.Summary)))) - if len(arg.Details) > 0 && fullDetail { - out.Print(Indented(2, Line(Text(arg.Details)))) - out.Print(Newlines(1)) - } - } - out.Print(Newlines(1)) - } else { - table := &Table{Sizing: &TableCalculator{Padding: 2}} - for _, arg := range marker.Fields { - table.StartRow() - table.Column(fieldDetailStyle.Containing(FieldSyntaxHelp(arg))) - table.Column(Text(arg.Summary)) - table.EndRow() - } - - out.Print(Indented(1, table)) - } - } else { - out.Print(Newlines(1)) - } - } - - return out -} - -func FieldSyntaxHelp(arg help.FieldHelp) Span { - return fieldSyntaxHelp(arg, "") -} - -// fieldSyntaxHelp prints the syntax help for a particular marker argument. -func fieldSyntaxHelp(arg help.FieldHelp, sep string) Span { - if arg.Optional { - return FromWriter(func(out io.Writer) error { - _, err := fmt.Fprintf(out, "[%s%s=<%s>]", sep, arg.Name, arg.TypeString()) - return err - }) - } - return FromWriter(func(out io.Writer) error { - _, err := fmt.Fprintf(out, "%s%s=<%s>", sep, arg.Name, arg.TypeString()) - return err - }) -} - -// markerName returns a span containing just the appropriately-formatted marker name. -func markerName(def help.MarkerDoc) Span { - if def.DeprecatedInFavorOf != nil { - return deprecatedStyle.Containing(Text("+" + def.Name)) - } - return markerNameStyle.Containing(Text("+" + def.Name)) -} - -// MarkerSyntaxHelp assembles syntax help for a given marker. -func MarkerSyntaxHelp(def help.MarkerDoc) Span { - out := new(SpanWriter) - - out.Print(markerName(def)) - - if def.Empty() { - return out - } - - sep := ":" - if def.AnonymousField() { - sep = "" - } - - fieldStyle := fieldSummaryStyle - if def.DeprecatedInFavorOf != nil { - fieldStyle = deprecatedStyle - } - - for _, arg := range def.Fields { - out.Print(fieldStyle.Containing(fieldSyntaxHelp(arg, sep))) - sep = "," - } - - return out -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/print.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/print.go deleted file mode 100644 index 8d7452a0..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/print.go +++ /dev/null @@ -1,304 +0,0 @@ -package pretty - -import ( - "bytes" - "fmt" - "io" - - "github.com/fatih/color" -) - -// NB(directxman12): this isn't particularly elegant, but it's also -// sufficiently simple as to be maintained here. Man (roff) would've -// probably worked, but it's not necessarily on Windows by default. - -// Span is a chunk of content that is writable to an output, but knows how to -// calculate its apparent visual "width" on the terminal (not to be confused -// with the raw length, which may include zero-width coloring sequences). -type Span interface { - // VisualLength reports the "width" as perceived by the user on the terminal - // (i.e. widest line, ignoring ANSI escape characters). - VisualLength() int - // WriteTo writes the full span contents to the given writer. - WriteTo(io.Writer) error -} - -// Table is a Span that writes its data in table form, with sizing controlled -// by the given table calculator. Rows are started with StartRow, followed by -// some calls to Column, followed by a call to EndRow. Once all rows are -// added, the table can be used as a Span. -type Table struct { - Sizing *TableCalculator - - cellsByRow [][]Span - colSizes []int -} - -// StartRow starts a new row. -// It must eventually be followed by EndRow. -func (t *Table) StartRow() { - t.cellsByRow = append(t.cellsByRow, []Span(nil)) -} - -// EndRow ends the currently started row. -func (t *Table) EndRow() { - lastRow := t.cellsByRow[len(t.cellsByRow)-1] - sizes := make([]int, len(lastRow)) - for i, cell := range lastRow { - sizes[i] = cell.VisualLength() - } - t.Sizing.AddRowSizes(sizes...) -} - -// Column adds the given span as a new column to the current row. -func (t *Table) Column(contents Span) { - currentRowInd := len(t.cellsByRow) - 1 - t.cellsByRow[currentRowInd] = append(t.cellsByRow[currentRowInd], contents) -} - -// SkipRow prints a span without having it contribute to the table calculation. -func (t *Table) SkipRow(contents Span) { - t.cellsByRow = append(t.cellsByRow, []Span{contents}) -} - -func (t *Table) WriteTo(out io.Writer) error { - if t.colSizes == nil { - t.colSizes = t.Sizing.ColumnWidths() - } - - for _, cells := range t.cellsByRow { - currentPosition := 0 - for colInd, cell := range cells { - colSize := t.colSizes[colInd] - diff := colSize - cell.VisualLength() - - if err := cell.WriteTo(out); err != nil { - return err - } - - if diff > 0 { - if err := writePadding(out, columnPadding, diff); err != nil { - return err - } - } - currentPosition += colSize - } - - if _, err := fmt.Fprint(out, "\n"); err != nil { - return err - } - } - - return nil -} - -func (t *Table) VisualLength() int { - if t.colSizes == nil { - t.colSizes = t.Sizing.ColumnWidths() - } - - res := 0 - for _, colSize := range t.colSizes { - res += colSize - } - return res -} - -// Text is a span that simply contains raw text. It's a good starting point. -type Text string - -func (t Text) VisualLength() int { return len(t) } -func (t Text) WriteTo(w io.Writer) error { - _, err := w.Write([]byte(t)) - return err -} - -// indented is a span that indents all lines by the given number of tabs. -type indented struct { - Amount int - Content Span -} - -func (i *indented) VisualLength() int { return i.Content.VisualLength() } -func (i *indented) WriteTo(w io.Writer) error { - var out bytes.Buffer - if err := i.Content.WriteTo(&out); err != nil { - return err - } - - lines := bytes.Split(out.Bytes(), []byte("\n")) - for lineInd, line := range lines { - if lineInd != 0 { - if _, err := w.Write([]byte("\n")); err != nil { - return err - } - } - if len(line) == 0 { - continue - } - - if err := writePadding(w, indentPadding, i.Amount); err != nil { - return err - } - if _, err := w.Write(line); err != nil { - return err - } - } - return nil -} - -// Indented returns a span that indents all lines by the given number of tabs. -func Indented(amt int, content Span) Span { - return &indented{Amount: amt, Content: content} -} - -// fromWriter is a span that takes content from a function expecting a Writer. -type fromWriter struct { - cache []byte - cacheError error - run func(io.Writer) error -} - -func (f *fromWriter) VisualLength() int { - if f.cache == nil { - var buf bytes.Buffer - if err := f.run(&buf); err != nil { - f.cacheError = err - } - f.cache = buf.Bytes() - } - return len(f.cache) -} -func (f *fromWriter) WriteTo(w io.Writer) error { - if f.cache != nil { - if f.cacheError != nil { - return f.cacheError - } - _, err := w.Write(f.cache) - return err - } - return f.run(w) -} - -// FromWriter returns a span that takes content from a function expecting a Writer. -func FromWriter(run func(io.Writer) error) Span { - return &fromWriter{run: run} -} - -// Decoration represents a terminal decoration. -type Decoration color.Color - -// Containing returns a Span that has the given decoration applied. -func (d Decoration) Containing(contents Span) Span { - return &decorated{ - Contents: contents, - Attributes: color.Color(d), - } -} - -// decorated is a span that has some terminal decoration applied. -type decorated struct { - Contents Span - Attributes color.Color -} - -func (d *decorated) VisualLength() int { return d.Contents.VisualLength() } -func (d *decorated) WriteTo(w io.Writer) error { - oldOut := color.Output - color.Output = w - defer func() { color.Output = oldOut }() - - d.Attributes.Set() - defer color.Unset() - - return d.Contents.WriteTo(w) -} - -// SpanWriter is a span that contains multiple sub-spans. -type SpanWriter struct { - contents []Span -} - -func (m *SpanWriter) VisualLength() int { - res := 0 - for _, span := range m.contents { - res += span.VisualLength() - } - return res -} -func (m *SpanWriter) WriteTo(w io.Writer) error { - for _, span := range m.contents { - if err := span.WriteTo(w); err != nil { - return err - } - } - return nil -} - -// Print adds a new span to this SpanWriter. -func (m *SpanWriter) Print(s Span) { - m.contents = append(m.contents, s) -} - -// lines is a span that adds some newlines, optionally followed by some content. -type lines struct { - content Span - amountBefore int -} - -func (l *lines) VisualLength() int { - if l.content == nil { - return 0 - } - return l.content.VisualLength() -} -func (l *lines) WriteTo(w io.Writer) error { - if err := writePadding(w, linesPadding, l.amountBefore); err != nil { - return err - } - if l.content != nil { - if err := l.content.WriteTo(w); err != nil { - return err - } - } - return nil -} - -// Newlines returns a span just containing some newlines. -func Newlines(amt int) Span { - return &lines{amountBefore: amt} -} - -// Line returns a span that emits a newline, followed by the given content. -func Line(content Span) Span { - return &lines{amountBefore: 1, content: content} -} - -var ( - columnPadding = []byte(" ") - indentPadding = []byte("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t") - linesPadding = []byte("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n") -) - -// writePadding writes out padding of the given type in the given amount to the writer. -// Each byte in the padding buffer contributes 1 to the amount -- the padding being -// a buffer is just for efficiency. -func writePadding(out io.Writer, typ []byte, amt int) error { - if amt <= len(typ) { - _, err := out.Write(typ[:amt]) - return err - } - - num := amt / len(typ) - rem := amt % len(typ) - for i := 0; i < num; i++ { - if _, err := out.Write(typ); err != nil { - return err - } - } - - if _, err := out.Write(typ[:rem]); err != nil { - return err - } - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/table.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/table.go deleted file mode 100644 index 5a0b4752..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/pretty/table.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package pretty - -// TableCalculator calculates column widths (with optional padding) -// for a table based on the maximum required column width. -type TableCalculator struct { - cellSizesByCol [][]int - - Padding int - MaxWidth int -} - -// AddRowSizes registers a new row with cells of the given sizes. -func (c *TableCalculator) AddRowSizes(cellSizes ...int) { - if len(cellSizes) > len(c.cellSizesByCol) { - for range cellSizes[len(c.cellSizesByCol):] { - c.cellSizesByCol = append(c.cellSizesByCol, []int(nil)) - } - } - for i, size := range cellSizes { - c.cellSizesByCol[i] = append(c.cellSizesByCol[i], size) - } -} - -// ColumnWidths calculates the appropriate column sizes given the -// previously registered rows. -func (c *TableCalculator) ColumnWidths() []int { - maxColWidths := make([]int, len(c.cellSizesByCol)) - - for colInd, cellSizes := range c.cellSizesByCol { - max := 0 - for _, cellSize := range cellSizes { - if max < cellSize { - max = cellSize - } - } - maxColWidths[colInd] = max - } - - actualMaxWidth := c.MaxWidth - c.Padding - for i, width := range maxColWidths { - if actualMaxWidth > 0 && width > actualMaxWidth { - maxColWidths[i] = actualMaxWidth - } - maxColWidths[i] += c.Padding - } - - return maxColWidths -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/sort.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/sort.go deleted file mode 100644 index 53c923e3..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/sort.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package help - -import ( - "strings" - - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// SortGroup knows how to sort and group marker definitions. -type SortGroup interface { - // Less is equivalent to the Less function from sort, and is used to sort the markers. - Less(*markers.Definition, *markers.Definition) bool - // Group returns the "group" that a given marker belongs to. - Group(*markers.Definition, *markers.DefinitionHelp) string -} - -var ( - // SortByCategory sorts the markers by name and groups them by their help category. - SortByCategory = sortByCategory{} - - // SortByOption sorts by the generator that the option belongs to. - SortByOption = optionsSort{} -) - -type sortByCategory struct{} - -func (sortByCategory) Group(_ *markers.Definition, help *markers.DefinitionHelp) string { - if help == nil { - return "" - } - return help.Category -} -func (sortByCategory) Less(i, j *markers.Definition) bool { - return i.Name < j.Name -} - -type optionsSort struct{} - -func (optionsSort) Less(i, j *markers.Definition) bool { - iParts := strings.Split(i.Name, ":") - jParts := strings.Split(j.Name, ":") - - iGen := "" - iRule := "" - jGen := "" - jRule := "" - - switch len(iParts) { - case 1: - iGen = iParts[0] - // two means a default output rule, so ignore - case 2: - iRule = iParts[1] - case 3: - iGen = iParts[1] - iRule = iParts[2] - } - switch len(jParts) { - case 1: - jGen = jParts[0] - // two means a default output rule, so ignore - case 2: - jRule = jParts[1] - case 3: - jGen = jParts[1] - jRule = jParts[2] - } - - if iGen != jGen { - return iGen > jGen - } - - return iRule < jRule -} -func (optionsSort) Group(def *markers.Definition, _ *markers.DefinitionHelp) string { - parts := strings.Split(def.Name, ":") - - switch len(parts) { - case 1: - if parts[0] == "paths" { - return "generic" - } - return "generators" - case 2: - return "output rules (optionally as output::...)" - default: - return "" - // three means a marker-specific output rule, ignore - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/types.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/types.go deleted file mode 100644 index be111043..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/help/types.go +++ /dev/null @@ -1,215 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package help - -import ( - "sort" - "strings" - - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// DetailedHelp contains both a summary and further details. -type DetailedHelp struct { - // Summary contains a one-line description. - Summary string `json:"summary"` - // Details contains further information. - Details string `json:"details,omitempty"` -} - -// Argument is the type data for a marker argument. -type Argument struct { - // Type is the data type of the argument (string, bool, int, slice, any, raw, invalid) - Type string `json:"type"` - // Optional marks this argument as optional. - Optional bool `json:"optional"` - // ItemType contains the type of the slice item, if this is a slice - ItemType *Argument `json:"itemType,omitempty"` -} - -func (a Argument) typeString(out *strings.Builder) { - if a.Type == "slice" { - out.WriteString("[]") - a.ItemType.typeString(out) - return - } - - out.WriteString(a.Type) -} - -// TypeString returns a string roughly equivalent -// (but not identical) to the underlying Go type that -// this argument would parse to. It's mainly useful -// for user-friendly formatting of this argument (e.g. -// help strings). -func (a Argument) TypeString() string { - out := &strings.Builder{} - a.typeString(out) - return out.String() -} - -// FieldHelp contains information required to print documentation for a marker field. -type FieldHelp struct { - // Name is the field name. - Name string `json:"name"` - // Argument is the type of the field. - Argument `json:",inline"` - - // DetailedHelp contains the textual help for the field. - DetailedHelp `json:",inline"` -} - -// MarkerDoc contains information required to print documentation for a marker. -type MarkerDoc struct { - // definition - - // Name is the name of the marker. - Name string `json:"name"` - // Target is the target (field, package, type) of the marker. - Target string `json:"target"` - - // help - - // DetailedHelp is the textual help for the marker. - DetailedHelp `json:",inline"` - // Category is the general "category" that this marker belongs to. - Category string `json:"category"` - // DeprecatedInFavorOf marks that this marker shouldn't be used when - // non-nil. If also non-empty, another marker should be used instead. - DeprecatedInFavorOf *string `json:"deprecatedInFavorOf,omitempty"` - // Fields is the type and help data for each field of this marker. - Fields []FieldHelp `json:"fields,omitempty"` -} - -// Empty checks if this marker has any arguments, returning true if not. -func (m MarkerDoc) Empty() bool { - return len(m.Fields) == 0 -} - -// AnonymousField chekcs if this is an single-valued marker -// (as opposed to having named fields). -func (m MarkerDoc) AnonymousField() bool { - return len(m.Fields) == 1 && m.Fields[0].Name == "" -} - -// ForArgument returns the equivalent documentation for a marker argument. -func ForArgument(argRaw markers.Argument) Argument { - res := Argument{ - Optional: argRaw.Optional, - } - - if argRaw.ItemType != nil { - itemType := ForArgument(*argRaw.ItemType) - res.ItemType = &itemType - } - - switch argRaw.Type { - case markers.IntType: - res.Type = "int" - case markers.StringType: - res.Type = "string" - case markers.BoolType: - res.Type = "bool" - case markers.AnyType: - res.Type = "any" - case markers.SliceType: - res.Type = "slice" - case markers.RawType: - res.Type = "raw" - case markers.InvalidType: - res.Type = "invalid" - } - - return res -} - -// ForDefinition returns the equivalent marker documentation for a given marker definition and spearate help. -func ForDefinition(defn *markers.Definition, maybeHelp *markers.DefinitionHelp) MarkerDoc { - var help markers.DefinitionHelp - if maybeHelp != nil { - help = *maybeHelp - } - - res := MarkerDoc{ - Name: defn.Name, - Category: help.Category, - DeprecatedInFavorOf: help.DeprecatedInFavorOf, - Target: defn.Target.String(), - DetailedHelp: DetailedHelp{Summary: help.Summary, Details: help.Details}, - } - - helpByField := help.FieldsHelp(defn) - - // TODO(directxman12): deterministic ordering - for fieldName, fieldHelpRaw := range helpByField { - fieldInfo := defn.Fields[fieldName] - fieldHelp := FieldHelp{ - Name: fieldName, - DetailedHelp: DetailedHelp{Summary: fieldHelpRaw.Summary, Details: fieldHelpRaw.Details}, - Argument: ForArgument(fieldInfo), - } - - res.Fields = append(res.Fields, fieldHelp) - } - - sort.Slice(res.Fields, func(i, j int) bool { return res.Fields[i].Name < res.Fields[j].Name }) - - return res -} - -// CategoryDoc contains help information for all markers in a Category. -type CategoryDoc struct { - Category string `json:"category"` - Markers []MarkerDoc `json:"markers"` -} - -// ByCategory returns the marker help for markers in the given -// registry, grouped and sorted according to the given method. -func ByCategory(reg *markers.Registry, sorter SortGroup) []CategoryDoc { - groupedMarkers := make(map[string][]*markers.Definition) - - for _, marker := range reg.AllDefinitions() { - group := sorter.Group(marker, reg.HelpFor(marker)) - groupedMarkers[group] = append(groupedMarkers[group], marker) - } - allGroups := make([]string, 0, len(groupedMarkers)) - for groupName := range groupedMarkers { - allGroups = append(allGroups, groupName) - } - - sort.Strings(allGroups) - - res := make([]CategoryDoc, len(allGroups)) - for i, groupName := range allGroups { - markers := groupedMarkers[groupName] - sort.Slice(markers, func(i, j int) bool { - return sorter.Less(markers[i], markers[j]) - }) - - markerDocs := make([]MarkerDoc, len(markers)) - for i, marker := range markers { - markerDocs[i] = ForDefinition(marker, reg.HelpFor(marker)) - } - - res[i] = CategoryDoc{ - Category: groupName, - Markers: markerDocs, - } - } - - return res -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/input.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/input.go deleted file mode 100644 index 46e191c0..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/input.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package genall - -import ( - "io" - "os" -) - -// InputRule describes how to load non-code boilerplate artifacts. -// It's not used for loading code. -type InputRule interface { - // OpenForRead opens the given non-code artifact for reading. - OpenForRead(path string) (io.ReadCloser, error) -} -type inputFromFileSystem struct{} - -func (inputFromFileSystem) OpenForRead(path string) (io.ReadCloser, error) { - return os.Open(path) -} - -// InputFromFileSystem reads from the filesystem as normal. -var InputFromFileSystem = inputFromFileSystem{} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/options.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/options.go deleted file mode 100644 index 836b1617..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/options.go +++ /dev/null @@ -1,194 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package genall - -import ( - "fmt" - "strings" - - "sigs.k8s.io/controller-tools/pkg/markers" -) - -var ( - InputPathsMarker = markers.Must(markers.MakeDefinition("paths", markers.DescribesPackage, InputPaths(nil))) -) - -// +controllertools:marker:generateHelp:category="" - -// InputPaths represents paths and go-style path patterns to use as package roots. -// -// Multiple paths can be specified using "{path1, path2, path3}". -type InputPaths []string - -// RegisterOptionsMarkers registers "mandatory" options markers for FromOptions into the given registry. -// At this point, that's just InputPaths. -func RegisterOptionsMarkers(into *markers.Registry) error { - if err := into.Register(InputPathsMarker); err != nil { - return err - } - // NB(directxman12): we make this optional so we don't have a bootstrap problem with helpgen - if helpGiver, hasHelp := ((interface{})(InputPaths(nil))).(HasHelp); hasHelp { - into.AddHelp(InputPathsMarker, helpGiver.Help()) - } - return nil -} - -// RegistryFromOptions produces just the marker registry that would be used by FromOptions, without -// attempting to produce a full Runtime. This can be useful if you want to display help without -// trying to load roots. -func RegistryFromOptions(optionsRegistry *markers.Registry, options []string) (*markers.Registry, error) { - protoRt, err := protoFromOptions(optionsRegistry, options) - if err != nil { - return nil, err - } - reg := &markers.Registry{} - if err := protoRt.Generators.RegisterMarkers(reg); err != nil { - return nil, err - } - return reg, nil -} - -// FromOptions parses the options from markers stored in the given registry out into a runtime. -// The markers in the registry must be either -// -// a) Generators -// b) OutputRules -// c) InputPaths -// -// The paths specified in InputPaths are loaded as package roots, and the combined with -// the generators and the specified output rules to produce a runtime that can be run or -// further modified. Not default generators are used if none are specified -- you can check -// the output and rerun for that. -func FromOptions(optionsRegistry *markers.Registry, options []string) (*Runtime, error) { - - protoRt, err := protoFromOptions(optionsRegistry, options) - if err != nil { - return nil, err - } - - // make the runtime - genRuntime, err := protoRt.Generators.ForRoots(protoRt.Paths...) - if err != nil { - return nil, err - } - - // attempt to figure out what the user wants without a lot of verbose specificity: - // if the user specifies a default rule, assume that they probably want to fall back - // to that. Otherwise, assume that they just wanted to customize one option from the - // set, and leave the rest in the standard configuration. - if protoRt.OutputRules.Default != nil { - genRuntime.OutputRules = protoRt.OutputRules - return genRuntime, nil - } - - outRules := DirectoryPerGenerator("config", protoRt.GeneratorsByName) - for gen, rule := range protoRt.OutputRules.ByGenerator { - outRules.ByGenerator[gen] = rule - } - - genRuntime.OutputRules = outRules - return genRuntime, nil -} - -// protoFromOptions returns a proto-Runtime from the given options registry and -// options set. This can then be used to construct an actual Runtime. See the -// FromOptions function for more details about how the options work. -func protoFromOptions(optionsRegistry *markers.Registry, options []string) (protoRuntime, error) { - var gens Generators - rules := OutputRules{ - ByGenerator: make(map[*Generator]OutputRule), - } - var paths []string - - // collect the generators first, so that we can key the output on the actual - // generator, which matters if there's settings in the gen object and it's not a pointer. - outputByGen := make(map[string]OutputRule) - gensByName := make(map[string]*Generator) - - for _, rawOpt := range options { - if rawOpt[0] != '+' { - rawOpt = "+" + rawOpt // add a `+` to make it acceptable for usage with the registry - } - defn := optionsRegistry.Lookup(rawOpt, markers.DescribesPackage) - if defn == nil { - return protoRuntime{}, fmt.Errorf("unknown option %q", rawOpt[1:]) - } - - val, err := defn.Parse(rawOpt) - if err != nil { - return protoRuntime{}, fmt.Errorf("unable to parse option %q: %w", rawOpt[1:], err) - } - - switch val := val.(type) { - case Generator: - gens = append(gens, &val) - gensByName[defn.Name] = &val - case OutputRule: - _, genName := splitOutputRuleOption(defn.Name) - if genName == "" { - // it's a default rule - rules.Default = val - continue - } - - outputByGen[genName] = val - continue - case InputPaths: - paths = append(paths, val...) - default: - return protoRuntime{}, fmt.Errorf("unknown option marker %q", defn.Name) - } - } - - // actually associate the rules now that we know the generators - for genName, outputRule := range outputByGen { - gen, knownGen := gensByName[genName] - if !knownGen { - return protoRuntime{}, fmt.Errorf("non-invoked generator %q", genName) - } - - rules.ByGenerator[gen] = outputRule - } - - return protoRuntime{ - Paths: paths, - Generators: Generators(gens), - OutputRules: rules, - GeneratorsByName: gensByName, - }, nil -} - -// protoRuntime represents the raw pieces needed to compose a runtime, as -// parsed from some options. -type protoRuntime struct { - Paths []string - Generators Generators - OutputRules OutputRules - GeneratorsByName map[string]*Generator -} - -// splitOutputRuleOption splits a marker name of "output:rule:gen" or "output:rule" -// into its compontent rule and generator name. -func splitOutputRuleOption(name string) (ruleName string, genName string) { - parts := strings.SplitN(name, ":", 3) - if len(parts) == 3 { - // output:: - return parts[2], parts[1] - } - // output: - return parts[1], "" -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/output.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/output.go deleted file mode 100644 index b5a09e16..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/output.go +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package genall - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - - "sigs.k8s.io/controller-tools/pkg/loader" -) - -// nopCloser is a WriteCloser whose Close -// is a no-op. -type nopCloser struct { - io.Writer -} - -func (n nopCloser) Close() error { - return nil -} - -// DirectoryPerGenerator produces output rules mapping output to a different subdirectory -// of the given base directory for each generator (with each subdirectory specified as -// the key in the input map). -func DirectoryPerGenerator(base string, generators map[string]*Generator) OutputRules { - rules := OutputRules{ - Default: OutputArtifacts{Config: OutputToDirectory(base)}, - ByGenerator: make(map[*Generator]OutputRule, len(generators)), - } - - for name, gen := range generators { - rules.ByGenerator[gen] = OutputArtifacts{ - Config: OutputToDirectory(filepath.Join(base, name)), - } - } - - return rules -} - -// OutputRules defines how to output artificats on a per-generator basis. -type OutputRules struct { - // Default is the output rule used when no specific per-generator overrides match. - Default OutputRule - // ByGenerator contains specific per-generator overrides. - // NB(directxman12): this is a pointer to avoid issues if a given Generator becomes unhashable - // (interface values compare by "dereferencing" their internal pointer first, whereas pointers - // compare by the actual pointer itself). - ByGenerator map[*Generator]OutputRule -} - -// ForGenerator returns the output rule that should be used -// by the given Generator. -func (o OutputRules) ForGenerator(gen *Generator) OutputRule { - if forGen, specific := o.ByGenerator[gen]; specific { - return forGen - } - return o.Default -} - -// OutputRule defines how to output artifacts from a generator. -type OutputRule interface { - // Open opens the given artifact path for writing. If a package is passed, - // the artifact is considered to be used as part of the package (e.g. - // generated code), while a nil package indicates that the artifact is - // config (or something else not involved in Go compilation). - Open(pkg *loader.Package, path string) (io.WriteCloser, error) -} - -// OutputToNothing skips outputting anything. -var OutputToNothing = outputToNothing{} - -// +controllertools:marker:generateHelp:category="" - -// outputToNothing skips outputting anything. -type outputToNothing struct{} - -func (o outputToNothing) Open(_ *loader.Package, _ string) (io.WriteCloser, error) { - return nopCloser{ioutil.Discard}, nil -} - -// +controllertools:marker:generateHelp:category="" - -// OutputToDirectory outputs each artifact to the given directory, regardless -// of if it's package-associated or not. -type OutputToDirectory string - -func (o OutputToDirectory) Open(_ *loader.Package, itemPath string) (io.WriteCloser, error) { - // ensure the directory exists - if err := os.MkdirAll(string(o), os.ModePerm); err != nil { - return nil, err - } - path := filepath.Join(string(o), itemPath) - return os.Create(path) -} - -// OutputToStdout outputs everything to standard-out, with no separation. -// -// Generally useful for single-artifact outputs. -var OutputToStdout = outputToStdout{} - -// +controllertools:marker:generateHelp:category="" - -// outputToStdout outputs everything to standard-out, with no separation. -// -// Generally useful for single-artifact outputs. -type outputToStdout struct{} - -func (o outputToStdout) Open(_ *loader.Package, itemPath string) (io.WriteCloser, error) { - return nopCloser{os.Stdout}, nil -} - -// +controllertools:marker:generateHelp:category="" - -// OutputArtifacts outputs artifacts to different locations, depending on -// whether they're package-associated or not. -// -// Non-package associated artifacts -// are output to the Config directory, while package-associated ones are output -// to their package's source files' directory, unless an alternate path is -// specified in Code. -type OutputArtifacts struct { - // Config points to the directory to which to write configuration. - Config OutputToDirectory - // Code overrides the directory in which to write new code (defaults to where the existing code lives). - Code OutputToDirectory `marker:",optional"` -} - -func (o OutputArtifacts) Open(pkg *loader.Package, itemPath string) (io.WriteCloser, error) { - if pkg == nil { - return o.Config.Open(pkg, itemPath) - } - - if o.Code != "" { - return o.Code.Open(pkg, itemPath) - } - - if len(pkg.CompiledGoFiles) == 0 { - return nil, fmt.Errorf("cannot output to a package with no path on disk") - } - outDir := filepath.Dir(pkg.CompiledGoFiles[0]) - outPath := filepath.Join(outDir, itemPath) - return os.Create(outPath) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/genall/zz_generated.markerhelp.go b/vendor/sigs.k8s.io/controller-tools/pkg/genall/zz_generated.markerhelp.go deleted file mode 100644 index 6428f0ce..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/genall/zz_generated.markerhelp.go +++ /dev/null @@ -1,90 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright2019 The Kubernetes Authors. - -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. -*/ - -// Code generated by helpgen. DO NOT EDIT. - -package genall - -import ( - "sigs.k8s.io/controller-tools/pkg/markers" -) - -func (InputPaths) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "represents paths and go-style path patterns to use as package roots. ", - Details: "Multiple paths can be specified using \"{path1, path2, path3}\".", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (OutputArtifacts) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "outputs artifacts to different locations, depending on whether they're package-associated or not. ", - Details: "Non-package associated artifacts are output to the Config directory, while package-associated ones are output to their package's source files' directory, unless an alternate path is specified in Code.", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "Config": { - Summary: "points to the directory to which to write configuration.", - Details: "", - }, - "Code": { - Summary: "overrides the directory in which to write new code (defaults to where the existing code lives).", - Details: "", - }, - }, - } -} - -func (OutputToDirectory) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "outputs each artifact to the given directory, regardless of if it's package-associated or not.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (outputToNothing) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "skips outputting anything.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} - -func (outputToStdout) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "outputs everything to standard-out, with no separation. ", - Details: "Generally useful for single-artifact outputs.", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/loader/doc.go b/vendor/sigs.k8s.io/controller-tools/pkg/loader/doc.go deleted file mode 100644 index 6853c062..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/loader/doc.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// Package loader defines helpers for loading packages from sources. It wraps -// go/packages, allow incremental loading of source code and manual control -// over which packages get type-checked. This allows for faster loading in -// cases where you don't actually care about certain imports. -// -// Because it uses go/packages, it's modules-aware, and works in both modules- -// and non-modules environments. -// -// # Loading -// -// The main entrypoint for loading is LoadRoots, which traverse the package -// graph starting at the given patterns (file, package, path, or ...-wildcard, -// as one might pass to go list). Packages beyond the roots can be accessed -// via the Imports() method. Packages are initially loaded with export data -// paths, filenames, and imports. -// -// Packages are suitable for comparison, as each unique package only ever has -// one *Package object returned. -// -// # Syntax and TypeChecking -// -// ASTs and type-checking information can be loaded with NeedSyntax and -// NeedTypesInfo, respectively. Both are idempotent -- repeated calls will -// simply re-use the cached contents. Note that NeedTypesInfo will *only* type -// check the current package -- if you want to type-check imports as well, -// you'll need to type-check them first. -// -// # Reference Pruning and Recursive Checking -// -// In order to type-check using only the packages you care about, you can use a -// TypeChecker. TypeChecker will visit each top-level type declaration, -// collect (optionally filtered) references, and type-check references -// packages. -// -// # Errors -// -// Errors can be added to each package. Use ErrFromNode to create an error -// from an AST node. Errors can then be printed (complete with file and -// position information) using PrintErrors, optionally filtered by error type. -// It's generally a good idea to filter out TypeErrors when doing incomplete -// type-checking with TypeChecker. You can use MaybeErrList to return multiple -// errors if you need to return an error instead of adding it to a package. -// AddError will later unroll it into individual errors. -package loader diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/loader/errors.go b/vendor/sigs.k8s.io/controller-tools/pkg/loader/errors.go deleted file mode 100644 index 5a675798..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/loader/errors.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package loader - -import ( - "fmt" - "go/token" -) - -// PositionedError represents some error with an associated position. -// The position is tied to some external token.FileSet. -type PositionedError struct { - Pos token.Pos - error -} - -// Node is the intersection of go/ast.Node and go/types.Var. -type Node interface { - Pos() token.Pos // position of first character belonging to the node -} - -// ErrFromNode returns the given error, with additional information -// attaching it to the given AST node. It will automatically map -// over error lists. -func ErrFromNode(err error, node Node) error { - if asList, isList := err.(ErrList); isList { - resList := make(ErrList, len(asList)) - for i, baseErr := range asList { - resList[i] = ErrFromNode(baseErr, node) - } - return resList - } - return PositionedError{ - Pos: node.Pos(), - error: err, - } -} - -// MaybeErrList constructs an ErrList if the given list of -// errors has any errors, otherwise returning nil. -func MaybeErrList(errs []error) error { - if len(errs) == 0 { - return nil - } - return ErrList(errs) -} - -// ErrList is a list of errors aggregated together into a single error. -type ErrList []error - -func (l ErrList) Error() string { - return fmt.Sprintf("%v", []error(l)) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/loader/loader.go b/vendor/sigs.k8s.io/controller-tools/pkg/loader/loader.go deleted file mode 100644 index b81acab2..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/loader/loader.go +++ /dev/null @@ -1,625 +0,0 @@ -/* -Copyright 2019-2022 The Kubernetes Authors. - -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. -*/ - -package loader - -import ( - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "sync" - - "golang.org/x/tools/go/packages" - "k8s.io/apimachinery/pkg/util/sets" -) - -// Much of this is strongly inspired by the contents of go/packages, -// except that it allows for lazy loading of syntax and type-checking -// information to speed up cases where full traversal isn't needed. - -// PrintErrors print errors associated with all packages -// in the given package graph, starting at the given root -// packages and traversing through all imports. It will skip -// any errors of the kinds specified in filterKinds. It will -// return true if any errors were printed. -func PrintErrors(pkgs []*Package, filterKinds ...packages.ErrorKind) bool { - pkgsRaw := make([]*packages.Package, len(pkgs)) - for i, pkg := range pkgs { - pkgsRaw[i] = pkg.Package - } - toSkip := make(map[packages.ErrorKind]struct{}) - for _, errKind := range filterKinds { - toSkip[errKind] = struct{}{} - } - hadErrors := false - packages.Visit(pkgsRaw, nil, func(pkgRaw *packages.Package) { - for _, err := range pkgRaw.Errors { - if _, skip := toSkip[err.Kind]; skip { - continue - } - hadErrors = true - fmt.Fprintln(os.Stderr, err) - } - }) - return hadErrors -} - -// Package is a single, unique Go package that can be -// lazily parsed and type-checked. Packages should not -// be constructed directly -- instead, use LoadRoots. -// For a given call to LoadRoots, only a single instance -// of each package exists, and thus they may be used as keys -// and for comparison. -type Package struct { - *packages.Package - - imports map[string]*Package - - loader *loader - sync.Mutex -} - -// Imports returns the imports for the given package, indexed by -// package path (*not* name in any particular file). -func (p *Package) Imports() map[string]*Package { - if p.imports == nil { - p.imports = p.loader.packagesFor(p.Package.Imports) - } - - return p.imports -} - -// NeedTypesInfo indicates that type-checking information is needed for this package. -// Actual type-checking information can be accessed via the Types and TypesInfo fields. -func (p *Package) NeedTypesInfo() { - if p.TypesInfo != nil { - return - } - p.NeedSyntax() - p.loader.typeCheck(p) -} - -// NeedSyntax indicates that a parsed AST is needed for this package. -// Actual ASTs can be accessed via the Syntax field. -func (p *Package) NeedSyntax() { - if p.Syntax != nil { - return - } - out := make([]*ast.File, len(p.CompiledGoFiles)) - var wg sync.WaitGroup - wg.Add(len(p.CompiledGoFiles)) - for i, filename := range p.CompiledGoFiles { - go func(i int, filename string) { - defer wg.Done() - src, err := ioutil.ReadFile(filename) - if err != nil { - p.AddError(err) - return - } - out[i], err = p.loader.parseFile(filename, src) - if err != nil { - p.AddError(err) - return - } - }(i, filename) - } - wg.Wait() - for _, file := range out { - if file == nil { - return - } - } - p.Syntax = out -} - -// AddError adds an error to the errors associated with the given package. -func (p *Package) AddError(err error) { - switch typedErr := err.(type) { - case *os.PathError: - // file-reading errors - p.Errors = append(p.Errors, packages.Error{ - Pos: typedErr.Path + ":1", - Msg: typedErr.Err.Error(), - Kind: packages.ParseError, - }) - case scanner.ErrorList: - // parsing/scanning errors - for _, subErr := range typedErr { - p.Errors = append(p.Errors, packages.Error{ - Pos: subErr.Pos.String(), - Msg: subErr.Msg, - Kind: packages.ParseError, - }) - } - case types.Error: - // type-checking errors - p.Errors = append(p.Errors, packages.Error{ - Pos: typedErr.Fset.Position(typedErr.Pos).String(), - Msg: typedErr.Msg, - Kind: packages.TypeError, - }) - case ErrList: - for _, subErr := range typedErr { - p.AddError(subErr) - } - case PositionedError: - p.Errors = append(p.Errors, packages.Error{ - Pos: p.loader.cfg.Fset.Position(typedErr.Pos).String(), - Msg: typedErr.Error(), - Kind: packages.UnknownError, - }) - default: - // should only happen for external errors, like ref checking - p.Errors = append(p.Errors, packages.Error{ - Pos: p.ID + ":-", - Msg: err.Error(), - Kind: packages.UnknownError, - }) - } -} - -// loader loads packages and their imports. Loaded packages will have -// type size, imports, and exports file information populated. Additional -// information, like ASTs and type-checking information, can be accessed -// via methods on individual packages. -type loader struct { - // Roots are the loaded "root" packages in the package graph loaded via - // LoadRoots. - Roots []*Package - - // cfg contains the package loading config (initialized on demand) - cfg *packages.Config - // packages contains the cache of Packages indexed by the underlying - // package.Package, so that we don't ever produce two Packages with - // the same underlying packages.Package. - packages map[*packages.Package]*Package - packagesMu sync.Mutex -} - -// packageFor returns a wrapped Package for the given packages.Package, -// ensuring that there's a one-to-one mapping between the two. -// It's *not* threadsafe -- use packagesFor for that. -func (l *loader) packageFor(pkgRaw *packages.Package) *Package { - if l.packages[pkgRaw] == nil { - l.packages[pkgRaw] = &Package{ - Package: pkgRaw, - loader: l, - } - } - return l.packages[pkgRaw] -} - -// packagesFor returns a map of Package objects for each packages.Package in the input -// map, ensuring that there's a one-to-one mapping between package.Package and Package -// (as per packageFor). -func (l *loader) packagesFor(pkgsRaw map[string]*packages.Package) map[string]*Package { - l.packagesMu.Lock() - defer l.packagesMu.Unlock() - - out := make(map[string]*Package, len(pkgsRaw)) - for name, rawPkg := range pkgsRaw { - out[name] = l.packageFor(rawPkg) - } - return out -} - -// typeCheck type-checks the given package. -func (l *loader) typeCheck(pkg *Package) { - // don't conflict with typeCheckFromExportData - - pkg.TypesInfo = &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - } - - pkg.Fset = l.cfg.Fset - pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name) - - importer := importerFunc(func(path string) (*types.Package, error) { - if path == "unsafe" { - return types.Unsafe, nil - } - - // The imports map is keyed by import path. - importedPkg := pkg.Imports()[path] - if importedPkg == nil { - return nil, fmt.Errorf("package %q possibly creates an import loop", path) - } - - // it's possible to have a call to check in parallel to a call to this - // if one package in the package graph gets its dependency filtered out, - // but another doesn't (so one wants a "placeholder" package here, and another - // wants the full check). - // - // Thus, we need to lock here (at least for the time being) to avoid - // races between the above write to `pkg.Types` and this checking of - // importedPkg.Types. - importedPkg.Lock() - defer importedPkg.Unlock() - - if importedPkg.Types != nil && importedPkg.Types.Complete() { - return importedPkg.Types, nil - } - - // if we haven't already loaded typecheck data, we don't care about this package's types - return types.NewPackage(importedPkg.PkgPath, importedPkg.Name), nil - }) - - var errs []error - - // type-check - checkConfig := &types.Config{ - Importer: importer, - - IgnoreFuncBodies: true, // we only need decl-level info - - Error: func(err error) { - errs = append(errs, err) - }, - - Sizes: pkg.TypesSizes, - } - if err := types.NewChecker(checkConfig, l.cfg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax); err != nil { - errs = append(errs, err) - } - - // make sure that if a given sub-import is ill-typed, we mark this package as ill-typed as well. - illTyped := len(errs) > 0 - if !illTyped { - for _, importedPkg := range pkg.Imports() { - if importedPkg.IllTyped { - illTyped = true - break - } - } - } - pkg.IllTyped = illTyped - - // publish errors to the package error list. - for _, err := range errs { - pkg.AddError(err) - } -} - -// parseFile parses the given file, including comments. -func (l *loader) parseFile(filename string, src []byte) (*ast.File, error) { - // skip function bodies - file, err := parser.ParseFile(l.cfg.Fset, filename, src, parser.AllErrors|parser.ParseComments) - if err != nil { - return nil, err - } - - return file, nil -} - -// LoadRoots loads the given "root" packages by path, transitively loading -// and all imports as well. -// -// Loaded packages will have type size, imports, and exports file information -// populated. Additional information, like ASTs and type-checking information, -// can be accessed via methods on individual packages. -func LoadRoots(roots ...string) ([]*Package, error) { - return LoadRootsWithConfig(&packages.Config{}, roots...) -} - -// LoadRootsWithConfig functions like LoadRoots, except that it allows passing -// a custom loading config. The config will be modified to suit the needs of -// the loader. -// -// This is generally only useful for use in testing when you need to modify -// loading settings to load from a fake location. -// -// This function will traverse Go module boundaries for roots that are file- -// system paths and end with "...". Please note this feature currently only -// supports roots that are filesystem paths. For more information, please -// refer to the high-level outline of this function's logic: -// -// 1. If no roots are provided then load the working directory and return -// early. -// -// 2. Otherwise sort the provided roots into two, distinct buckets: -// -// a. package/module names -// b. filesystem paths -// -// A filesystem path is distinguished from a Go package/module name by -// the same rules as followed by the "go" command. At a high level, a -// root is a filesystem path IFF it meets ANY of the following criteria: -// -// * is absolute -// * begins with . -// * begins with .. -// -// For more information please refer to the output of the command -// "go help packages". -// -// 3. Load the package/module roots as a single call to packages.Load. If -// there are no filesystem path roots then return early. -// -// 4. For filesystem path roots ending with "...", check to see if its -// descendants include any nested, Go modules. If so, add the directory -// that contains the nested Go module to the filesystem path roots. -// -// 5. Load the filesystem path roots and return the load packages for the -// package/module roots AND the filesystem path roots. -func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, error) { - l := &loader{ - cfg: cfg, - packages: make(map[*packages.Package]*Package), - } - l.cfg.Mode |= packages.LoadImports | packages.NeedTypesSizes - if l.cfg.Fset == nil { - l.cfg.Fset = token.NewFileSet() - } - // put our build flags first so that callers can override them - l.cfg.BuildFlags = append([]string{"-tags", "ignore_autogenerated"}, l.cfg.BuildFlags...) - - // Visit the import graphs of the loaded, root packages. If an imported - // package refers to another loaded, root package, then replace the - // instance of the imported package with a reference to the loaded, root - // package. This is required to make kubebuilder markers work correctly - // when multiple root paths are loaded and types from one path reference - // types from another root path. - defer func() { - for i := range l.Roots { - visitImports(l.Roots, l.Roots[i], nil) - } - }() - - // uniquePkgIDs is used to keep track of the discovered packages to be nice - // and try and prevent packages from showing up twice when nested module - // support is enabled. there is not harm that comes from this per se, but - // it makes testing easier when a known number of modules can be asserted - uniquePkgIDs := sets.String{} - - // loadPackages returns the Go packages for the provided roots - // - // if validatePkgFn is nil, a package will be returned in the slice, - // otherwise the package is only returned if the result of - // validatePkgFn(pkg.ID) is truthy - loadPackages := func(roots ...string) ([]*Package, error) { - rawPkgs, err := packages.Load(l.cfg, roots...) - if err != nil { - return nil, err - } - var pkgs []*Package - for _, rp := range rawPkgs { - p := l.packageFor(rp) - if !uniquePkgIDs.Has(p.ID) { - pkgs = append(pkgs, p) - uniquePkgIDs.Insert(p.ID) - } - } - return pkgs, nil - } - - // if no roots were provided then load the current package and return early - if len(roots) == 0 { - pkgs, err := loadPackages() - if err != nil { - return nil, err - } - l.Roots = append(l.Roots, pkgs...) - return l.Roots, nil - } - - // pkgRoots is a slice of roots that are package/modules and fspRoots - // is a slice of roots that are local filesystem paths. - // - // please refer to this function's godoc comments for more information on - // how these two types of roots are distinguished from one another - var ( - pkgRoots []string - fspRoots []string - fspRootRx = regexp.MustCompile(`^\.{1,2}`) - ) - for _, r := range roots { - if filepath.IsAbs(r) || fspRootRx.MatchString(r) { - fspRoots = append(fspRoots, r) - } else { - pkgRoots = append(pkgRoots, r) - } - } - - // handle the package roots by sending them into the packages.Load function - // all at once. this is more efficient, but cannot be used for the file- - // system path roots due to them needing a custom, calculated value for the - // cfg.Dir field - if len(pkgRoots) > 0 { - pkgs, err := loadPackages(pkgRoots...) - if err != nil { - return nil, err - } - l.Roots = append(l.Roots, pkgs...) - } - - // if there are no filesystem path roots then go ahead and return early - if len(fspRoots) == 0 { - return l.Roots, nil - } - - // - // at this point we are handling filesystem path roots - // - - // ensure the cfg.Dir field is reset to its original value upon - // returning from this function. it should honestly be fine if it is - // not given most callers will not send in the cfg parameter directly, - // as it's largely for testing, but still, let's be good stewards. - defer func(d string) { - cfg.Dir = d - }(cfg.Dir) - - // store the value of cfg.Dir so we can use it later if it is non-empty. - // we need to store it now as the value of cfg.Dir will be updated by - // a loop below - cfgDir := cfg.Dir - - // addNestedGoModulesToRoots is given to filepath.WalkDir and adds the - // directory part of p to the list of filesystem path roots IFF p is the - // path to a file named "go.mod" - addNestedGoModulesToRoots := func( - p string, - d os.DirEntry, - e error) error { - - if e != nil { - return e - } - if !d.IsDir() && filepath.Base(p) == "go.mod" { - fspRoots = append(fspRoots, filepath.Join(filepath.Dir(p), "...")) - } - return nil - } - - // in the first pass over the filesystem path roots we: - // - // 1. make the root into an absolute path - // - // 2. check to see if a root uses the nested path syntax, ex. ... - // - // 3. if so, walk the root's descendants, searching for any nested Go - // modules - // - // 4. if found then the directory containing the Go module is added to - // the list of the filesystem path roots - for i := range fspRoots { - r := fspRoots[i] - - // clean up the root - r = filepath.Clean(r) - - // get the absolute path of the root - if !filepath.IsAbs(r) { - - // if the initial value of cfg.Dir was non-empty then use it when - // building the absolute path to this root. otherwise use the - // filepath.Abs function to get the absolute path of the root based - // on the working directory - if cfgDir != "" { - r = filepath.Join(cfgDir, r) - } else { - ar, err := filepath.Abs(r) - if err != nil { - return nil, err - } - r = ar - } - } - - // update the root to be an absolute path - fspRoots[i] = r - - b, d := filepath.Base(r), filepath.Dir(r) - - // if the base element is "..." then it means nested traversal is - // activated. this can be passed directly to the loader. however, if - // specified we also want to traverse the path manually to determine if - // there are any nested Go modules we want to add to the list of file- - // system path roots to process - if b == "..." { - if err := filepath.WalkDir( - d, - addNestedGoModulesToRoots); err != nil { - - return nil, err - } - } - } - - // in the second pass over the filesystem path roots we: - // - // 1. determine the directory from which to execute the loader - // - // 2. update the loader config's Dir property to be the directory from - // step one - // - // 3. determine whether the root passed to the loader should be "./." - // or "./..." - // - // 4. execute the loader with the value from step three - for _, r := range fspRoots { - b, d := filepath.Base(r), filepath.Dir(r) - - // we want the base part of the path to be either "..." or ".", except - // Go's filepath utilities clean paths during manipulation, removing the - // ".". thus, if not "...", let's update the path components so that: - // - // d = r - // b = "." - if b != "..." { - d = r - b = "." - } - - // update the loader configuration's Dir field to the directory part of - // the root - l.cfg.Dir = d - - // update the root to be "./..." or "./." - // (with OS-specific filepath separator). please note filepath.Join - // would clean up the trailing "." character that we want preserved, - // hence the more manual path concatenation logic - r = fmt.Sprintf(".%s%s", string(filepath.Separator), b) - - // load the packages from the roots - pkgs, err := loadPackages(r) - if err != nil { - return nil, err - } - l.Roots = append(l.Roots, pkgs...) - } - - return l.Roots, nil -} - -// visitImports walks a dependency graph, replacing imported package -// references with those from the rootPkgs list. This ensures the -// kubebuilder marker generation is handled correctly. For more info, -// please see issue 680. -func visitImports(rootPkgs []*Package, pkg *Package, seen sets.String) { - if seen == nil { - seen = sets.String{} - } - for importedPkgID, importedPkg := range pkg.Imports() { - for i := range rootPkgs { - if importedPkgID == rootPkgs[i].ID { - pkg.imports[importedPkgID] = rootPkgs[i] - } - } - if !seen.Has(importedPkgID) { - seen.Insert(importedPkgID) - visitImports(rootPkgs, importedPkg, seen) - } - } -} - -// importFunc is an implementation of the single-method -// types.Importer interface based on a function value. -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/loader/paths.go b/vendor/sigs.k8s.io/controller-tools/pkg/loader/paths.go deleted file mode 100644 index 3b783e16..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/loader/paths.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package loader - -import ( - "strings" -) - -// NonVendorPath returns a package path that does not include anything before the -// last vendor directory. This is useful for when using vendor directories, -// and using go/types.Package.Path(), which returns the full path including vendor. -// -// If you're using this, make sure you really need it -- it's better to index by -// the actual Package object when you can. -func NonVendorPath(rawPath string) string { - parts := strings.Split(rawPath, "/vendor/") - return parts[len(parts)-1] -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/loader/refs.go b/vendor/sigs.k8s.io/controller-tools/pkg/loader/refs.go deleted file mode 100644 index 37c3295f..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/loader/refs.go +++ /dev/null @@ -1,273 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package loader - -import ( - "fmt" - - "go/ast" - "strconv" - "sync" -) - -// NB(directxman12): most of this is done by the typechecker, -// but it's a bit slow/heavyweight for what we want -- we want -// to resolve external imports *only* if we actually need them. - -// Basically, what we do is: -// 1. Map imports to names -// 2. Find all explicit external references (`name.type`) -// 3. Find all referenced packages by merging explicit references and dot imports -// 4. Only type-check those packages -// 5. Ignore type-checking errors from the missing packages, because we won't ever -// touch unloaded types (they're probably used in ignored fields/types, variables, or functions) -// (done using PrintErrors with an ignore argument from the caller). -// 6. Notice any actual type-checking errors via invalid types - -// importsMap saves import aliases, mapping them to underlying packages. -type importsMap struct { - // dotImports maps package IDs to packages for any packages that have/ been imported as `.` - dotImports map[string]*Package - // byName maps package aliases or names to the underlying package. - byName map[string]*Package -} - -// mapImports maps imports from the names they use in the given file to the underlying package, -// using a map of package import paths to packages (generally from Package.Imports()). -func mapImports(file *ast.File, importedPkgs map[string]*Package) (*importsMap, error) { - m := &importsMap{ - dotImports: make(map[string]*Package), - byName: make(map[string]*Package), - } - for _, importSpec := range file.Imports { - path, err := strconv.Unquote(importSpec.Path.Value) - if err != nil { - return nil, ErrFromNode(err, importSpec.Path) - } - importedPkg := importedPkgs[path] - if importedPkg == nil { - return nil, ErrFromNode(fmt.Errorf("no such package located"), importSpec.Path) - } - if importSpec.Name == nil { - m.byName[importedPkg.Name] = importedPkg - continue - } - if importSpec.Name.Name == "." { - m.dotImports[importedPkg.ID] = importedPkg - continue - } - m.byName[importSpec.Name.Name] = importedPkg - } - - return m, nil -} - -// referenceSet finds references to external packages' types in the given file, -// without otherwise calling into the type-checker. When checking structs, -// it only checks fields with JSON tags. -type referenceSet struct { - file *ast.File - imports *importsMap - pkg *Package - - externalRefs map[*Package]struct{} -} - -func (r *referenceSet) init() { - if r.externalRefs == nil { - r.externalRefs = make(map[*Package]struct{}) - } -} - -// NodeFilter filters nodes, accepting them for reference collection -// when true is returned and rejecting them when false is returned. -type NodeFilter func(ast.Node) bool - -// collectReferences saves all references to external types in the given info. -func (r *referenceSet) collectReferences(rawType ast.Expr, filterNode NodeFilter) { - r.init() - col := &referenceCollector{ - refs: r, - filterNode: filterNode, - } - ast.Walk(col, rawType) -} - -// external saves an external reference to the given named package. -func (r *referenceSet) external(pkgName string) { - pkg := r.imports.byName[pkgName] - if pkg == nil { - r.pkg.AddError(fmt.Errorf("use of unimported package %q", pkgName)) - return - } - r.externalRefs[pkg] = struct{}{} -} - -// referenceCollector visits nodes in an AST, adding external references to a -// referenceSet. -type referenceCollector struct { - refs *referenceSet - filterNode NodeFilter -} - -func (c *referenceCollector) Visit(node ast.Node) ast.Visitor { - if !c.filterNode(node) { - return nil - } - switch typedNode := node.(type) { - case *ast.Ident: - // local reference or dot-import, ignore - return nil - case *ast.SelectorExpr: - switch x := typedNode.X.(type) { - case *ast.Ident: - pkgName := x.Name - c.refs.external(pkgName) - return nil - default: - return c - } - default: - return c - } -} - -// allReferencedPackages finds all directly referenced packages in the given package. -func allReferencedPackages(pkg *Package, filterNodes NodeFilter) []*Package { - pkg.NeedSyntax() - refsByFile := make(map[*ast.File]*referenceSet) - for _, file := range pkg.Syntax { - imports, err := mapImports(file, pkg.Imports()) - if err != nil { - pkg.AddError(err) - return nil - } - refs := &referenceSet{ - file: file, - imports: imports, - pkg: pkg, - } - refsByFile[file] = refs - } - - EachType(pkg, func(file *ast.File, decl *ast.GenDecl, spec *ast.TypeSpec) { - refs := refsByFile[file] - refs.collectReferences(spec.Type, filterNodes) - }) - - allPackages := make(map[*Package]struct{}) - for _, refs := range refsByFile { - for _, pkg := range refs.imports.dotImports { - allPackages[pkg] = struct{}{} - } - for ref := range refs.externalRefs { - allPackages[ref] = struct{}{} - } - } - - res := make([]*Package, 0, len(allPackages)) - for pkg := range allPackages { - res = append(res, pkg) - } - return res -} - -// TypeChecker performs type-checking on a limitted subset of packages by -// checking each package's types' externally-referenced types, and only -// type-checking those packages. -type TypeChecker struct { - // NodeFilters are used to filter the set of references that are followed - // when typechecking. If any of the filters returns true for a given node, - // its package will be added to the set of packages to check. - // - // If no filters are specified, all references are followed (this may be slow). - // - // Modifying this after the first call to check may yield strange/invalid - // results. - NodeFilters []NodeFilter - - checkedPackages map[*Package]struct{} - sync.Mutex -} - -// Check type-checks the given package and all packages referenced by types -// that pass through (have true returned by) any of the NodeFilters. -func (c *TypeChecker) Check(root *Package) { - c.init() - - // use a sub-checker with the appropriate settings - (&TypeChecker{ - NodeFilters: c.NodeFilters, - checkedPackages: c.checkedPackages, - }).check(root) -} - -func (c *TypeChecker) isNodeInteresting(node ast.Node) bool { - // no filters --> everything is important - if len(c.NodeFilters) == 0 { - return true - } - - // otherwise, passing through any one filter means this node is important - for _, filter := range c.NodeFilters { - if filter(node) { - return true - } - } - return false -} - -func (c *TypeChecker) init() { - if c.checkedPackages == nil { - c.checkedPackages = make(map[*Package]struct{}) - } -} - -// check recursively type-checks the given package, only loading packages that -// are actually referenced by our types (it's the actual implementation of Check, -// without initialization). -func (c *TypeChecker) check(root *Package) { - root.Lock() - defer root.Unlock() - - c.Lock() - _, ok := c.checkedPackages[root] - c.Unlock() - if ok { - return - } - - refedPackages := allReferencedPackages(root, c.isNodeInteresting) - - // first, resolve imports for all leaf packages... - var wg sync.WaitGroup - for _, pkg := range refedPackages { - wg.Add(1) - go func(pkg *Package) { - defer wg.Done() - c.check(pkg) - }(pkg) - } - wg.Wait() - - // ...then, we can safely type-check ourself - root.NeedTypesInfo() - - c.Lock() - defer c.Unlock() - c.checkedPackages[root] = struct{}{} -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/loader/visit.go b/vendor/sigs.k8s.io/controller-tools/pkg/loader/visit.go deleted file mode 100644 index b5646fde..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/loader/visit.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package loader - -import ( - "go/ast" - "reflect" - "strconv" -) - -// TypeCallback is a callback called for each raw AST (gendecl, typespec) combo. -type TypeCallback func(file *ast.File, decl *ast.GenDecl, spec *ast.TypeSpec) - -// EachType calls the given callback for each (gendecl, typespec) combo in the -// given package. Generally, using markers.EachType is better when working -// with marker data, and has a more convinient representation. -func EachType(pkg *Package, cb TypeCallback) { - visitor := &typeVisitor{ - callback: cb, - } - pkg.NeedSyntax() - for _, file := range pkg.Syntax { - visitor.file = file - ast.Walk(visitor, file) - } -} - -// typeVisitor visits all TypeSpecs, calling the given callback for each. -type typeVisitor struct { - callback TypeCallback - decl *ast.GenDecl - file *ast.File -} - -// Visit visits all TypeSpecs. -func (v *typeVisitor) Visit(node ast.Node) ast.Visitor { - if node == nil { - v.decl = nil - return v - } - - switch typedNode := node.(type) { - case *ast.File: - v.file = typedNode - return v - case *ast.GenDecl: - v.decl = typedNode - return v - case *ast.TypeSpec: - v.callback(v.file, v.decl, typedNode) - return nil // don't recurse - default: - return nil - } -} - -// ParseAstTag parses the given raw tag literal into a reflect.StructTag. -func ParseAstTag(tag *ast.BasicLit) reflect.StructTag { - if tag == nil { - return reflect.StructTag("") - } - tagStr, err := strconv.Unquote(tag.Value) - if err != nil { - return reflect.StructTag("") - } - return reflect.StructTag(tagStr) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/markers/collect.go b/vendor/sigs.k8s.io/controller-tools/pkg/markers/collect.go deleted file mode 100644 index b2f82199..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/markers/collect.go +++ /dev/null @@ -1,422 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "go/ast" - "go/token" - "strings" - "sync" - - "sigs.k8s.io/controller-tools/pkg/loader" -) - -// Collector collects and parses marker comments defined in the registry -// from package source code. If no registry is provided, an empty one will -// be initialized on the first call to MarkersInPackage. -type Collector struct { - *Registry - - byPackage map[string]map[ast.Node]MarkerValues - mu sync.Mutex -} - -// MarkerValues are all the values for some set of markers. -type MarkerValues map[string][]interface{} - -// Get fetches the first value that for the given marker, returning -// nil if no values are available. -func (v MarkerValues) Get(name string) interface{} { - vals := v[name] - if len(vals) == 0 { - return nil - } - return vals[0] -} - -func (c *Collector) init() { - if c.Registry == nil { - c.Registry = &Registry{} - } - if c.byPackage == nil { - c.byPackage = make(map[string]map[ast.Node]MarkerValues) - } -} - -// MarkersInPackage computes the marker values by node for the given package. Results -// are cached by package ID, so this is safe to call repeatedly from different functions. -// Each file in the package is treated as a distinct node. -// -// We consider a marker to be associated with a given AST node if either of the following are true: -// -// - it's in the Godoc for that AST node -// -// - it's in the closest non-godoc comment group above that node, -// *and* that node is a type or field node, *and* [it's either -// registered as type-level *or* it's not registered as being -// package-level] -// -// - it's not in the Godoc of a node, doesn't meet the above criteria, and -// isn't in a struct definition (in which case it's package-level) -func (c *Collector) MarkersInPackage(pkg *loader.Package) (map[ast.Node]MarkerValues, error) { - c.mu.Lock() - c.init() - if markers, exist := c.byPackage[pkg.ID]; exist { - c.mu.Unlock() - return markers, nil - } - // unlock early, it's ok if we do a bit extra work rather than locking while we're working - c.mu.Unlock() - - pkg.NeedSyntax() - nodeMarkersRaw := c.associatePkgMarkers(pkg) - markers, err := c.parseMarkersInPackage(nodeMarkersRaw) - if err != nil { - return nil, err - } - - c.mu.Lock() - defer c.mu.Unlock() - c.byPackage[pkg.ID] = markers - - return markers, nil -} - -// parseMarkersInPackage parses the given raw marker comments into output values using the registry. -func (c *Collector) parseMarkersInPackage(nodeMarkersRaw map[ast.Node][]markerComment) (map[ast.Node]MarkerValues, error) { - var errors []error - nodeMarkerValues := make(map[ast.Node]MarkerValues) - for node, markersRaw := range nodeMarkersRaw { - var target TargetType - switch node.(type) { - case *ast.File: - target = DescribesPackage - case *ast.Field: - target = DescribesField - default: - target = DescribesType - } - markerVals := make(map[string][]interface{}) - for _, markerRaw := range markersRaw { - markerText := markerRaw.Text() - def := c.Registry.Lookup(markerText, target) - if def == nil { - continue - } - val, err := def.Parse(markerText) - if err != nil { - errors = append(errors, loader.ErrFromNode(err, markerRaw)) - continue - } - markerVals[def.Name] = append(markerVals[def.Name], val) - } - nodeMarkerValues[node] = markerVals - } - - return nodeMarkerValues, loader.MaybeErrList(errors) -} - -// associatePkgMarkers associates markers with AST nodes in the given package. -func (c *Collector) associatePkgMarkers(pkg *loader.Package) map[ast.Node][]markerComment { - nodeMarkers := make(map[ast.Node][]markerComment) - for _, file := range pkg.Syntax { - fileNodeMarkers := c.associateFileMarkers(file) - for node, markers := range fileNodeMarkers { - nodeMarkers[node] = append(nodeMarkers[node], markers...) - } - } - - return nodeMarkers -} - -// associateFileMarkers associates markers with AST nodes in the given file. -func (c *Collector) associateFileMarkers(file *ast.File) map[ast.Node][]markerComment { - // grab all the raw marker comments by node - visitor := markerSubVisitor{ - collectPackageLevel: true, - markerVisitor: &markerVisitor{ - nodeMarkers: make(map[ast.Node][]markerComment), - allComments: file.Comments, - }, - } - ast.Walk(visitor, file) - - // grab the last package-level comments at the end of the file (if any) - lastFileMarkers := visitor.markersBetween(false, visitor.commentInd, len(visitor.allComments)) - visitor.pkgMarkers = append(visitor.pkgMarkers, lastFileMarkers...) - - // figure out if any type-level markers are actually package-level markers - for node, markers := range visitor.nodeMarkers { - _, isType := node.(*ast.TypeSpec) - if !isType { - continue - } - endOfMarkers := 0 - for _, marker := range markers { - if marker.fromGodoc { - // markers from godoc are never package level - markers[endOfMarkers] = marker - endOfMarkers++ - continue - } - markerText := marker.Text() - typeDef := c.Registry.Lookup(markerText, DescribesType) - if typeDef != nil { - // prefer assuming type-level markers - markers[endOfMarkers] = marker - endOfMarkers++ - continue - } - def := c.Registry.Lookup(markerText, DescribesPackage) - if def == nil { - // assume type-level unless proven otherwise - markers[endOfMarkers] = marker - endOfMarkers++ - continue - } - // it's package-level, since a package-level definition exists - visitor.pkgMarkers = append(visitor.pkgMarkers, marker) - } - visitor.nodeMarkers[node] = markers[:endOfMarkers] // re-set after trimming the package markers - } - visitor.nodeMarkers[file] = visitor.pkgMarkers - - return visitor.nodeMarkers -} - -// markerComment is an AST comment that contains a marker. -// It may or may not be from a Godoc comment, which affects -// marker re-associated (from type-level to package-level) -type markerComment struct { - *ast.Comment - fromGodoc bool -} - -// Text returns the text of the marker, stripped of the comment -// marker and leading spaces, as should be passed to Registry.Lookup -// and Registry.Parse. -func (c markerComment) Text() string { - return strings.TrimSpace(c.Comment.Text[2:]) -} - -// markerVisistor visits AST nodes, recording markers associated with each node. -type markerVisitor struct { - allComments []*ast.CommentGroup - commentInd int - - declComments []markerComment - lastLineCommentGroup *ast.CommentGroup - - pkgMarkers []markerComment - nodeMarkers map[ast.Node][]markerComment -} - -// isMarkerComment checks that the given comment is a single-line (`//`) -// comment and it's first non-space content is `+`. -func isMarkerComment(comment string) bool { - if comment[0:2] != "//" { - return false - } - stripped := strings.TrimSpace(comment[2:]) - if len(stripped) < 1 || stripped[0] != '+' { - return false - } - return true -} - -// markersBetween grabs the markers between the given indicies in the list of all comments. -func (v *markerVisitor) markersBetween(fromGodoc bool, start, end int) []markerComment { - if start < 0 || end < 0 { - return nil - } - var res []markerComment - for i := start; i < end; i++ { - commentGroup := v.allComments[i] - for _, comment := range commentGroup.List { - if !isMarkerComment(comment.Text) { - continue - } - res = append(res, markerComment{Comment: comment, fromGodoc: fromGodoc}) - } - } - return res -} - -type markerSubVisitor struct { - *markerVisitor - node ast.Node - collectPackageLevel bool -} - -// Visit collects markers for each node in the AST, optionally -// collecting unassociated markers as package-level. -func (v markerSubVisitor) Visit(node ast.Node) ast.Visitor { - if node == nil { - // end of the node, so we might need to advance comments beyond the end - // of the block if we don't want to collect package-level markers in - // this block. - - if !v.collectPackageLevel { - if v.commentInd < len(v.allComments) { - lastCommentInd := v.commentInd - nextGroup := v.allComments[lastCommentInd] - for nextGroup.Pos() < v.node.End() { - lastCommentInd++ - if lastCommentInd >= len(v.allComments) { - // after the increment so our decrement below still makes sense - break - } - nextGroup = v.allComments[lastCommentInd] - } - v.commentInd = lastCommentInd - } - } - - return nil - } - - // skip comments on the same line as the previous node - // making sure to double-check for the case where we've gone past the end of the comments - // but still have to finish up typespec-gendecl association (see below). - if v.lastLineCommentGroup != nil && v.commentInd < len(v.allComments) && v.lastLineCommentGroup.Pos() == v.allComments[v.commentInd].Pos() { - v.commentInd++ - } - - // stop visiting if there are no more comments in the file - // NB(directxman12): we can't just stop immediately, because we - // still need to check if there are typespecs associated with gendecls. - var markerCommentBlock []markerComment - var docCommentBlock []markerComment - lastCommentInd := v.commentInd - if v.commentInd < len(v.allComments) { - // figure out the first comment after the node in question... - nextGroup := v.allComments[lastCommentInd] - for nextGroup.Pos() < node.Pos() { - lastCommentInd++ - if lastCommentInd >= len(v.allComments) { - // after the increment so our decrement below still makes sense - break - } - nextGroup = v.allComments[lastCommentInd] - } - lastCommentInd-- // ...then decrement to get the last comment before the node in question - - // figure out the godoc comment so we can deal with it separately - var docGroup *ast.CommentGroup - docGroup, v.lastLineCommentGroup = associatedCommentsFor(node) - - // find the last comment group that's not godoc - markerCommentInd := lastCommentInd - if docGroup != nil && v.allComments[markerCommentInd].Pos() == docGroup.Pos() { - markerCommentInd-- - } - - // check if we have freestanding package markers, - // and find the markers in our "closest non-godoc" comment block, - // plus our godoc comment block - if markerCommentInd >= v.commentInd { - if v.collectPackageLevel { - // assume anything between the comment ind and the marker ind (not including it) - // are package-level - v.pkgMarkers = append(v.pkgMarkers, v.markersBetween(false, v.commentInd, markerCommentInd)...) - } - markerCommentBlock = v.markersBetween(false, markerCommentInd, markerCommentInd+1) - docCommentBlock = v.markersBetween(true, markerCommentInd+1, lastCommentInd+1) - } else { - docCommentBlock = v.markersBetween(true, markerCommentInd+1, lastCommentInd+1) - } - } - - resVisitor := markerSubVisitor{ - collectPackageLevel: false, // don't collect package level by default - markerVisitor: v.markerVisitor, - node: node, - } - - // associate those markers with a node - switch typedNode := node.(type) { - case *ast.GenDecl: - // save the comments associated with the gen-decl if it's a single-line type decl - if typedNode.Lparen != token.NoPos || typedNode.Tok != token.TYPE { - // not a single-line type spec, treat them as free comments - v.pkgMarkers = append(v.pkgMarkers, markerCommentBlock...) - break - } - // save these, we'll need them when we encounter the actual type spec - v.declComments = append(v.declComments, markerCommentBlock...) - v.declComments = append(v.declComments, docCommentBlock...) - case *ast.TypeSpec: - // add in comments attributed to the gen-decl, if any, - // as well as comments associated with the actual type - v.nodeMarkers[node] = append(v.nodeMarkers[node], v.declComments...) - v.nodeMarkers[node] = append(v.nodeMarkers[node], markerCommentBlock...) - v.nodeMarkers[node] = append(v.nodeMarkers[node], docCommentBlock...) - - v.declComments = nil - v.collectPackageLevel = false // don't collect package-level inside type structs - case *ast.Field: - v.nodeMarkers[node] = append(v.nodeMarkers[node], markerCommentBlock...) - v.nodeMarkers[node] = append(v.nodeMarkers[node], docCommentBlock...) - case *ast.File: - v.pkgMarkers = append(v.pkgMarkers, markerCommentBlock...) - v.pkgMarkers = append(v.pkgMarkers, docCommentBlock...) - - // collect markers in root file scope - resVisitor.collectPackageLevel = true - default: - // assume markers before anything else are package-level markers, - // *but* don't include any markers in godoc - if v.collectPackageLevel { - v.pkgMarkers = append(v.pkgMarkers, markerCommentBlock...) - } - } - - // increment the comment ind so that we start at the right place for the next node - v.commentInd = lastCommentInd + 1 - - return resVisitor - -} - -// associatedCommentsFor returns the doc comment group (if relevant and present) and end-of-line comment -// (again if relevant and present) for the given AST node. -func associatedCommentsFor(node ast.Node) (docGroup *ast.CommentGroup, lastLineCommentGroup *ast.CommentGroup) { - switch typedNode := node.(type) { - case *ast.Field: - docGroup = typedNode.Doc - lastLineCommentGroup = typedNode.Comment - case *ast.File: - docGroup = typedNode.Doc - case *ast.FuncDecl: - docGroup = typedNode.Doc - case *ast.GenDecl: - docGroup = typedNode.Doc - case *ast.ImportSpec: - docGroup = typedNode.Doc - lastLineCommentGroup = typedNode.Comment - case *ast.TypeSpec: - docGroup = typedNode.Doc - lastLineCommentGroup = typedNode.Comment - case *ast.ValueSpec: - docGroup = typedNode.Doc - lastLineCommentGroup = typedNode.Comment - default: - lastLineCommentGroup = nil - } - - return docGroup, lastLineCommentGroup -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/markers/doc.go b/vendor/sigs.k8s.io/controller-tools/pkg/markers/doc.go deleted file mode 100644 index ab6947cc..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/markers/doc.go +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// Package markers contains utilities for defining and parsing "marker -// comments", also occasionally called tag comments (we use the term marker to -// avoid confusing with struct tags). Parsed result (output) values take the -// form of Go values, much like the "encoding/json" package. -// -// # Definitions and Parsing -// -// Markers are defined as structured Definitions which can be used to -// consistently parse marker comments. A Definition contains an concrete -// output type for the marker, which can be a simple type (like string), a -// struct, or a wrapper type (useful for defining additional methods on marker -// types). -// -// Markers take the general form -// -// +path:to:marker=val -// -// +path:to:marker:arg1=val,arg2=val2 -// -// +path:to:marker -// -// Arguments may be ints, bools, strings, and slices. Ints and bool take their -// standard form from Go. Strings may take any of their standard forms, or any -// sequence of unquoted characters up until a `,` or `;` is encountered. Lists -// take either of the following forms: -// -// val;val;val -// -// {val, val, val} -// -// Note that the first form will not properly parse nested slices, but is -// generally convenient and is the form used in many existing markers. -// -// Each of those argument types maps to the corresponding go type. Pointers -// mark optional fields (a struct tag, below, may also be used). The empty -// interface will match any type. -// -// Struct fields may optionally be annotated with the `marker` struct tag. The -// first argument is a name override. If it's left blank (or the tag isn't -// present), the camelCase version of the name will be used. The only -// additional argument defined is `optional`, which marks a field as optional -// without using a pointer. -// -// All parsed values are unmarshalled into the output type. If any -// non-optional fields aren't mentioned, an error will be raised unless -// `Strict` is set to false. -// -// # Registries and Lookup -// -// Definitions can be added to registries to facilitate lookups. Each -// definition is marked as either describing a type, struct field, or package -// (unassociated). The same marker name may be registered multiple times, as -// long as each describes a different construct (type, field, or package). -// Definitions can then be looked up by passing unparsed markers. -// -// # Collection and Extraction -// -// Markers can be collected from a loader.Package using a Collector. The -// Collector will read from a given Registry, collecting comments that look -// like markers and parsing them if they match some definition on the registry. -// -// Markers are considered associated with a particular field or type if they -// exist in the Godoc, or the closest non-godoc comment. Any other markers not -// inside a some other block (e.g. a struct definition, interface definition, -// etc) are considered package level. Markers in a "closest non-Go comment -// block" may also be considered package level if registered as such and no -// identical type-level definition exists. -// -// Like loader.Package, Collector's methods are idempotent and will not -// reperform work. -// -// # Traversal -// -// EachType function iterates over each type in a Package, providing -// conveniently structured type and field information with marker values -// associated. -// -// PackageMarkers can be used to fetch just package-level markers. -// -// # Help -// -// Help can be defined for each marker using the DefinitionHelp struct. It's -// mostly intended to be generated off of godocs using cmd/helpgen, which takes -// the first line as summary (removing the type/field name), and considers the -// rest as details. It looks for the -// -// +controllertools:generateHelp[:category=] -// -// marker to start generation. -// -// If you can't use godoc-based generation for whatever reasons (e.g. -// primitive-typed markers), you can use the SimpleHelp and DeprecatedHelp -// helper functions to generate help structs. -// -// Help is then registered into a registry as associated with the actual -// definition, and can then be later retrieved from the registry. -package markers diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/markers/help.go b/vendor/sigs.k8s.io/controller-tools/pkg/markers/help.go deleted file mode 100644 index 26ca059b..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/markers/help.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -// You *probably* don't want to write these structs by hand -// -- use cmd/helpgen if you can write Godoc, and {Simple,Deprecated}Help -// otherwise. - -// DetailedHelp contains brief help, as well as more details. -// For the "full" help, join the two together. -type DetailedHelp struct { - Summary string - Details string -} - -// DefinitionHelp contains overall help for a marker Definition, -// as well as per-field help. -type DefinitionHelp struct { - // DetailedHelp contains the overall help for the marker. - DetailedHelp - // Category describes what kind of marker this is. - Category string - // DeprecatedInFavorOf marks the marker as deprecated. - // If non-nil & empty, it's assumed to just mean deprecated permanently. - // If non-empty, it's assumed to be a marker name. - DeprecatedInFavorOf *string - - // NB(directxman12): we make FieldHelp be in terms of the Go struct field - // names so that we don't have to know the conversion or processing rules - // for struct fields at compile-time for help generation. - - // FieldHelp defines the per-field help for this marker, *in terms of the - // go struct field names. Use the FieldsHelp method to map this to - // marker argument names. - FieldHelp map[string]DetailedHelp -} - -// FieldsHelp maps per-field help to the actual marker argument names from the -// given definition. -func (d *DefinitionHelp) FieldsHelp(def *Definition) map[string]DetailedHelp { - fieldsHelp := make(map[string]DetailedHelp, len(def.FieldNames)) - for fieldName, argName := range def.FieldNames { - fieldsHelp[fieldName] = d.FieldHelp[argName] - } - return fieldsHelp -} - -// SimpleHelp returns help that just has marker-level summary information -// (e.g. for use with empty or primitive-typed markers, where Godoc-based -// generation isn't possible). -func SimpleHelp(category, summary string) *DefinitionHelp { - return &DefinitionHelp{ - Category: category, - DetailedHelp: DetailedHelp{Summary: summary}, - } -} - -// DeprecatedHelp returns simple help (a la SimpleHelp), except marked as -// deprecated in favor of the given marker (or an empty string for just -// deprecated). -func DeprecatedHelp(inFavorOf, category, summary string) *DefinitionHelp { - return &DefinitionHelp{ - Category: category, - DetailedHelp: DetailedHelp{Summary: summary}, - DeprecatedInFavorOf: &inFavorOf, - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/markers/parse.go b/vendor/sigs.k8s.io/controller-tools/pkg/markers/parse.go deleted file mode 100644 index 3e1d75a8..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/markers/parse.go +++ /dev/null @@ -1,963 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "strings" - sc "text/scanner" - "unicode" - - "sigs.k8s.io/controller-tools/pkg/loader" -) - -// expect checks that the next token of the scanner is the given token, adding an error -// to the scanner if not. It returns whether the token was as expected. -func expect(scanner *sc.Scanner, expected rune, errDesc string) bool { - tok := scanner.Scan() - if tok != expected { - scanner.Error(scanner, fmt.Sprintf("expected %s, got %q", errDesc, scanner.TokenText())) - return false - } - return true -} - -// peekNoSpace is equivalent to scanner.Peek, except that it will consume intervening whitespace. -func peekNoSpace(scanner *sc.Scanner) rune { - hint := scanner.Peek() - for ; hint <= rune(' ') && ((1<") - case IntType: - out.WriteString("int") - case NumberType: - out.WriteString("float64") - case StringType: - out.WriteString("string") - case BoolType: - out.WriteString("bool") - case AnyType: - out.WriteString("") - case SliceType: - out.WriteString("[]") - // arguments can't be non-pointer optional, so just call into typeString again. - a.ItemType.typeString(out) - case MapType: - out.WriteString("map[string]") - a.ItemType.typeString(out) - case RawType: - out.WriteString("") - } -} - -// TypeString returns a string roughly equivalent -// (but not identical) to the underlying Go type that -// this argument would parse to. It's mainly useful -// for user-friendly formatting of this argument (e.g. -// help strings). -func (a Argument) TypeString() string { - out := &strings.Builder{} - a.typeString(out) - return out.String() -} - -func (a Argument) String() string { - if a.Optional { - return fmt.Sprintf("", a.TypeString()) - } - return fmt.Sprintf("", a.TypeString()) -} - -// castAndSet casts val to out's type if needed, -// then sets out to val. -func castAndSet(out, val reflect.Value) { - outType := out.Type() - if outType != val.Type() { - val = val.Convert(outType) - } - out.Set(val) -} - -// makeSliceType makes a reflect.Type for a slice of the given type. -// Useful for constructing the out value for when AnyType's guess returns a slice. -func makeSliceType(itemType Argument) (reflect.Type, error) { - var itemReflectedType reflect.Type - switch itemType.Type { - case IntType: - itemReflectedType = reflect.TypeOf(int(0)) - case NumberType: - itemReflectedType = reflect.TypeOf(float64(0)) - case StringType: - itemReflectedType = reflect.TypeOf("") - case BoolType: - itemReflectedType = reflect.TypeOf(false) - case SliceType: - subItemType, err := makeSliceType(*itemType.ItemType) - if err != nil { - return nil, err - } - itemReflectedType = subItemType - case MapType: - subItemType, err := makeMapType(*itemType.ItemType) - if err != nil { - return nil, err - } - itemReflectedType = subItemType - // TODO(directxman12): support non-uniform slices? (probably not) - default: - return nil, fmt.Errorf("invalid type when constructing guessed slice out: %v", itemType.Type) - } - - if itemType.Pointer { - itemReflectedType = reflect.PtrTo(itemReflectedType) - } - - return reflect.SliceOf(itemReflectedType), nil -} - -// makeMapType makes a reflect.Type for a map of the given item type. -// Useful for constructing the out value for when AnyType's guess returns a map. -func makeMapType(itemType Argument) (reflect.Type, error) { - var itemReflectedType reflect.Type - switch itemType.Type { - case IntType: - itemReflectedType = reflect.TypeOf(int(0)) - case NumberType: - itemReflectedType = reflect.TypeOf(float64(0)) - case StringType: - itemReflectedType = reflect.TypeOf("") - case BoolType: - itemReflectedType = reflect.TypeOf(false) - case SliceType: - subItemType, err := makeSliceType(*itemType.ItemType) - if err != nil { - return nil, err - } - itemReflectedType = subItemType - // TODO(directxman12): support non-uniform slices? (probably not) - case MapType: - subItemType, err := makeMapType(*itemType.ItemType) - if err != nil { - return nil, err - } - itemReflectedType = subItemType - case AnyType: - // NB(directxman12): maps explicitly allow non-uniform item types, unlike slices at the moment - itemReflectedType = interfaceType - default: - return nil, fmt.Errorf("invalid type when constructing guessed slice out: %v", itemType.Type) - } - - if itemType.Pointer { - itemReflectedType = reflect.PtrTo(itemReflectedType) - } - - return reflect.MapOf(reflect.TypeOf(""), itemReflectedType), nil -} - -// guessType takes an educated guess about the type of the next field. If allowSlice -// is false, it will not guess slices. It's less efficient than parsing with actual -// type information, since we need to allocate to peek ahead full tokens, and the scanner -// only allows peeking ahead one character. -// Maps are *always* non-uniform (i.e. type the AnyType item type), since they're frequently -// used to represent things like defaults for an object in JSON. -func guessType(scanner *sc.Scanner, raw string, allowSlice bool) *Argument { - if allowSlice { - maybeItem := guessType(scanner, raw, false) - - subRaw := raw[scanner.Pos().Offset:] - subScanner := parserScanner(subRaw, scanner.Error) - - var tok rune - for tok = subScanner.Scan(); tok != ',' && tok != sc.EOF && tok != ';'; tok = subScanner.Scan() { - // wait till we get something interesting - } - - // semicolon means it's a legacy slice - if tok == ';' { - return &Argument{ - Type: SliceType, - ItemType: maybeItem, - } - } - - return maybeItem - } - - // everything else needs a duplicate scanner to scan properly - // (so we don't consume our scanner tokens until we actually - // go to use this -- Go doesn't like scanners that can be rewound). - subRaw := raw[scanner.Pos().Offset:] - subScanner := parserScanner(subRaw, scanner.Error) - - // skip whitespace - hint := peekNoSpace(subScanner) - - // first, try the easy case -- quoted strings strings - switch hint { - case '"', '\'', '`': - return &Argument{Type: StringType} - } - - // next, check for slices or maps - if hint == '{' { - subScanner.Scan() - - // TODO(directxman12): this can't guess at empty objects, but that's generally ok. - // We'll cross that bridge when we get there. - - // look ahead till we can figure out if this is a map or a slice - firstElemType := guessType(subScanner, subRaw, false) - if firstElemType.Type == StringType { - // might be a map or slice, parse the string and check for colon - // (blech, basically arbitrary look-ahead due to raw strings). - var keyVal string // just ignore this - (&Argument{Type: StringType}).parseString(subScanner, raw, reflect.Indirect(reflect.ValueOf(&keyVal))) - - if subScanner.Scan() == ':' { - // it's got a string followed by a colon -- it's a map - return &Argument{ - Type: MapType, - ItemType: &Argument{Type: AnyType}, - } - } - } - - // definitely a slice -- maps have to have string keys and have a value followed by a colon - return &Argument{ - Type: SliceType, - ItemType: firstElemType, - } - } - - // then, bools... - probablyString := false - if hint == 't' || hint == 'f' { - // maybe a bool - if nextTok := subScanner.Scan(); nextTok == sc.Ident { - switch subScanner.TokenText() { - case "true", "false": - // definitely a bool - return &Argument{Type: BoolType} - } - // probably a string - probablyString = true - } else { - // we shouldn't ever get here - scanner.Error(scanner, fmt.Sprintf("got a token (%q) that looked like an ident, but was not", scanner.TokenText())) - return &Argument{Type: InvalidType} - } - } - - // then, integers... - if !probablyString { - nextTok := subScanner.Scan() - if nextTok == '-' { - nextTok = subScanner.Scan() - } - - if nextTok == sc.Int { - return &Argument{Type: IntType} - } - if nextTok == sc.Float { - return &Argument{Type: NumberType} - } - } - - // otherwise assume bare strings - return &Argument{Type: StringType} -} - -// parseString parses either of the two accepted string forms (quoted, or bare tokens). -func (a *Argument) parseString(scanner *sc.Scanner, raw string, out reflect.Value) { - // strings are a bit weird -- the "easy" case is quoted strings (tokenized as strings), - // the "hard" case (present for backwards compat) is a bare sequence of tokens that aren't - // a comma. - tok := scanner.Scan() - if tok == sc.String || tok == sc.RawString { - // the easy case - val, err := strconv.Unquote(scanner.TokenText()) - if err != nil { - scanner.Error(scanner, fmt.Sprintf("unable to parse string: %v", err)) - return - } - castAndSet(out, reflect.ValueOf(val)) - return - } - - // the "hard" case -- bare tokens not including ',' (the argument - // separator), ';' (the slice separator), ':' (the map separator), or '}' - // (delimitted slice ender) - startPos := scanner.Position.Offset - for hint := peekNoSpace(scanner); hint != ',' && hint != ';' && hint != ':' && hint != '}' && hint != sc.EOF; hint = peekNoSpace(scanner) { - // skip this token - scanner.Scan() - } - endPos := scanner.Position.Offset + len(scanner.TokenText()) - castAndSet(out, reflect.ValueOf(raw[startPos:endPos])) -} - -// parseSlice parses either of the two slice forms (curly-brace-delimitted and semicolon-separated). -func (a *Argument) parseSlice(scanner *sc.Scanner, raw string, out reflect.Value) { - // slices have two supported formats, like string: - // - `{val, val, val}` (preferred) - // - `val;val;val` (legacy) - resSlice := reflect.Zero(out.Type()) - elem := reflect.Indirect(reflect.New(out.Type().Elem())) - - // preferred case - if peekNoSpace(scanner) == '{' { - // NB(directxman12): supporting delimitted slices in bare slices - // would require an extra look-ahead here :-/ - - scanner.Scan() // skip '{' - for hint := peekNoSpace(scanner); hint != '}' && hint != sc.EOF; hint = peekNoSpace(scanner) { - a.ItemType.parse(scanner, raw, elem, true /* parsing a slice */) - resSlice = reflect.Append(resSlice, elem) - tok := peekNoSpace(scanner) - if tok == '}' { - break - } - if !expect(scanner, ',', "comma") { - return - } - } - if !expect(scanner, '}', "close curly brace") { - return - } - castAndSet(out, resSlice) - return - } - - // legacy case - for hint := peekNoSpace(scanner); hint != ',' && hint != '}' && hint != sc.EOF; hint = peekNoSpace(scanner) { - a.ItemType.parse(scanner, raw, elem, true /* parsing a slice */) - resSlice = reflect.Append(resSlice, elem) - tok := peekNoSpace(scanner) - if tok == ',' || tok == '}' || tok == sc.EOF { - break - } - scanner.Scan() - if tok != ';' { - scanner.Error(scanner, fmt.Sprintf("expected comma, got %q", scanner.TokenText())) - return - } - } - castAndSet(out, resSlice) -} - -// parseMap parses a map of the form {string: val, string: val, string: val} -func (a *Argument) parseMap(scanner *sc.Scanner, raw string, out reflect.Value) { - resMap := reflect.MakeMap(out.Type()) - elem := reflect.Indirect(reflect.New(out.Type().Elem())) - key := reflect.Indirect(reflect.New(out.Type().Key())) - - if !expect(scanner, '{', "open curly brace") { - return - } - - for hint := peekNoSpace(scanner); hint != '}' && hint != sc.EOF; hint = peekNoSpace(scanner) { - a.parseString(scanner, raw, key) - if !expect(scanner, ':', "colon") { - return - } - a.ItemType.parse(scanner, raw, elem, false /* not in a slice */) - resMap.SetMapIndex(key, elem) - - if peekNoSpace(scanner) == '}' { - break - } - if !expect(scanner, ',', "comma") { - return - } - } - - if !expect(scanner, '}', "close curly brace") { - return - } - - castAndSet(out, resMap) -} - -// parse functions like Parse, except that it allows passing down whether or not we're -// already in a slice, to avoid duplicate legacy slice detection for AnyType -func (a *Argument) parse(scanner *sc.Scanner, raw string, out reflect.Value, inSlice bool) { - // nolint:gocyclo - if a.Type == InvalidType { - scanner.Error(scanner, "cannot parse invalid type") - return - } - if a.Pointer { - out.Set(reflect.New(out.Type().Elem())) - out = reflect.Indirect(out) - } - switch a.Type { - case RawType: - // raw consumes everything else - castAndSet(out, reflect.ValueOf(raw[scanner.Pos().Offset:])) - // consume everything else - for tok := scanner.Scan(); tok != sc.EOF; tok = scanner.Scan() { - } - case NumberType: - nextChar := scanner.Peek() - isNegative := false - if nextChar == '-' { - isNegative = true - scanner.Scan() // eat the '-' - } - - tok := scanner.Scan() - if tok != sc.Float && tok != sc.Int { - scanner.Error(scanner, fmt.Sprintf("expected integer or float, got %q", scanner.TokenText())) - return - } - - text := scanner.TokenText() - if isNegative { - text = "-" + text - } - - val, err := strconv.ParseFloat(text, 64) - if err != nil { - scanner.Error(scanner, fmt.Sprintf("unable to parse number: %v", err)) - return - } - - castAndSet(out, reflect.ValueOf(val)) - case IntType: - nextChar := scanner.Peek() - isNegative := false - if nextChar == '-' { - isNegative = true - scanner.Scan() // eat the '-' - } - if !expect(scanner, sc.Int, "integer") { - return - } - // TODO(directxman12): respect the size when parsing - text := scanner.TokenText() - if isNegative { - text = "-" + text - } - val, err := strconv.Atoi(text) - if err != nil { - scanner.Error(scanner, fmt.Sprintf("unable to parse integer: %v", err)) - return - } - castAndSet(out, reflect.ValueOf(val)) - case StringType: - // strings are a bit weird -- the "easy" case is quoted strings (tokenized as strings), - // the "hard" case (present for backwards compat) is a bare sequence of tokens that aren't - // a comma. - a.parseString(scanner, raw, out) - case BoolType: - if !expect(scanner, sc.Ident, "true or false") { - return - } - switch scanner.TokenText() { - case "true": - castAndSet(out, reflect.ValueOf(true)) - case "false": - castAndSet(out, reflect.ValueOf(false)) - default: - scanner.Error(scanner, fmt.Sprintf("expected true or false, got %q", scanner.TokenText())) - return - } - case AnyType: - guessedType := guessType(scanner, raw, !inSlice) - newOut := out - - // we need to be able to construct the right element types, below - // in parse, so construct a concretely-typed value to use as "out" - switch guessedType.Type { - case SliceType: - newType, err := makeSliceType(*guessedType.ItemType) - if err != nil { - scanner.Error(scanner, err.Error()) - return - } - newOut = reflect.Indirect(reflect.New(newType)) - case MapType: - newType, err := makeMapType(*guessedType.ItemType) - if err != nil { - scanner.Error(scanner, err.Error()) - return - } - newOut = reflect.Indirect(reflect.New(newType)) - } - if !newOut.CanSet() { - panic("at the disco") // TODO(directxman12): this is left over from debugging -- it might need to be an error - } - guessedType.Parse(scanner, raw, newOut) - castAndSet(out, newOut) - case SliceType: - // slices have two supported formats, like string: - // - `{val, val, val}` (preferred) - // - `val;val;val` (legacy) - a.parseSlice(scanner, raw, out) - case MapType: - // maps are {string: val, string: val, string: val} - a.parseMap(scanner, raw, out) - } -} - -// Parse attempts to consume the argument from the given scanner (based on the given -// raw input as well for collecting ranges of content), and places the output value -// in the given reflect.Value. Errors are reported via the given scanner. -func (a *Argument) Parse(scanner *sc.Scanner, raw string, out reflect.Value) { - a.parse(scanner, raw, out, false) -} - -// ArgumentFromType constructs an Argument by examining the given -// raw reflect.Type. It can construct arguments from the Go types -// corresponding to any of the types listed in ArgumentType. -func ArgumentFromType(rawType reflect.Type) (Argument, error) { - if rawType == rawArgsType { - return Argument{ - Type: RawType, - }, nil - } - - if rawType == interfaceType { - return Argument{ - Type: AnyType, - }, nil - } - - arg := Argument{} - if rawType.Kind() == reflect.Ptr { - rawType = rawType.Elem() - arg.Pointer = true - arg.Optional = true - } - - switch rawType.Kind() { - case reflect.String: - arg.Type = StringType - case reflect.Int, reflect.Int32: // NB(directxman12): all ints in kubernetes are int32, so explicitly support that - arg.Type = IntType - case reflect.Float64: - arg.Type = NumberType - case reflect.Bool: - arg.Type = BoolType - case reflect.Slice: - arg.Type = SliceType - itemType, err := ArgumentFromType(rawType.Elem()) - if err != nil { - return Argument{}, fmt.Errorf("bad slice item type: %w", err) - } - arg.ItemType = &itemType - case reflect.Map: - arg.Type = MapType - if rawType.Key().Kind() != reflect.String { - return Argument{}, fmt.Errorf("bad map key type: map keys must be strings") - } - itemType, err := ArgumentFromType(rawType.Elem()) - if err != nil { - return Argument{}, fmt.Errorf("bad slice item type: %w", err) - } - arg.ItemType = &itemType - default: - return Argument{}, fmt.Errorf("type has unsupported kind %s", rawType.Kind()) - } - - return arg, nil -} - -// TargetType describes which kind of node a given marker is associated with. -type TargetType int - -const ( - // DescribesPackage indicates that a marker is associated with a package. - DescribesPackage TargetType = iota - // DescribesType indicates that a marker is associated with a type declaration. - DescribesType - // DescribesField indicates that a marker is associated with a struct field. - DescribesField -) - -func (t TargetType) String() string { - switch t { - case DescribesPackage: - return "package" - case DescribesType: - return "type" - case DescribesField: - return "field" - default: - return "(unknown)" - } -} - -// Definition is a parsed definition of a marker. -type Definition struct { - // Output is the deserialized Go type of the marker. - Output reflect.Type - // Name is the marker's name. - Name string - // Target indicates which kind of node this marker can be associated with. - Target TargetType - // Fields lists out the types of each field that this marker has, by - // argument name as used in the marker (if the output type isn't a struct, - // it'll have a single, blank field name). This only lists exported fields, - // (as per reflection rules). - Fields map[string]Argument - // FieldNames maps argument names (as used in the marker) to struct field name - // in the output type. - FieldNames map[string]string - // Strict indicates that this definition should error out when parsing if - // not all non-optional fields were seen. - Strict bool -} - -// AnonymousField indicates that the definition has one field, -// (actually the original object), and thus the field -// doesn't get named as part of the name. -func (d *Definition) AnonymousField() bool { - if len(d.Fields) != 1 { - return false - } - _, hasAnonField := d.Fields[""] - return hasAnonField -} - -// Empty indicates that this definition has no fields. -func (d *Definition) Empty() bool { - return len(d.Fields) == 0 -} - -// argumentInfo returns information about an argument field as the marker parser's field loader -// would see it. This can be useful if you have to interact with marker definition structs -// externally (e.g. at compile time). -func argumentInfo(fieldName string, tag reflect.StructTag) (argName string, optionalOpt bool) { - argName = lowerCamelCase(fieldName) - markerTag, tagSpecified := tag.Lookup("marker") - markerTagParts := strings.Split(markerTag, ",") - if tagSpecified && markerTagParts[0] != "" { - // allow overriding to support legacy cases where we don't follow camelCase conventions - argName = markerTagParts[0] - } - optionalOpt = false - for _, tagOption := range markerTagParts[1:] { - switch tagOption { - case "optional": - optionalOpt = true - } - } - - return argName, optionalOpt -} - -// loadFields uses reflection to populate argument information from the Output type. -func (d *Definition) loadFields() error { - if d.Fields == nil { - d.Fields = make(map[string]Argument) - d.FieldNames = make(map[string]string) - } - if d.Output.Kind() != reflect.Struct { - // anonymous field type - argType, err := ArgumentFromType(d.Output) - if err != nil { - return err - } - d.Fields[""] = argType - d.FieldNames[""] = "" - return nil - } - - for i := 0; i < d.Output.NumField(); i++ { - field := d.Output.Field(i) - if field.PkgPath != "" { - // as per the reflect package docs, pkgpath is empty for exported fields, - // so non-empty package path means a private field, which we should skip - continue - } - argName, optionalOpt := argumentInfo(field.Name, field.Tag) - - argType, err := ArgumentFromType(field.Type) - if err != nil { - return fmt.Errorf("unable to extract type information for field %q: %w", field.Name, err) - } - - if argType.Type == RawType { - return fmt.Errorf("RawArguments must be the direct type of a marker, and not a field") - } - - argType.Optional = optionalOpt || argType.Optional - - d.Fields[argName] = argType - d.FieldNames[argName] = field.Name - } - - return nil -} - -// parserScanner makes a new scanner appropriate for use in parsing definitions and arguments. -func parserScanner(raw string, err func(*sc.Scanner, string)) *sc.Scanner { - scanner := &sc.Scanner{} - scanner.Init(bytes.NewBufferString(raw)) - scanner.Mode = sc.ScanIdents | sc.ScanInts | sc.ScanFloats | sc.ScanStrings | sc.ScanRawStrings | sc.SkipComments - scanner.Error = err - - return scanner -} - -// Parse uses the type information in this Definition to parse the given -// raw marker in the form `+a:b:c=arg,d=arg` into an output object of the -// type specified in the definition. -func (d *Definition) Parse(rawMarker string) (interface{}, error) { - name, anonName, fields := splitMarker(rawMarker) - - out := reflect.Indirect(reflect.New(d.Output)) - - // if we're a not a struct or have no arguments, treat the full `a:b:c` as the name, - // otherwise, treat `c` as a field name, and `a:b` as the marker name. - if !d.AnonymousField() && !d.Empty() && len(anonName) >= len(name)+1 { - fields = anonName[len(name)+1:] + "=" + fields - } - - var errs []error - scanner := parserScanner(fields, func(scanner *sc.Scanner, msg string) { - errs = append(errs, &ScannerError{Msg: msg, Pos: scanner.Position}) - }) - - // TODO(directxman12): strict parsing where we error out if certain fields aren't optional - seen := make(map[string]struct{}, len(d.Fields)) - if d.AnonymousField() && scanner.Peek() != sc.EOF { - // might still be a struct that something fiddled with, so double check - structFieldName := d.FieldNames[""] - outTarget := out - if structFieldName != "" { - // it's a struct field mapped to an anonymous marker - outTarget = out.FieldByName(structFieldName) - if !outTarget.CanSet() { - scanner.Error(scanner, fmt.Sprintf("cannot set field %q (might not exist)", structFieldName)) - return out.Interface(), loader.MaybeErrList(errs) - } - } - - // no need for trying to parse field names if we're not a struct - field := d.Fields[""] - field.Parse(scanner, fields, outTarget) - seen[""] = struct{}{} // mark as seen for strict definitions - } else if !d.Empty() && scanner.Peek() != sc.EOF { - // if we expect *and* actually have arguments passed - for { - // parse the argument name - if !expect(scanner, sc.Ident, "argument name") { - break - } - argName := scanner.TokenText() - if !expect(scanner, '=', "equals") { - break - } - - // make sure we know the field - fieldName, known := d.FieldNames[argName] - if !known { - scanner.Error(scanner, fmt.Sprintf("unknown argument %q", argName)) - break - } - fieldType, known := d.Fields[argName] - if !known { - scanner.Error(scanner, fmt.Sprintf("unknown argument %q", argName)) - break - } - seen[argName] = struct{}{} // mark as seen for strict definitions - - // parse the field value - fieldVal := out.FieldByName(fieldName) - if !fieldVal.CanSet() { - scanner.Error(scanner, fmt.Sprintf("cannot set field %q (might not exist)", fieldName)) - break - } - fieldType.Parse(scanner, fields, fieldVal) - - if len(errs) > 0 { - break - } - - if scanner.Peek() == sc.EOF { - break - } - if !expect(scanner, ',', "comma") { - break - } - } - } - - if tok := scanner.Scan(); tok != sc.EOF { - scanner.Error(scanner, fmt.Sprintf("extra arguments provided: %q", fields[scanner.Position.Offset:])) - } - - if d.Strict { - for argName, arg := range d.Fields { - if _, wasSeen := seen[argName]; !wasSeen && !arg.Optional { - scanner.Error(scanner, fmt.Sprintf("missing argument %q", argName)) - } - } - } - - return out.Interface(), loader.MaybeErrList(errs) -} - -// MakeDefinition constructs a definition from a name, type, and the output type. -// All such definitions are strict by default. If a struct is passed as the output -// type, its public fields will automatically be populated into Fields (and similar -// fields in Definition). Other values will have a single, empty-string-named Fields -// entry. -func MakeDefinition(name string, target TargetType, output interface{}) (*Definition, error) { - def := &Definition{ - Name: name, - Target: target, - Output: reflect.TypeOf(output), - Strict: true, - } - - if err := def.loadFields(); err != nil { - return nil, err - } - - return def, nil -} - -// MakeAnyTypeDefinition constructs a definition for an output struct with a -// field named `Value` of type `interface{}`. The argument to the marker will -// be parsed as AnyType and assigned to the field named `Value`. -func MakeAnyTypeDefinition(name string, target TargetType, output interface{}) (*Definition, error) { - defn, err := MakeDefinition(name, target, output) - if err != nil { - return nil, err - } - defn.FieldNames = map[string]string{"": "Value"} - defn.Fields = map[string]Argument{"": defn.Fields["value"]} - return defn, nil -} - -// splitMarker takes a marker in the form of `+a:b:c=arg,d=arg` and splits it -// into the name (`a:b`), the name if it's not a struct (`a:b:c`), and the parts -// that are definitely fields (`arg,d=arg`). -func splitMarker(raw string) (name string, anonymousName string, restFields string) { - raw = raw[1:] // get rid of the leading '+' - nameFieldParts := strings.SplitN(raw, "=", 2) - if len(nameFieldParts) == 1 { - return nameFieldParts[0], nameFieldParts[0], "" - } - anonymousName = nameFieldParts[0] - name = anonymousName - restFields = nameFieldParts[1] - - nameParts := strings.Split(name, ":") - if len(nameParts) > 1 { - name = strings.Join(nameParts[:len(nameParts)-1], ":") - } - return name, anonymousName, restFields -} - -type ScannerError struct { - Msg string - Pos sc.Position -} - -func (e *ScannerError) Error() string { - return fmt.Sprintf("%s (at %s)", e.Msg, e.Pos) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/markers/reg.go b/vendor/sigs.k8s.io/controller-tools/pkg/markers/reg.go deleted file mode 100644 index 7dcd4589..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/markers/reg.go +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "fmt" - "sync" -) - -// Registry keeps track of registered definitions, and allows for easy lookup. -// It's thread-safe, and the zero-value can be safely used. -type Registry struct { - forPkg map[string]*Definition - forType map[string]*Definition - forField map[string]*Definition - helpFor map[*Definition]*DefinitionHelp - - mu sync.RWMutex - initOnce sync.Once -} - -func (r *Registry) init() { - r.initOnce.Do(func() { - if r.forPkg == nil { - r.forPkg = make(map[string]*Definition) - } - if r.forType == nil { - r.forType = make(map[string]*Definition) - } - if r.forField == nil { - r.forField = make(map[string]*Definition) - } - if r.helpFor == nil { - r.helpFor = make(map[*Definition]*DefinitionHelp) - } - }) -} - -// Define defines a new marker with the given name, target, and output type. -// It's a shortcut around -// -// r.Register(MakeDefinition(name, target, obj)) -func (r *Registry) Define(name string, target TargetType, obj interface{}) error { - def, err := MakeDefinition(name, target, obj) - if err != nil { - return err - } - return r.Register(def) -} - -// Register registers the given marker definition with this registry for later lookup. -func (r *Registry) Register(def *Definition) error { - r.init() - - r.mu.Lock() - defer r.mu.Unlock() - - switch def.Target { - case DescribesPackage: - r.forPkg[def.Name] = def - case DescribesType: - r.forType[def.Name] = def - case DescribesField: - r.forField[def.Name] = def - default: - return fmt.Errorf("unknown target type %v", def.Target) - } - return nil -} - -// AddHelp stores the given help in the registry, marking it as associated with -// the given definition. -func (r *Registry) AddHelp(def *Definition, help *DefinitionHelp) { - r.init() - - r.mu.Lock() - defer r.mu.Unlock() - - r.helpFor[def] = help -} - -// Lookup fetches the definition corresponding to the given name and target type. -func (r *Registry) Lookup(name string, target TargetType) *Definition { - r.init() - - r.mu.RLock() - defer r.mu.RUnlock() - - switch target { - case DescribesPackage: - return tryAnonLookup(name, r.forPkg) - case DescribesType: - return tryAnonLookup(name, r.forType) - case DescribesField: - return tryAnonLookup(name, r.forField) - default: - return nil - } -} - -// HelpFor fetches the help for a given definition, if present. -func (r *Registry) HelpFor(def *Definition) *DefinitionHelp { - r.init() - - r.mu.RLock() - defer r.mu.RUnlock() - - return r.helpFor[def] -} - -// AllDefinitions returns all marker definitions known to this registry. -func (r *Registry) AllDefinitions() []*Definition { - res := make([]*Definition, 0, len(r.forPkg)+len(r.forType)+len(r.forField)) - for _, def := range r.forPkg { - res = append(res, def) - } - for _, def := range r.forType { - res = append(res, def) - } - for _, def := range r.forField { - res = append(res, def) - } - return res -} - -// tryAnonLookup tries looking up the given marker as both an struct-based -// marker and an anonymous marker, returning whichever format matches first, -// preferring the longer (anonymous) name in case of conflicts. -func tryAnonLookup(name string, defs map[string]*Definition) *Definition { - // NB(directxman12): we look up anonymous names first to work with - // legacy style marker definitions that have a namespaced approach - // (e.g. deepcopy-gen, which uses `+k8s:deepcopy-gen=foo,bar` *and* - // `+k8s.io:deepcopy-gen:interfaces=foo`). - name, anonName, _ := splitMarker(name) - if def, exists := defs[anonName]; exists { - return def - } - - return defs[name] -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/markers/regutil.go b/vendor/sigs.k8s.io/controller-tools/pkg/markers/regutil.go deleted file mode 100644 index a9160c3c..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/markers/regutil.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -// Must panics on errors creating definitions. -func Must(def *Definition, err error) *Definition { - if err != nil { - panic(err) - } - return def -} - -// RegisterAll attempts to register all definitions against the given registry, -// stopping and returning if an error occurs. -func RegisterAll(reg *Registry, defs ...*Definition) error { - for _, def := range defs { - if err := reg.Register(def); err != nil { - return err - } - } - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/markers/zip.go b/vendor/sigs.k8s.io/controller-tools/pkg/markers/zip.go deleted file mode 100644 index b352eded..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/markers/zip.go +++ /dev/null @@ -1,201 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package markers - -import ( - "go/ast" - "go/token" - "reflect" - "strings" - - "sigs.k8s.io/controller-tools/pkg/loader" -) - -// extractDoc extracts documentation from the given node, skipping markers -// in the godoc and falling back to the decl if necessary (for single-line decls). -func extractDoc(node ast.Node, decl *ast.GenDecl) string { - var docs *ast.CommentGroup - switch docced := node.(type) { - case *ast.Field: - docs = docced.Doc - case *ast.File: - docs = docced.Doc - case *ast.GenDecl: - docs = docced.Doc - case *ast.TypeSpec: - docs = docced.Doc - // type Ident expr expressions get docs attached to the decl, - // so check for that case (missing Lparen == single line type decl) - if docs == nil && decl.Lparen == token.NoPos { - docs = decl.Doc - } - } - - if docs == nil { - return "" - } - - // filter out markers - var outGroup ast.CommentGroup - outGroup.List = make([]*ast.Comment, 0, len(docs.List)) - for _, comment := range docs.List { - if isMarkerComment(comment.Text) { - continue - } - outGroup.List = append(outGroup.List, comment) - } - - // split lines, and re-join together as a single - // paragraph, respecting double-newlines as - // paragraph markers. - outLines := strings.Split(outGroup.Text(), "\n") - if outLines[len(outLines)-1] == "" { - // chop off the extraneous last part - outLines = outLines[:len(outLines)-1] - } - - for i, line := range outLines { - // Trim any extranous whitespace, - // for handling /*…*/-style comments, - // which have whitespace preserved in go/ast: - line = strings.TrimSpace(line) - - // Respect that double-newline means - // actual newline: - if line == "" { - outLines[i] = "\n" - } else { - outLines[i] = line - } - } - - return strings.Join(outLines, " ") -} - -// PackageMarkers collects all the package-level marker values for the given package. -func PackageMarkers(col *Collector, pkg *loader.Package) (MarkerValues, error) { - markers, err := col.MarkersInPackage(pkg) - if err != nil { - return nil, err - } - res := make(MarkerValues) - for _, file := range pkg.Syntax { - fileMarkers := markers[file] - for name, vals := range fileMarkers { - res[name] = append(res[name], vals...) - } - } - - return res, nil -} - -// FieldInfo contains marker values and commonly used information for a struct field. -type FieldInfo struct { - // Name is the name of the field (or "" for embedded fields) - Name string - // Doc is the Godoc of the field, pre-processed to remove markers and joine - // single newlines together. - Doc string - // Tag struct tag associated with this field (or "" if non existed). - Tag reflect.StructTag - - // Markers are all registered markers associated with this field. - Markers MarkerValues - - // RawField is the raw, underlying field AST object that this field represents. - RawField *ast.Field -} - -// TypeInfo contains marker values and commonly used information for a type declaration. -type TypeInfo struct { - // Name is the name of the type. - Name string - // Doc is the Godoc of the type, pre-processed to remove markers and joine - // single newlines together. - Doc string - - // Markers are all registered markers associated with the type. - Markers MarkerValues - - // Fields are all the fields associated with the type, if it's a struct. - // (if not, Fields will be nil). - Fields []FieldInfo - - // RawDecl contains the raw GenDecl that the type was declared as part of. - RawDecl *ast.GenDecl - // RawSpec contains the raw Spec that declared this type. - RawSpec *ast.TypeSpec - // RawFile contains the file in which this type was declared. - RawFile *ast.File -} - -// TypeCallback is a callback called for each type declaration in a package. -type TypeCallback func(info *TypeInfo) - -// EachType collects all markers, then calls the given callback for each type declaration in a package. -// Each individual spec is considered separate, so -// -// type ( -// Foo string -// Bar int -// Baz struct{} -// ) -// -// yields three calls to the callback. -func EachType(col *Collector, pkg *loader.Package, cb TypeCallback) error { - markers, err := col.MarkersInPackage(pkg) - if err != nil { - return err - } - - loader.EachType(pkg, func(file *ast.File, decl *ast.GenDecl, spec *ast.TypeSpec) { - var fields []FieldInfo - if structSpec, isStruct := spec.Type.(*ast.StructType); isStruct { - for _, field := range structSpec.Fields.List { - for _, name := range field.Names { - fields = append(fields, FieldInfo{ - Name: name.Name, - Doc: extractDoc(field, nil), - Tag: loader.ParseAstTag(field.Tag), - Markers: markers[field], - RawField: field, - }) - } - if field.Names == nil { - fields = append(fields, FieldInfo{ - Doc: extractDoc(field, nil), - Tag: loader.ParseAstTag(field.Tag), - Markers: markers[field], - RawField: field, - }) - } - } - } - - cb(&TypeInfo{ - Name: spec.Name.Name, - Markers: markers[spec], - Doc: extractDoc(spec, decl), - Fields: fields, - RawDecl: decl, - RawSpec: spec, - RawFile: file, - }) - }) - - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/rbac/parser.go b/vendor/sigs.k8s.io/controller-tools/pkg/rbac/parser.go deleted file mode 100644 index c2a24f47..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/rbac/parser.go +++ /dev/null @@ -1,267 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -// Package rbac contain libraries for generating RBAC manifests from RBAC -// markers in Go source files. -// -// The markers take the form: -// -// +kubebuilder:rbac:groups=,resources=,resourceNames=,verbs=,urls= -package rbac - -import ( - "fmt" - "sort" - "strings" - - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "sigs.k8s.io/controller-tools/pkg/genall" - "sigs.k8s.io/controller-tools/pkg/markers" -) - -var ( - // RuleDefinition is a marker for defining RBAC rules. - // Call ToRule on the value to get a Kubernetes RBAC policy rule. - RuleDefinition = markers.Must(markers.MakeDefinition("kubebuilder:rbac", markers.DescribesPackage, Rule{})) -) - -// +controllertools:marker:generateHelp:category=RBAC - -// Rule specifies an RBAC rule to all access to some resources or non-resource URLs. -type Rule struct { - // Groups specifies the API groups that this rule encompasses. - Groups []string `marker:",optional"` - // Resources specifies the API resources that this rule encompasses. - Resources []string `marker:",optional"` - // ResourceNames specifies the names of the API resources that this rule encompasses. - // - // Create requests cannot be restricted by resourcename, as the object's name - // is not known at authorization time. - ResourceNames []string `marker:",optional"` - // Verbs specifies the (lowercase) kubernetes API verbs that this rule encompasses. - Verbs []string - // URL specifies the non-resource URLs that this rule encompasses. - URLs []string `marker:"urls,optional"` - // Namespace specifies the scope of the Rule. - // If not set, the Rule belongs to the generated ClusterRole. - // If set, the Rule belongs to a Role, whose namespace is specified by this field. - Namespace string `marker:",optional"` -} - -// ruleKey represents the resources and non-resources a Rule applies. -type ruleKey struct { - Groups string - Resources string - ResourceNames string - URLs string -} - -func (key ruleKey) String() string { - return fmt.Sprintf("%s + %s + %s + %s", key.Groups, key.Resources, key.ResourceNames, key.URLs) -} - -// ruleKeys implements sort.Interface -type ruleKeys []ruleKey - -func (keys ruleKeys) Len() int { return len(keys) } -func (keys ruleKeys) Swap(i, j int) { keys[i], keys[j] = keys[j], keys[i] } -func (keys ruleKeys) Less(i, j int) bool { return keys[i].String() < keys[j].String() } - -// key normalizes the Rule and returns a ruleKey object. -func (r *Rule) key() ruleKey { - r.normalize() - return ruleKey{ - Groups: strings.Join(r.Groups, "&"), - Resources: strings.Join(r.Resources, "&"), - ResourceNames: strings.Join(r.ResourceNames, "&"), - URLs: strings.Join(r.URLs, "&"), - } -} - -// addVerbs adds new verbs into a Rule. -// The duplicates in `r.Verbs` will be removed, and then `r.Verbs` will be sorted. -func (r *Rule) addVerbs(verbs []string) { - r.Verbs = removeDupAndSort(append(r.Verbs, verbs...)) -} - -// normalize removes duplicates from each field of a Rule, and sorts each field. -func (r *Rule) normalize() { - r.Groups = removeDupAndSort(r.Groups) - r.Resources = removeDupAndSort(r.Resources) - r.ResourceNames = removeDupAndSort(r.ResourceNames) - r.Verbs = removeDupAndSort(r.Verbs) - r.URLs = removeDupAndSort(r.URLs) -} - -// removeDupAndSort removes duplicates in strs, sorts the items, and returns a -// new slice of strings. -func removeDupAndSort(strs []string) []string { - set := make(map[string]bool) - for _, str := range strs { - if _, ok := set[str]; !ok { - set[str] = true - } - } - - var result []string - for str := range set { - result = append(result, str) - } - sort.Strings(result) - return result -} - -// ToRule converts this rule to its Kubernetes API form. -func (r *Rule) ToRule() rbacv1.PolicyRule { - // fix the group names first, since letting people type "core" is nice - for i, group := range r.Groups { - if group == "core" { - r.Groups[i] = "" - } - } - return rbacv1.PolicyRule{ - APIGroups: r.Groups, - Verbs: r.Verbs, - Resources: r.Resources, - ResourceNames: r.ResourceNames, - NonResourceURLs: r.URLs, - } -} - -// +controllertools:marker:generateHelp - -// Generator generates ClusterRole objects. -type Generator struct { - // RoleName sets the name of the generated ClusterRole. - RoleName string -} - -func (Generator) RegisterMarkers(into *markers.Registry) error { - if err := into.Register(RuleDefinition); err != nil { - return err - } - into.AddHelp(RuleDefinition, Rule{}.Help()) - return nil -} - -// GenerateRoles generate a slice of objs representing either a ClusterRole or a Role object -// The order of the objs in the returned slice is stable and determined by their namespaces. -func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{}, error) { - rulesByNS := make(map[string][]*Rule) - for _, root := range ctx.Roots { - markerSet, err := markers.PackageMarkers(ctx.Collector, root) - if err != nil { - root.AddError(err) - } - - // group RBAC markers by namespace - for _, markerValue := range markerSet[RuleDefinition.Name] { - rule := markerValue.(Rule) - namespace := rule.Namespace - if _, ok := rulesByNS[namespace]; !ok { - rules := make([]*Rule, 0) - rulesByNS[namespace] = rules - } - rulesByNS[namespace] = append(rulesByNS[namespace], &rule) - } - } - - // NormalizeRules merge Rule with the same ruleKey and sort the Rules - NormalizeRules := func(rules []*Rule) []rbacv1.PolicyRule { - ruleMap := make(map[ruleKey]*Rule) - // all the Rules having the same ruleKey will be merged into the first Rule - for _, rule := range rules { - key := rule.key() - if _, ok := ruleMap[key]; !ok { - ruleMap[key] = rule - continue - } - ruleMap[key].addVerbs(rule.Verbs) - } - - // sort the Rules in rules according to their ruleKeys - keys := make([]ruleKey, 0, len(ruleMap)) - for key := range ruleMap { - keys = append(keys, key) - } - sort.Sort(ruleKeys(keys)) - - var policyRules []rbacv1.PolicyRule - for _, key := range keys { - policyRules = append(policyRules, ruleMap[key].ToRule()) - - } - return policyRules - } - - // collect all the namespaces and sort them - var namespaces []string - for ns := range rulesByNS { - namespaces = append(namespaces, ns) - } - sort.Strings(namespaces) - - // process the items in rulesByNS by the order specified in `namespaces` to make sure that the Role order is stable - var objs []interface{} - for _, ns := range namespaces { - rules := rulesByNS[ns] - policyRules := NormalizeRules(rules) - if len(policyRules) == 0 { - continue - } - if ns == "" { - objs = append(objs, rbacv1.ClusterRole{ - TypeMeta: metav1.TypeMeta{ - Kind: "ClusterRole", - APIVersion: rbacv1.SchemeGroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{ - Name: roleName, - }, - Rules: policyRules, - }) - } else { - objs = append(objs, rbacv1.Role{ - TypeMeta: metav1.TypeMeta{ - Kind: "Role", - APIVersion: rbacv1.SchemeGroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{ - Name: roleName, - Namespace: ns, - }, - Rules: policyRules, - }) - } - } - - return objs, nil -} - -func (g Generator) Generate(ctx *genall.GenerationContext) error { - objs, err := GenerateRoles(ctx, g.RoleName) - if err != nil { - return err - } - - if len(objs) == 0 { - return nil - } - - return ctx.WriteYAML("role.yaml", objs) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/rbac/zz_generated.markerhelp.go b/vendor/sigs.k8s.io/controller-tools/pkg/rbac/zz_generated.markerhelp.go deleted file mode 100644 index 0e2083a2..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/rbac/zz_generated.markerhelp.go +++ /dev/null @@ -1,78 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright2019 The Kubernetes Authors. - -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. -*/ - -// Code generated by helpgen. DO NOT EDIT. - -package rbac - -import ( - "sigs.k8s.io/controller-tools/pkg/markers" -) - -func (Generator) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "generates ClusterRole objects.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "RoleName": { - Summary: "sets the name of the generated ClusterRole.", - Details: "", - }, - }, - } -} - -func (Rule) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "RBAC", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies an RBAC rule to all access to some resources or non-resource URLs.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "Groups": { - Summary: "specifies the API groups that this rule encompasses.", - Details: "", - }, - "Resources": { - Summary: "specifies the API resources that this rule encompasses.", - Details: "", - }, - "ResourceNames": { - Summary: "specifies the names of the API resources that this rule encompasses. ", - Details: "Create requests cannot be restricted by resourcename, as the object's name is not known at authorization time.", - }, - "Verbs": { - Summary: "specifies the (lowercase) kubernetes API verbs that this rule encompasses.", - Details: "", - }, - "URLs": { - Summary: "URL specifies the non-resource URLs that this rule encompasses.", - Details: "", - }, - "Namespace": { - Summary: "specifies the scope of the Rule. If not set, the Rule belongs to the generated ClusterRole. If set, the Rule belongs to a Role, whose namespace is specified by this field.", - Details: "", - }, - }, - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/gen.go b/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/gen.go deleted file mode 100644 index e33ec11f..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/gen.go +++ /dev/null @@ -1,433 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package schemapatcher - -import ( - "fmt" - "io/ioutil" - "path/filepath" - - "gopkg.in/yaml.v3" - apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/api/equality" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - kyaml "sigs.k8s.io/yaml" - - crdgen "sigs.k8s.io/controller-tools/pkg/crd" - crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers" - "sigs.k8s.io/controller-tools/pkg/genall" - "sigs.k8s.io/controller-tools/pkg/loader" - "sigs.k8s.io/controller-tools/pkg/markers" - yamlop "sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml" -) - -// NB(directxman12): this code is quite fragile, but there are a sufficient -// number of corner cases that it's hard to decompose into separate tools. -// When in doubt, ping @sttts. -// -// Namely: -// - It needs to only update existing versions -// - It needs to make "stable" changes that don't mess with map key ordering -// (in order to facilitate validating that no change has occurred) -// - It needs to collapse identical schema versions into a top-level schema, -// if all versions are identical (this is a common requirement to all CRDs, -// but in this case it means simple jsonpatch wouldn't suffice) - -// TODO(directxman12): When CRD v1 rolls around, consider splitting this into a -// tool that generates a patch, and a separate tool for applying stable YAML -// patches. - -var ( - currentAPIExtVersion = apiext.SchemeGroupVersion.String() -) - -// +controllertools:marker:generateHelp - -// Generator patches existing CRDs with new schemata. -// -// It will generate output for each "CRD Version" (API version of the CRD type -// itself) , e.g. apiextensions/v1) available. -type Generator struct { - // ManifestsPath contains the CustomResourceDefinition YAML files. - ManifestsPath string `marker:"manifests"` - - // MaxDescLen specifies the maximum description length for fields in CRD's OpenAPI schema. - // - // 0 indicates drop the description for all fields completely. - // n indicates limit the description to at most n characters and truncate the description to - // closest sentence boundary if it exceeds n characters. - MaxDescLen *int `marker:",optional"` - - // GenerateEmbeddedObjectMeta specifies if any embedded ObjectMeta in the CRD should be generated - GenerateEmbeddedObjectMeta *bool `marker:",optional"` -} - -var _ genall.Generator = &Generator{} - -func (Generator) CheckFilter() loader.NodeFilter { - return crdgen.Generator{}.CheckFilter() -} - -func (Generator) RegisterMarkers(into *markers.Registry) error { - return crdmarkers.Register(into) -} - -func (g Generator) Generate(ctx *genall.GenerationContext) (result error) { - parser := &crdgen.Parser{ - Collector: ctx.Collector, - Checker: ctx.Checker, - // Indicates the parser on whether to register the ObjectMeta type or not - GenerateEmbeddedObjectMeta: g.GenerateEmbeddedObjectMeta != nil && *g.GenerateEmbeddedObjectMeta == true, - } - - crdgen.AddKnownTypes(parser) - for _, root := range ctx.Roots { - parser.NeedPackage(root) - } - - metav1Pkg := crdgen.FindMetav1(ctx.Roots) - if metav1Pkg == nil { - // no objects in the roots, since nothing imported metav1 - return nil - } - - // load existing CRD manifests with group-kind and versions - partialCRDSets, err := crdsFromDirectory(ctx, g.ManifestsPath) - if err != nil { - return err - } - - // generate schemata for the types we care about, and save them to be written later. - for _, groupKind := range crdgen.FindKubeKinds(parser, metav1Pkg) { - existingSet, wanted := partialCRDSets[groupKind] - if !wanted { - continue - } - - for pkg, gv := range parser.GroupVersions { - if gv.Group != groupKind.Group { - continue - } - if _, wantedVersion := existingSet.Versions[gv.Version]; !wantedVersion { - continue - } - - typeIdent := crdgen.TypeIdent{Package: pkg, Name: groupKind.Kind} - parser.NeedFlattenedSchemaFor(typeIdent) - - fullSchema := parser.FlattenedSchemata[typeIdent] - if g.MaxDescLen != nil { - fullSchema = *fullSchema.DeepCopy() - crdgen.TruncateDescription(&fullSchema, *g.MaxDescLen) - } - - // Fix top level ObjectMeta regardless of the settings. - if _, ok := fullSchema.Properties["metadata"]; ok { - fullSchema.Properties["metadata"] = apiext.JSONSchemaProps{Type: "object"} - } - - existingSet.NewSchemata[gv.Version] = fullSchema - } - } - - // patch existing CRDs with new schemata - for _, existingSet := range partialCRDSets { - // first, figure out if we need to merge schemata together if they're *all* - // identical (meaning we also don't have any "unset" versions) - - if len(existingSet.NewSchemata) == 0 { - continue - } - - // copy over the new versions that we have, keeping old versions so - // that we can tell if a schema would be nil - var someVer string - for ver := range existingSet.NewSchemata { - someVer = ver - existingSet.Versions[ver] = struct{}{} - } - - allSame := true - firstSchema := existingSet.NewSchemata[someVer] - for ver := range existingSet.Versions { - otherSchema, hasSchema := existingSet.NewSchemata[ver] - if !hasSchema || !equality.Semantic.DeepEqual(firstSchema, otherSchema) { - allSame = false - break - } - } - - if allSame { - if err := existingSet.setGlobalSchema(); err != nil { - return fmt.Errorf("failed to set global firstSchema for %s: %w", existingSet.GroupKind, err) - } - } else { - if err := existingSet.setVersionedSchemata(); err != nil { - return fmt.Errorf("failed to set versioned schemas for %s: %w", existingSet.GroupKind, err) - } - } - } - - // write the final result out to the new location - for _, set := range partialCRDSets { - // We assume all CRD versions came from different files, since this - // is how controller-gen works. If they came from the same file, - // it'd be non-sensical, since you couldn't reasonably use kubectl - // with them against older servers. - for _, crd := range set.CRDVersions { - if err := func() error { - outWriter, err := ctx.OutputRule.Open(nil, crd.FileName) - if err != nil { - return err - } - defer outWriter.Close() - - enc := yaml.NewEncoder(outWriter) - // yaml.v2 defaults to indent=2, yaml.v3 defaults to indent=4, - // so be compatible with everything else in k8s and choose 2. - enc.SetIndent(2) - - return enc.Encode(crd.Yaml) - }(); err != nil { - return err - } - } - } - - return nil -} - -// partialCRDSet represents a set of CRDs of different apiext versions -// (v1beta1.CRD vs v1.CRD) that represent the same GroupKind. -// -// It tracks modifications to the schemata of those CRDs from this source file, -// plus some useful structured content, and keeps track of the raw YAML representation -// of the different apiext versions. -type partialCRDSet struct { - // GroupKind is the GroupKind represented by this CRD. - GroupKind schema.GroupKind - // NewSchemata are the new schemata generated from Go IDL by controller-gen. - NewSchemata map[string]apiext.JSONSchemaProps - // CRDVersions are the forms of this CRD across different apiextensions - // versions - CRDVersions []*partialCRD - // Versions are the versions of the given GroupKind in this set of CRDs. - Versions map[string]struct{} -} - -// partialCRD represents the raw YAML encoding of a given CRD instance, plus -// the versions contained therein for easy lookup. -type partialCRD struct { - // Yaml is the raw YAML structure of the CRD. - Yaml *yaml.Node - // FileName is the source name of the file that this was read from. - // - // This isn't on partialCRDSet because we could have different CRD versions - // stored in the same file (like controller-tools does by default) or in - // different files. - FileName string - - // CRDVersion is the version of the CRD object itself, from - // apiextensions (currently apiextensions/v1 or apiextensions/v1beta1). - CRDVersion string -} - -// setGlobalSchema sets the versioned schemas (as per setVersionedSchemata). -func (e *partialCRDSet) setGlobalSchema() error { - for _, crdInfo := range e.CRDVersions { - if err := crdInfo.setVersionedSchemata(e.NewSchemata); err != nil { - return err - } - } - return nil -} - -// getVersionsNode gets the YAML node of .spec.versions YAML mapping, -// if returning the node, and whether or not it was present. -func (e *partialCRD) getVersionsNode() (*yaml.Node, bool, error) { - versions, found, err := yamlop.GetNode(e.Yaml, "spec", "versions") - if err != nil { - return nil, false, err - } - if !found { - return nil, false, nil - } - if versions.Kind != yaml.SequenceNode { - return nil, true, fmt.Errorf("unexpected non-sequence versions") - } - return versions, found, nil -} - -// setVersionedSchemata sets the versioned schemata on each encoding in this set as per -// setVersionedSchemata on partialCRD. -func (e *partialCRDSet) setVersionedSchemata() error { - for _, crdInfo := range e.CRDVersions { - if err := crdInfo.setVersionedSchemata(e.NewSchemata); err != nil { - return err - } - } - return nil -} - -// setVersionedSchemata populates all existing versions with new schemata, -// wiping the schema of any version that doesn't have a listed schema. -// Any "unknown" versions are ignored. -func (e *partialCRD) setVersionedSchemata(newSchemata map[string]apiext.JSONSchemaProps) error { - var err error - if err := yamlop.DeleteNode(e.Yaml, "spec", "validation"); err != nil { - return err - } - - versions, found, err := e.getVersionsNode() - if err != nil { - return err - } - if !found { - return fmt.Errorf("unexpected missing versions") - } - - for i, verNode := range versions.Content { - nameNode, _, _ := yamlop.GetNode(verNode, "name") - if nameNode.Kind != yaml.ScalarNode || nameNode.ShortTag() != "!!str" { - return fmt.Errorf("version name was not a string at spec.versions[%d]", i) - } - name := nameNode.Value - if name == "" { - return fmt.Errorf("unexpected empty name at spec.versions[%d]", i) - } - newSchema, found := newSchemata[name] - if !found { - if err := yamlop.DeleteNode(verNode, "schema"); err != nil { - return fmt.Errorf("spec.versions[%d]: %w", i, err) - } - } else { - schemaNodeTree, err := yamlop.ToYAML(newSchema) - if err != nil { - return fmt.Errorf("failed to convert schema to YAML: %w", err) - } - schemaNodeTree = schemaNodeTree.Content[0] // get rid of the document node - yamlop.SetStyle(schemaNodeTree, 0) // clear the style so it defaults to an auto-chosen one - if err := yamlop.SetNode(verNode, *schemaNodeTree, "schema", "openAPIV3Schema"); err != nil { - return fmt.Errorf("spec.versions[%d]: %w", i, err) - } - } - } - return nil -} - -// crdsFromDirectory returns loads all CRDs from the given directory in a -// manner that preserves ordering, comments, etc in order to make patching -// minimally invasive. Returned CRDs are mapped by group-kind. -func crdsFromDirectory(ctx *genall.GenerationContext, dir string) (map[schema.GroupKind]*partialCRDSet, error) { - res := map[schema.GroupKind]*partialCRDSet{} - dirEntries, err := ioutil.ReadDir(dir) - if err != nil { - return nil, err - } - for _, fileInfo := range dirEntries { - // find all files that are YAML - if fileInfo.IsDir() || filepath.Ext(fileInfo.Name()) != ".yaml" { - continue - } - - rawContent, err := ctx.ReadFile(filepath.Join(dir, fileInfo.Name())) - if err != nil { - return nil, err - } - - // NB(directxman12): we could use the universal deserializer for this, but it's - // really pretty clunky, and the alternative is actually kinda easier to understand - - // ensure that this is a CRD - var typeMeta metav1.TypeMeta - if err := kyaml.Unmarshal(rawContent, &typeMeta); err != nil { - continue - } - - if typeMeta.APIVersion == "" || typeMeta.Kind != "CustomResourceDefinition" { - // If there's no API version this file probably isn't a CRD. - // Likewise we don't need to care if the Kind isn't CustomResourceDefinition. - continue - } - - if !isSupportedAPIExtGroupVer(typeMeta.APIVersion) { - return nil, fmt.Errorf("load %q: apiVersion %q not supported", filepath.Join(dir, fileInfo.Name()), typeMeta.APIVersion) - } - - // collect the group-kind and versions from the actual structured form - var actualCRD crdIsh - if err := kyaml.Unmarshal(rawContent, &actualCRD); err != nil { - continue - } - groupKind := schema.GroupKind{Group: actualCRD.Spec.Group, Kind: actualCRD.Spec.Names.Kind} - versions := make(map[string]struct{}, len(actualCRD.Spec.Versions)) - for _, ver := range actualCRD.Spec.Versions { - versions[ver.Name] = struct{}{} - } - - // then actually unmarshal in a manner that preserves ordering, etc - var yamlNodeTree yaml.Node - if err := yaml.Unmarshal(rawContent, &yamlNodeTree); err != nil { - continue - } - - // then store this CRDVersion of the CRD in a set, populating the set if necessary - if res[groupKind] == nil { - res[groupKind] = &partialCRDSet{ - GroupKind: groupKind, - NewSchemata: make(map[string]apiext.JSONSchemaProps), - Versions: make(map[string]struct{}), - } - } - for ver := range versions { - res[groupKind].Versions[ver] = struct{}{} - } - res[groupKind].CRDVersions = append(res[groupKind].CRDVersions, &partialCRD{ - Yaml: &yamlNodeTree, - FileName: fileInfo.Name(), - CRDVersion: typeMeta.APIVersion, - }) - } - return res, nil -} - -// isSupportedAPIExtGroupVer checks if the given string-form group-version -// is one of the known apiextensions versions (v1). -func isSupportedAPIExtGroupVer(groupVer string) bool { - return groupVer == currentAPIExtVersion -} - -// crdIsh is a merged blob of CRD fields that looks enough like all versions of -// CRD to extract the relevant information for partialCRDSet and partialCRD. -// -// We keep this separate so it's clear what info we need, and so we don't break -// when we switch canonical internal versions and lose old fields while gaining -// new ones (like in v1beta1 --> v1). -// -// Its use is tied directly to crdsFromDirectory, and is mostly an implementation detail of that. -type crdIsh struct { - Spec struct { - Group string `json:"group"` - Names struct { - Kind string `json:"kind"` - } `json:"names"` - Versions []struct { - Name string `json:"name"` - } `json:"versions"` - } `json:"spec"` -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/convert.go b/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/convert.go deleted file mode 100644 index b0ac0015..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/convert.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package yaml - -import ( - "encoding/json" - "fmt" - - "gopkg.in/yaml.v3" -) - -// ToYAML converts some object that serializes to JSON into a YAML node tree. -// It's useful since it pays attention to JSON tags, unlike yaml.Unmarshal or -// yaml.Node.Decode. -func ToYAML(rawObj interface{}) (*yaml.Node, error) { - if rawObj == nil { - return &yaml.Node{Kind: yaml.ScalarNode, Value: "null", Tag: "!!null"}, nil - } - - rawJSON, err := json.Marshal(rawObj) - if err != nil { - return nil, fmt.Errorf("failed to marshal object: %w", err) - } - - var out yaml.Node - if err := yaml.Unmarshal(rawJSON, &out); err != nil { - return nil, fmt.Errorf("unable to unmarshal marshalled object: %w", err) - } - return &out, nil -} - -// changeAll calls the given callback for all nodes in -// the given YAML node tree. -func changeAll(root *yaml.Node, cb func(*yaml.Node)) { - cb(root) - for _, child := range root.Content { - changeAll(child, cb) - } -} - -// SetStyle sets the style for all nodes in the given -// node tree to the given style. -func SetStyle(root *yaml.Node, style yaml.Style) { - changeAll(root, func(node *yaml.Node) { - node.Style = style - }) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/nested.go b/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/nested.go deleted file mode 100644 index 70d43dbe..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/nested.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package yaml - -import ( - "fmt" - - "gopkg.in/yaml.v3" -) - -// ValueInMapping finds the value node with the corresponding string key -// in the given mapping node. If the given node is not a mapping, an -// error will be returned. -func ValueInMapping(root *yaml.Node, key string) (*yaml.Node, error) { - if root.Kind != yaml.MappingNode { - return nil, fmt.Errorf("unexpected non-mapping node") - } - - for i := 0; i < len(root.Content)/2; i++ { - keyNode := root.Content[i*2] - if keyNode.Value == key { - return root.Content[i*2+1], nil - } - } - return nil, nil -} - -// asCloseAsPossible goes as deep on the given path as possible, returning the -// last node that existed from the given path in the given tree of mapping -// nodes, as well as the rest of the path that could not be fetched, if any. -func asCloseAsPossible(root *yaml.Node, path ...string) (*yaml.Node, []string, error) { - if root == nil { - return nil, path, nil - } - if root.Kind == yaml.DocumentNode && len(root.Content) > 0 { - root = root.Content[0] - } - - currNode := root - for ; len(path) > 0; path = path[1:] { - if currNode.Kind != yaml.MappingNode { - return nil, nil, fmt.Errorf("unexpected non-mapping (%v) before path %v", currNode.Kind, path) - } - - nextNode, err := ValueInMapping(currNode, path[0]) - if err != nil { - return nil, nil, fmt.Errorf("unable to get next node in path %v: %w", path, err) - } - - if nextNode == nil { - // we're as close as possible - break - } - - currNode = nextNode - } - - return currNode, path, nil -} - -// GetNode gets the node at the given path in the given sequence of mapping -// nodes, or, if it doesn't exist, returning false. -func GetNode(root *yaml.Node, path ...string) (*yaml.Node, bool, error) { - resNode, restPath, err := asCloseAsPossible(root, path...) - if err != nil { - return nil, false, err - } - // more path means the node didn't exist - if len(restPath) != 0 { - return nil, false, nil - } - return resNode, true, nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/set.go b/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/set.go deleted file mode 100644 index ede417f1..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/internal/yaml/set.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ - -package yaml - -import ( - "fmt" - - "gopkg.in/yaml.v3" -) - -// SetNode sets the given path to the given yaml Node, creating mapping nodes along the way. -func SetNode(root *yaml.Node, val yaml.Node, path ...string) error { - currNode, path, err := asCloseAsPossible(root, path...) - if err != nil { - return err - } - - if len(path) > 0 { - if currNode.Kind != yaml.MappingNode { - return fmt.Errorf("unexpected non-mapping before path %v", path) - } - - for ; len(path) > 0; path = path[1:] { - keyNode := yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Style: yaml.DoubleQuotedStyle, Value: path[0]} - nextNode := &yaml.Node{Kind: yaml.MappingNode} - currNode.Content = append(currNode.Content, &keyNode, nextNode) - - currNode = nextNode - } - } - - *currNode = val - return nil -} - -// DeleteNode deletes the node at the given path in the given tree of mapping nodes. -// It's a noop if the path doesn't exist. -func DeleteNode(root *yaml.Node, path ...string) error { - if len(path) == 0 { - return fmt.Errorf("must specify a path to delete") - } - pathToParent, keyToDelete := path[:len(path)-1], path[len(path)-1] - parentNode, path, err := asCloseAsPossible(root, pathToParent...) - if err != nil { - return err - } - if len(path) > 0 { - // no-op, parent node doesn't exist - return nil - } - - if parentNode.Kind != yaml.MappingNode { - return fmt.Errorf("unexpected non-mapping node") - } - - for i := 0; i < len(parentNode.Content)/2; i++ { - keyNode := parentNode.Content[i*2] - if keyNode.Value == keyToDelete { - parentNode.Content = append(parentNode.Content[:i*2], parentNode.Content[i*2+2:]...) - return nil - } - } - - // no-op, key not found in parent node - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/zz_generated.markerhelp.go b/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/zz_generated.markerhelp.go deleted file mode 100644 index db9745d7..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/zz_generated.markerhelp.go +++ /dev/null @@ -1,50 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright2019 The Kubernetes Authors. - -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. -*/ - -// Code generated by helpgen. DO NOT EDIT. - -package schemapatcher - -import ( - "sigs.k8s.io/controller-tools/pkg/markers" -) - -func (Generator) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "patches existing CRDs with new schemata. ", - Details: "It will generate output for each \"CRD Version\" (API version of the CRD type itself) , e.g. apiextensions/v1) available.", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "ManifestsPath": { - Summary: "contains the CustomResourceDefinition YAML files.", - Details: "", - }, - "MaxDescLen": { - Summary: "specifies the maximum description length for fields in CRD's OpenAPI schema. ", - Details: "0 indicates drop the description for all fields completely. n indicates limit the description to at most n characters and truncate the description to closest sentence boundary if it exceeds n characters.", - }, - "GenerateEmbeddedObjectMeta": { - Summary: "specifies if any embedded ObjectMeta in the CRD should be generated", - Details: "", - }, - }, - } -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/version/version.go b/vendor/sigs.k8s.io/controller-tools/pkg/version/version.go deleted file mode 100644 index 09c8efcf..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/version/version.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -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. -*/ -package version - -import ( - "fmt" - "runtime/debug" -) - -// Version returns the version of the main module -func Version() string { - info, ok := debug.ReadBuildInfo() - if !ok || info == nil || info.Main.Version == "" { - // binary has not been built with module support or doesn't contain a version. - return "(unknown)" - } - return info.Main.Version -} - -// Print prints the main module version on stdout. -// -// Print will display either: -// -// - "Version: v0.2.1" when the program has been compiled with: -// -// $ go get github.com/controller-tools/cmd/controller-gen@v0.2.1 -// -// Note: go modules requires the usage of semver compatible tags starting with -// 'v' to have nice human-readable versions. -// -// - "Version: (devel)" when the program is compiled from a local git checkout. -// -// - "Version: (unknown)" when not using go modules. -func Print() { - fmt.Printf("Version: %s\n", Version()) -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/webhook/parser.go b/vendor/sigs.k8s.io/controller-tools/pkg/webhook/parser.go deleted file mode 100644 index a76dcdcb..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/webhook/parser.go +++ /dev/null @@ -1,431 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -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. -*/ - -// Package webhook contains libraries for generating webhookconfig manifests -// from markers in Go source files. -// -// The markers take the form: -// -// +kubebuilder:webhook:webhookVersions=<[]string>,failurePolicy=,matchPolicy=,groups=<[]string>,resources=<[]string>,verbs=<[]string>,versions=<[]string>,name=,path=,mutating=,sideEffects=,admissionReviewVersions=<[]string>,reinvocationPolicy= -package webhook - -import ( - "fmt" - "strings" - - admissionregv1 "k8s.io/api/admissionregistration/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/sets" - - "sigs.k8s.io/controller-tools/pkg/genall" - "sigs.k8s.io/controller-tools/pkg/markers" -) - -// The default {Mutating,Validating}WebhookConfiguration version to generate. -const ( - v1 = "v1" - defaultWebhookVersion = v1 -) - -var ( - // ConfigDefinition s a marker for defining Webhook manifests. - // Call ToWebhook on the value to get a Kubernetes Webhook. - ConfigDefinition = markers.Must(markers.MakeDefinition("kubebuilder:webhook", markers.DescribesPackage, Config{})) -) - -// supportedWebhookVersions returns currently supported API version of {Mutating,Validating}WebhookConfiguration. -func supportedWebhookVersions() []string { - return []string{defaultWebhookVersion} -} - -// +controllertools:marker:generateHelp:category=Webhook - -// Config specifies how a webhook should be served. -// -// It specifies only the details that are intrinsic to the application serving -// it (e.g. the resources it can handle, or the path it serves on). -type Config struct { - // Mutating marks this as a mutating webhook (it's validating only if false) - // - // Mutating webhooks are allowed to change the object in their response, - // and are called *before* all validating webhooks. Mutating webhooks may - // choose to reject an object, similarly to a validating webhook. - Mutating bool - // FailurePolicy specifies what should happen if the API server cannot reach the webhook. - // - // It may be either "ignore" (to skip the webhook and continue on) or "fail" (to reject - // the object in question). - FailurePolicy string - // MatchPolicy defines how the "rules" list is used to match incoming requests. - // Allowed values are "Exact" (match only if it exactly matches the specified rule) - // or "Equivalent" (match a request if it modifies a resource listed in rules, even via another API group or version). - MatchPolicy string `marker:",optional"` - // SideEffects specify whether calling the webhook will have side effects. - // This has an impact on dry runs and `kubectl diff`: if the sideEffect is "Unknown" (the default) or "Some", then - // the API server will not call the webhook on a dry-run request and fails instead. - // If the value is "None", then the webhook has no side effects and the API server will call it on dry-run. - // If the value is "NoneOnDryRun", then the webhook is responsible for inspecting the "dryRun" property of the - // AdmissionReview sent in the request, and avoiding side effects if that value is "true." - SideEffects string `marker:",optional"` - - // Groups specifies the API groups that this webhook receives requests for. - Groups []string - // Resources specifies the API resources that this webhook receives requests for. - Resources []string - // Verbs specifies the Kubernetes API verbs that this webhook receives requests for. - // - // Only modification-like verbs may be specified. - // May be "create", "update", "delete", "connect", or "*" (for all). - Verbs []string - // Versions specifies the API versions that this webhook receives requests for. - Versions []string - - // Name indicates the name of this webhook configuration. Should be a domain with at least three segments separated by dots - Name string - - // Path specifies that path that the API server should connect to this webhook on. Must be - // prefixed with a '/validate-' or '/mutate-' depending on the type, and followed by - // $GROUP-$VERSION-$KIND where all values are lower-cased and the periods in the group - // are substituted for hyphens. For example, a validating webhook path for type - // batch.tutorial.kubebuilder.io/v1,Kind=CronJob would be - // /validate-batch-tutorial-kubebuilder-io-v1-cronjob - Path string - - // WebhookVersions specifies the target API versions of the {Mutating,Validating}WebhookConfiguration objects - // itself to generate. The only supported value is v1. Defaults to v1. - WebhookVersions []string `marker:"webhookVersions,optional"` - - // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` - // versions the Webhook expects. - AdmissionReviewVersions []string `marker:"admissionReviewVersions"` - - // ReinvocationPolicy allows mutating webhooks to request reinvocation after other mutations - // - // To allow mutating admission plugins to observe changes made by other plugins, - // built-in mutating admission plugins are re-run if a mutating webhook modifies - // an object, and mutating webhooks can specify a reinvocationPolicy to control - // whether they are reinvoked as well. - ReinvocationPolicy string `marker:"reinvocationPolicy,optional"` -} - -// verbToAPIVariant converts a marker's verb to the proper value for the API. -// Unrecognized verbs are passed through. -func verbToAPIVariant(verbRaw string) admissionregv1.OperationType { - switch strings.ToLower(verbRaw) { - case strings.ToLower(string(admissionregv1.Create)): - return admissionregv1.Create - case strings.ToLower(string(admissionregv1.Update)): - return admissionregv1.Update - case strings.ToLower(string(admissionregv1.Delete)): - return admissionregv1.Delete - case strings.ToLower(string(admissionregv1.Connect)): - return admissionregv1.Connect - case strings.ToLower(string(admissionregv1.OperationAll)): - return admissionregv1.OperationAll - default: - return admissionregv1.OperationType(verbRaw) - } -} - -// ToMutatingWebhook converts this rule to its Kubernetes API form. -func (c Config) ToMutatingWebhook() (admissionregv1.MutatingWebhook, error) { - if !c.Mutating { - return admissionregv1.MutatingWebhook{}, fmt.Errorf("%s is a validating webhook", c.Name) - } - - matchPolicy, err := c.matchPolicy() - if err != nil { - return admissionregv1.MutatingWebhook{}, err - } - - return admissionregv1.MutatingWebhook{ - Name: c.Name, - Rules: c.rules(), - FailurePolicy: c.failurePolicy(), - MatchPolicy: matchPolicy, - ClientConfig: c.clientConfig(), - SideEffects: c.sideEffects(), - AdmissionReviewVersions: c.AdmissionReviewVersions, - ReinvocationPolicy: c.reinvocationPolicy(), - }, nil -} - -// ToValidatingWebhook converts this rule to its Kubernetes API form. -func (c Config) ToValidatingWebhook() (admissionregv1.ValidatingWebhook, error) { - if c.Mutating { - return admissionregv1.ValidatingWebhook{}, fmt.Errorf("%s is a mutating webhook", c.Name) - } - - matchPolicy, err := c.matchPolicy() - if err != nil { - return admissionregv1.ValidatingWebhook{}, err - } - - return admissionregv1.ValidatingWebhook{ - Name: c.Name, - Rules: c.rules(), - FailurePolicy: c.failurePolicy(), - MatchPolicy: matchPolicy, - ClientConfig: c.clientConfig(), - SideEffects: c.sideEffects(), - AdmissionReviewVersions: c.AdmissionReviewVersions, - }, nil -} - -// rules returns the configuration of what operations on what -// resources/subresources a webhook should care about. -func (c Config) rules() []admissionregv1.RuleWithOperations { - whConfig := admissionregv1.RuleWithOperations{ - Rule: admissionregv1.Rule{ - APIGroups: c.Groups, - APIVersions: c.Versions, - Resources: c.Resources, - }, - Operations: make([]admissionregv1.OperationType, len(c.Verbs)), - } - - for i, verbRaw := range c.Verbs { - whConfig.Operations[i] = verbToAPIVariant(verbRaw) - } - - // fix the group names, since letting people type "core" is nice - for i, group := range whConfig.APIGroups { - if group == "core" { - whConfig.APIGroups[i] = "" - } - } - - return []admissionregv1.RuleWithOperations{whConfig} -} - -// failurePolicy converts the string value to the proper value for the API. -// Unrecognized values are passed through. -func (c Config) failurePolicy() *admissionregv1.FailurePolicyType { - var failurePolicy admissionregv1.FailurePolicyType - switch strings.ToLower(c.FailurePolicy) { - case strings.ToLower(string(admissionregv1.Ignore)): - failurePolicy = admissionregv1.Ignore - case strings.ToLower(string(admissionregv1.Fail)): - failurePolicy = admissionregv1.Fail - default: - failurePolicy = admissionregv1.FailurePolicyType(c.FailurePolicy) - } - return &failurePolicy -} - -// matchPolicy converts the string value to the proper value for the API. -func (c Config) matchPolicy() (*admissionregv1.MatchPolicyType, error) { - var matchPolicy admissionregv1.MatchPolicyType - switch strings.ToLower(c.MatchPolicy) { - case strings.ToLower(string(admissionregv1.Exact)): - matchPolicy = admissionregv1.Exact - case strings.ToLower(string(admissionregv1.Equivalent)): - matchPolicy = admissionregv1.Equivalent - case "": - return nil, nil - default: - return nil, fmt.Errorf("unknown value %q for matchPolicy", c.MatchPolicy) - } - return &matchPolicy, nil -} - -// clientConfig returns the client config for a webhook. -func (c Config) clientConfig() admissionregv1.WebhookClientConfig { - path := c.Path - return admissionregv1.WebhookClientConfig{ - Service: &admissionregv1.ServiceReference{ - Name: "webhook-service", - Namespace: "system", - Path: &path, - }, - } -} - -// sideEffects returns the sideEffects config for a webhook. -func (c Config) sideEffects() *admissionregv1.SideEffectClass { - var sideEffects admissionregv1.SideEffectClass - switch strings.ToLower(c.SideEffects) { - case strings.ToLower(string(admissionregv1.SideEffectClassNone)): - sideEffects = admissionregv1.SideEffectClassNone - case strings.ToLower(string(admissionregv1.SideEffectClassNoneOnDryRun)): - sideEffects = admissionregv1.SideEffectClassNoneOnDryRun - case strings.ToLower(string(admissionregv1.SideEffectClassSome)): - sideEffects = admissionregv1.SideEffectClassSome - case "": - return nil - default: - return nil - } - return &sideEffects -} - -// reinvocationPolicy returns the reinvocationPolicy config for a mutating webhook. -func (c Config) reinvocationPolicy() *admissionregv1.ReinvocationPolicyType { - var reinvocationPolicy admissionregv1.ReinvocationPolicyType - switch strings.ToLower(c.ReinvocationPolicy) { - case strings.ToLower(string(admissionregv1.NeverReinvocationPolicy)): - reinvocationPolicy = admissionregv1.NeverReinvocationPolicy - case strings.ToLower(string(admissionregv1.IfNeededReinvocationPolicy)): - reinvocationPolicy = admissionregv1.IfNeededReinvocationPolicy - default: - return nil - } - return &reinvocationPolicy -} - -// webhookVersions returns the target API versions of the {Mutating,Validating}WebhookConfiguration objects for a webhook. -func (c Config) webhookVersions() ([]string, error) { - // If WebhookVersions is not specified, we default it to `v1`. - if len(c.WebhookVersions) == 0 { - return []string{defaultWebhookVersion}, nil - } - supportedWebhookVersions := sets.NewString(supportedWebhookVersions()...) - for _, version := range c.WebhookVersions { - if !supportedWebhookVersions.Has(version) { - return nil, fmt.Errorf("unsupported webhook version: %s", version) - } - } - return sets.NewString(c.WebhookVersions...).UnsortedList(), nil -} - -// +controllertools:marker:generateHelp - -// Generator generates (partial) {Mutating,Validating}WebhookConfiguration objects. -type Generator struct{} - -func (Generator) RegisterMarkers(into *markers.Registry) error { - if err := into.Register(ConfigDefinition); err != nil { - return err - } - into.AddHelp(ConfigDefinition, Config{}.Help()) - return nil -} - -func (Generator) Generate(ctx *genall.GenerationContext) error { - supportedWebhookVersions := supportedWebhookVersions() - mutatingCfgs := make(map[string][]admissionregv1.MutatingWebhook, len(supportedWebhookVersions)) - validatingCfgs := make(map[string][]admissionregv1.ValidatingWebhook, len(supportedWebhookVersions)) - for _, root := range ctx.Roots { - markerSet, err := markers.PackageMarkers(ctx.Collector, root) - if err != nil { - root.AddError(err) - } - - for _, cfg := range markerSet[ConfigDefinition.Name] { - cfg := cfg.(Config) - webhookVersions, err := cfg.webhookVersions() - if err != nil { - return err - } - if cfg.Mutating { - w, err := cfg.ToMutatingWebhook() - if err != nil { - return err - } - for _, webhookVersion := range webhookVersions { - mutatingCfgs[webhookVersion] = append(mutatingCfgs[webhookVersion], w) - } - } else { - w, err := cfg.ToValidatingWebhook() - if err != nil { - return err - } - for _, webhookVersion := range webhookVersions { - validatingCfgs[webhookVersion] = append(validatingCfgs[webhookVersion], w) - } - } - } - } - - versionedWebhooks := make(map[string][]interface{}, len(supportedWebhookVersions)) - for _, version := range supportedWebhookVersions { - if cfgs, ok := mutatingCfgs[version]; ok { - // The only possible version in supportedWebhookVersions is v1, - // so use it for all versioned types in this context. - objRaw := &admissionregv1.MutatingWebhookConfiguration{} - objRaw.SetGroupVersionKind(schema.GroupVersionKind{ - Group: admissionregv1.SchemeGroupVersion.Group, - Version: version, - Kind: "MutatingWebhookConfiguration", - }) - objRaw.SetName("mutating-webhook-configuration") - objRaw.Webhooks = cfgs - for i := range objRaw.Webhooks { - // SideEffects is required in admissionregistration/v1, if this is not set or set to `Some` or `Known`, - // return an error - if err := checkSideEffectsForV1(objRaw.Webhooks[i].SideEffects); err != nil { - return err - } - // AdmissionReviewVersions is required in admissionregistration/v1, if this is not set, - // return an error - if len(objRaw.Webhooks[i].AdmissionReviewVersions) == 0 { - return fmt.Errorf("AdmissionReviewVersions is mandatory for v1 {Mutating,Validating}WebhookConfiguration") - } - } - versionedWebhooks[version] = append(versionedWebhooks[version], objRaw) - } - - if cfgs, ok := validatingCfgs[version]; ok { - // The only possible version in supportedWebhookVersions is v1, - // so use it for all versioned types in this context. - objRaw := &admissionregv1.ValidatingWebhookConfiguration{} - objRaw.SetGroupVersionKind(schema.GroupVersionKind{ - Group: admissionregv1.SchemeGroupVersion.Group, - Version: version, - Kind: "ValidatingWebhookConfiguration", - }) - objRaw.SetName("validating-webhook-configuration") - objRaw.Webhooks = cfgs - for i := range objRaw.Webhooks { - // SideEffects is required in admissionregistration/v1, if this is not set or set to `Some` or `Known`, - // return an error - if err := checkSideEffectsForV1(objRaw.Webhooks[i].SideEffects); err != nil { - return err - } - // AdmissionReviewVersions is required in admissionregistration/v1, if this is not set, - // return an error - if len(objRaw.Webhooks[i].AdmissionReviewVersions) == 0 { - return fmt.Errorf("AdmissionReviewVersions is mandatory for v1 {Mutating,Validating}WebhookConfiguration") - } - } - versionedWebhooks[version] = append(versionedWebhooks[version], objRaw) - } - } - - for k, v := range versionedWebhooks { - var fileName string - if k == defaultWebhookVersion { - fileName = fmt.Sprintf("manifests.yaml") - } else { - fileName = fmt.Sprintf("manifests.%s.yaml", k) - } - if err := ctx.WriteYAML(fileName, v); err != nil { - return err - } - } - return nil -} - -func checkSideEffectsForV1(sideEffects *admissionregv1.SideEffectClass) error { - if sideEffects == nil { - return fmt.Errorf("SideEffects is required for creating v1 {Mutating,Validating}WebhookConfiguration") - } - if *sideEffects == admissionregv1.SideEffectClassUnknown || - *sideEffects == admissionregv1.SideEffectClassSome { - return fmt.Errorf("SideEffects should not be set to `Some` or `Unknown` for v1 {Mutating,Validating}WebhookConfiguration") - } - return nil -} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/webhook/zz_generated.markerhelp.go b/vendor/sigs.k8s.io/controller-tools/pkg/webhook/zz_generated.markerhelp.go deleted file mode 100644 index 411c58e1..00000000 --- a/vendor/sigs.k8s.io/controller-tools/pkg/webhook/zz_generated.markerhelp.go +++ /dev/null @@ -1,101 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright2019 The Kubernetes Authors. - -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. -*/ - -// Code generated by helpgen. DO NOT EDIT. - -package webhook - -import ( - "sigs.k8s.io/controller-tools/pkg/markers" -) - -func (Config) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "Webhook", - DetailedHelp: markers.DetailedHelp{ - Summary: "specifies how a webhook should be served. ", - Details: "It specifies only the details that are intrinsic to the application serving it (e.g. the resources it can handle, or the path it serves on).", - }, - FieldHelp: map[string]markers.DetailedHelp{ - "Mutating": { - Summary: "marks this as a mutating webhook (it's validating only if false) ", - Details: "Mutating webhooks are allowed to change the object in their response, and are called *before* all validating webhooks. Mutating webhooks may choose to reject an object, similarly to a validating webhook.", - }, - "FailurePolicy": { - Summary: "specifies what should happen if the API server cannot reach the webhook. ", - Details: "It may be either \"ignore\" (to skip the webhook and continue on) or \"fail\" (to reject the object in question).", - }, - "MatchPolicy": { - Summary: "defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" (match only if it exactly matches the specified rule) or \"Equivalent\" (match a request if it modifies a resource listed in rules, even via another API group or version).", - Details: "", - }, - "SideEffects": { - Summary: "specify whether calling the webhook will have side effects. This has an impact on dry runs and `kubectl diff`: if the sideEffect is \"Unknown\" (the default) or \"Some\", then the API server will not call the webhook on a dry-run request and fails instead. If the value is \"None\", then the webhook has no side effects and the API server will call it on dry-run. If the value is \"NoneOnDryRun\", then the webhook is responsible for inspecting the \"dryRun\" property of the AdmissionReview sent in the request, and avoiding side effects if that value is \"true.\"", - Details: "", - }, - "Groups": { - Summary: "specifies the API groups that this webhook receives requests for.", - Details: "", - }, - "Resources": { - Summary: "specifies the API resources that this webhook receives requests for.", - Details: "", - }, - "Verbs": { - Summary: "specifies the Kubernetes API verbs that this webhook receives requests for. ", - Details: "Only modification-like verbs may be specified. May be \"create\", \"update\", \"delete\", \"connect\", or \"*\" (for all).", - }, - "Versions": { - Summary: "specifies the API versions that this webhook receives requests for.", - Details: "", - }, - "Name": { - Summary: "indicates the name of this webhook configuration. Should be a domain with at least three segments separated by dots", - Details: "", - }, - "Path": { - Summary: "specifies that path that the API server should connect to this webhook on. Must be prefixed with a '/validate-' or '/mutate-' depending on the type, and followed by $GROUP-$VERSION-$KIND where all values are lower-cased and the periods in the group are substituted for hyphens. For example, a validating webhook path for type batch.tutorial.kubebuilder.io/v1,Kind=CronJob would be /validate-batch-tutorial-kubebuilder-io-v1-cronjob", - Details: "", - }, - "WebhookVersions": { - Summary: "specifies the target API versions of the {Mutating,Validating}WebhookConfiguration objects itself to generate. The only supported value is v1. Defaults to v1.", - Details: "", - }, - "AdmissionReviewVersions": { - Summary: "is an ordered list of preferred `AdmissionReview` versions the Webhook expects.", - Details: "", - }, - "ReinvocationPolicy": { - Summary: "allows mutating webhooks to request reinvocation after other mutations ", - Details: "To allow mutating admission plugins to observe changes made by other plugins, built-in mutating admission plugins are re-run if a mutating webhook modifies an object, and mutating webhooks can specify a reinvocationPolicy to control whether they are reinvoked as well.", - }, - }, - } -} - -func (Generator) Help() *markers.DefinitionHelp { - return &markers.DefinitionHelp{ - Category: "", - DetailedHelp: markers.DetailedHelp{ - Summary: "generates (partial) {Mutating,Validating}WebhookConfiguration objects.", - Details: "", - }, - FieldHelp: map[string]markers.DetailedHelp{}, - } -}