diff --git a/pkg/controller/provider/container/openstack/BUILD.bazel b/pkg/controller/provider/container/openstack/BUILD.bazel index 859730198..7f3f0fbd3 100644 --- a/pkg/controller/provider/container/openstack/BUILD.bazel +++ b/pkg/controller/provider/container/openstack/BUILD.bazel @@ -31,6 +31,7 @@ go_library( "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumetypes", "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors", "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers", + "//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials", "//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/projects", "//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/regions", "//vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens", diff --git a/pkg/controller/provider/container/openstack/client.go b/pkg/controller/provider/container/openstack/client.go index ec8c6904c..38ac21821 100644 --- a/pkg/controller/provider/container/openstack/client.go +++ b/pkg/controller/provider/container/openstack/client.go @@ -18,6 +18,7 @@ import ( "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumetypes" "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials" "github.com/gophercloud/gophercloud/openstack/identity/v3/projects" "github.com/gophercloud/gophercloud/openstack/identity/v3/regions" "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens" @@ -301,31 +302,10 @@ func (r *Client) list(object interface{}, listopts interface{}) (err error) { case *[]Project: object := object.(*[]Project) // TODO implement support multiple regions/projects sync per user - opts := listopts.(*ProjectListOpts) - opts.Name = r.getStringFromSecret(ProjectName) - allPages, err = projects.List(r.identityService, opts).AllPages() - if err != nil { - if !r.isForbidden(err) { - err = liberr.Wrap(err) - return - } - *object, err = r.getUserProjects() - if err != nil { - err = liberr.Wrap(err) - } - return - } - var projectList []projects.Project - projectList, err = projects.ExtractProjects(allPages) + *object, err = r.getUserProjects() if err != nil { err = liberr.Wrap(err) - return } - var instanceList []Project - for _, project := range projectList { - instanceList = append(instanceList, Project{project}) - } - *object = instanceList return case *[]Flavor: @@ -699,9 +679,38 @@ func (r *Client) getUserProjects() (userProjects []Project, err error) { err = liberr.Wrap(err) return } + + projectName := r.getStringFromSecret(ProjectName) + projectID := r.getStringFromSecret(ProjectID) + + if projectName == "" && projectID == "" { + applicationCredentialID := r.getStringFromSecret(ApplicationCredentialID) + if applicationCredentialID != "" { + var applicationCredential *applicationcredentials.ApplicationCredential + applicationCredential, err = applicationcredentials.Get(r.identityService, userID, applicationCredentialID).Extract() + if err != nil { + err = liberr.Wrap(err) + return + } + projectID = applicationCredential.ProjectID + } + applicationCredentialName := r.getStringFromSecret(ApplicationCredentialName) + if applicationCredentialName != "" { + var applicationCredentials []applicationcredentials.ApplicationCredential + allPages, err = applicationcredentials.List(r.identityService, userID, &applicationcredentials.ListOpts{Name: applicationCredentialName}).AllPages() + if err != nil { + err = liberr.Wrap(err) + return + } + applicationCredentials, err = applicationcredentials.ExtractApplicationCredentials(allPages) + projectID = applicationCredentials[0].ProjectID + } + + } + for _, project := range projectList { // TODO implement support multiple regions/projects sync per user - if project.Name == r.getStringFromSecret(ProjectName) { + if project.Name == projectName || project.ID == projectID { userProjects = append(userProjects, Project{project}) } } diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/BUILD.bazel b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/BUILD.bazel new file mode 100644 index 000000000..73f40742d --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/BUILD.bazel @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "applicationcredentials", + srcs = [ + "requests.go", + "results.go", + "urls.go", + ], + importmap = "github.com/konveyor/forklift-controller/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials", + importpath = "github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/gophercloud/gophercloud", + "//vendor/github.com/gophercloud/gophercloud/pagination", + ], +) diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/requests.go new file mode 100644 index 000000000..be62af7f7 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/requests.go @@ -0,0 +1,136 @@ +package applicationcredentials + +import ( + "time" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to +// the List request +type ListOptsBuilder interface { + ToApplicationCredentialListQuery() (string, error) +} + +// ListOpts provides options to filter the List results. +type ListOpts struct { + // Name filters the response by an application credential name + Name string `q:"name"` +} + +// ToApplicationCredentialListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToApplicationCredentialListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// List enumerates the ApplicationCredentials to which the current token has access. +func List(client *gophercloud.ServiceClient, userID string, opts ListOptsBuilder) pagination.Pager { + url := listURL(client, userID) + if opts != nil { + query, err := opts.ToApplicationCredentialListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return ApplicationCredentialPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// Get retrieves details on a single user, by ID. +func Get(client *gophercloud.ServiceClient, userID string, id string) (r GetResult) { + resp, err := client.Get(getURL(client, userID, id), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// CreateOptsBuilder allows extensions to add additional parameters to +// the Create request. +type CreateOptsBuilder interface { + ToApplicationCredentialCreateMap() (map[string]interface{}, error) +} + +// CreateOpts provides options used to create an application credential. +type CreateOpts struct { + // The name of the application credential. + Name string `json:"name,omitempty" required:"true"` + // A description of the application credential’s purpose. + Description string `json:"description,omitempty"` + // A flag indicating whether the application credential may be used for creation or destruction of other application credentials or trusts. + // Defaults to false + Unrestricted bool `json:"unrestricted"` + // The secret for the application credential, either generated by the server or provided by the user. + // This is only ever shown once in the response to a create request. It is not stored nor ever shown again. + // If the secret is lost, a new application credential must be created. + Secret string `json:"secret,omitempty"` + // A list of one or more roles that this application credential has associated with its project. + // A token using this application credential will have these same roles. + Roles []Role `json:"roles,omitempty"` + // A list of access rules objects. + AccessRules []AccessRule `json:"access_rules,omitempty"` + // The expiration time of the application credential, if one was specified. + ExpiresAt *time.Time `json:"-"` +} + +// ToApplicationCredentialCreateMap formats a CreateOpts into a create request. +func (opts CreateOpts) ToApplicationCredentialCreateMap() (map[string]interface{}, error) { + parent := "application_credential" + b, err := gophercloud.BuildRequestBody(opts, parent) + if err != nil { + return nil, err + } + + if opts.ExpiresAt != nil { + if v, ok := b[parent].(map[string]interface{}); ok { + v["expires_at"] = opts.ExpiresAt.Format(gophercloud.RFC3339MilliNoZ) + } + } + + return b, nil +} + +// Create creates a new ApplicationCredential. +func Create(client *gophercloud.ServiceClient, userID string, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToApplicationCredentialCreateMap() + if err != nil { + r.Err = err + return + } + resp, err := client.Post(createURL(client, userID), &b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{201}, + }) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// Delete deletes an application credential. +func Delete(client *gophercloud.ServiceClient, userID string, id string) (r DeleteResult) { + resp, err := client.Delete(deleteURL(client, userID, id), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// ListAccessRules enumerates the AccessRules to which the current user has access. +func ListAccessRules(client *gophercloud.ServiceClient, userID string) pagination.Pager { + url := listAccessRulesURL(client, userID) + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return AccessRulePage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// GetAccessRule retrieves details on a single access rule by ID. +func GetAccessRule(client *gophercloud.ServiceClient, userID string, id string) (r GetAccessRuleResult) { + resp, err := client.Get(getAccessRuleURL(client, userID, id), &r.Body, nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} + +// DeleteAccessRule deletes an access rule. +func DeleteAccessRule(client *gophercloud.ServiceClient, userID string, id string) (r DeleteResult) { + resp, err := client.Delete(deleteAccessRuleURL(client, userID, id), nil) + _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/results.go new file mode 100644 index 000000000..8ed389d13 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/results.go @@ -0,0 +1,201 @@ +package applicationcredentials + +import ( + "encoding/json" + "time" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +type Role struct { + // DomainID is the domain ID the role belongs to. + DomainID string `json:"domain_id,omitempty"` + // ID is the unique ID of the role. + ID string `json:"id,omitempty"` + // Name is the role name + Name string `json:"name,omitempty"` +} + +// ApplicationCredential represents the access rule object +type AccessRule struct { + // The ID of the access rule + ID string `json:"id,omitempty"` + // The API path that the application credential is permitted to access + Path string `json:"path,omitempty"` + // The request method that the application credential is permitted to use for a + // given API endpoint + Method string `json:"method,omitempty"` + // The service type identifier for the service that the application credential + // is permitted to access + Service string `json:"service,omitempty"` +} + +// ApplicationCredential represents the application credential object +type ApplicationCredential struct { + // The ID of the application credential. + ID string `json:"id"` + // The name of the application credential. + Name string `json:"name"` + // A description of the application credential’s purpose. + Description string `json:"description"` + // A flag indicating whether the application credential may be used for creation or destruction of other application credentials or trusts. + // Defaults to false + Unrestricted bool `json:"unrestricted"` + // The secret for the application credential, either generated by the server or provided by the user. + // This is only ever shown once in the response to a create request. It is not stored nor ever shown again. + // If the secret is lost, a new application credential must be created. + Secret string `json:"secret"` + // The ID of the project the application credential was created for and that authentication requests using this application credential will be scoped to. + ProjectID string `json:"project_id"` + // A list of one or more roles that this application credential has associated with its project. + // A token using this application credential will have these same roles. + Roles []Role `json:"roles"` + // The expiration time of the application credential, if one was specified. + ExpiresAt time.Time `json:"-"` + // A list of access rules objects. + AccessRules []AccessRule `json:"access_rules,omitempty"` + // Links contains referencing links to the application credential. + Links map[string]interface{} `json:"links"` +} + +func (r *ApplicationCredential) UnmarshalJSON(b []byte) error { + type tmp ApplicationCredential + var s struct { + tmp + ExpiresAt gophercloud.JSONRFC3339MilliNoZ `json:"expires_at"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = ApplicationCredential(s.tmp) + + r.ExpiresAt = time.Time(s.ExpiresAt) + + return nil +} + +type applicationCredentialResult struct { + gophercloud.Result +} + +// GetResult is the response from a Get operation. Call its Extract method +// to interpret it as an ApplicationCredential. +type GetResult struct { + applicationCredentialResult +} + +// CreateResult is the response from a Create operation. Call its Extract method +// to interpret it as an ApplicationCredential. +type CreateResult struct { + applicationCredentialResult +} + +// DeleteResult is the response from a Delete operation. Call its ExtractErr to +// determine if the request succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// an ApplicationCredentialPage is a single page of an ApplicationCredential results. +type ApplicationCredentialPage struct { + pagination.LinkedPageBase +} + +// IsEmpty determines whether or not a an ApplicationCredentialPage contains any results. +func (r ApplicationCredentialPage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + applicationCredentials, err := ExtractApplicationCredentials(r) + return len(applicationCredentials) == 0, err +} + +// NextPageURL extracts the "next" link from the links section of the result. +func (r ApplicationCredentialPage) NextPageURL() (string, error) { + var s struct { + Links struct { + Next string `json:"next"` + Previous string `json:"previous"` + } `json:"links"` + } + err := r.ExtractInto(&s) + if err != nil { + return "", err + } + return s.Links.Next, err +} + +// Extractan ApplicationCredentials returns a slice of ApplicationCredentials contained in a single page of results. +func ExtractApplicationCredentials(r pagination.Page) ([]ApplicationCredential, error) { + var s struct { + ApplicationCredentials []ApplicationCredential `json:"application_credentials"` + } + err := (r.(ApplicationCredentialPage)).ExtractInto(&s) + return s.ApplicationCredentials, err +} + +// Extract interprets any application_credential results as an ApplicationCredential. +func (r applicationCredentialResult) Extract() (*ApplicationCredential, error) { + var s struct { + ApplicationCredential *ApplicationCredential `json:"application_credential"` + } + err := r.ExtractInto(&s) + return s.ApplicationCredential, err +} + +// GetAccessRuleResult is the response from a Get operation. Call its Extract method +// to interpret it as an AccessRule. +type GetAccessRuleResult struct { + gophercloud.Result +} + +// an AccessRulePage is a single page of an AccessRule results. +type AccessRulePage struct { + pagination.LinkedPageBase +} + +// IsEmpty determines whether or not a an AccessRulePage contains any results. +func (r AccessRulePage) IsEmpty() (bool, error) { + if r.StatusCode == 204 { + return true, nil + } + + accessRules, err := ExtractAccessRules(r) + return len(accessRules) == 0, err +} + +// NextPageURL extracts the "next" link from the links section of the result. +func (r AccessRulePage) NextPageURL() (string, error) { + var s struct { + Links struct { + Next string `json:"next"` + Previous string `json:"previous"` + } `json:"links"` + } + err := r.ExtractInto(&s) + if err != nil { + return "", err + } + return s.Links.Next, err +} + +// ExtractAccessRules returns a slice of AccessRules contained in a single page of results. +func ExtractAccessRules(r pagination.Page) ([]AccessRule, error) { + var s struct { + AccessRules []AccessRule `json:"access_rules"` + } + err := (r.(AccessRulePage)).ExtractInto(&s) + return s.AccessRules, err +} + +// Extract interprets any access_rule results as an AccessRule. +func (r GetAccessRuleResult) Extract() (*AccessRule, error) { + var s struct { + AccessRule *AccessRule `json:"access_rule"` + } + err := r.ExtractInto(&s) + return s.AccessRule, err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/urls.go new file mode 100644 index 000000000..f809385f2 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials/urls.go @@ -0,0 +1,31 @@ +package applicationcredentials + +import "github.com/gophercloud/gophercloud" + +func listURL(client *gophercloud.ServiceClient, userID string) string { + return client.ServiceURL("users", userID, "application_credentials") +} + +func getURL(client *gophercloud.ServiceClient, userID string, id string) string { + return client.ServiceURL("users", userID, "application_credentials", id) +} + +func createURL(client *gophercloud.ServiceClient, userID string) string { + return client.ServiceURL("users", userID, "application_credentials") +} + +func deleteURL(client *gophercloud.ServiceClient, userID string, id string) string { + return client.ServiceURL("users", userID, "application_credentials", id) +} + +func listAccessRulesURL(client *gophercloud.ServiceClient, userID string) string { + return client.ServiceURL("users", userID, "access_rules") +} + +func getAccessRuleURL(client *gophercloud.ServiceClient, userID string, id string) string { + return client.ServiceURL("users", userID, "access_rules", id) +} + +func deleteAccessRuleURL(client *gophercloud.ServiceClient, userID string, id string) string { + return client.ServiceURL("users", userID, "access_rules", id) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 8a8a9c12c..dea878f30 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -99,6 +99,7 @@ github.com/gophercloud/gophercloud/openstack/compute/v2/flavors github.com/gophercloud/gophercloud/openstack/compute/v2/servers github.com/gophercloud/gophercloud/openstack/identity/v2/tenants github.com/gophercloud/gophercloud/openstack/identity/v2/tokens +github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1 github.com/gophercloud/gophercloud/openstack/identity/v3/groups @@ -817,7 +818,6 @@ sigs.k8s.io/controller-runtime/pkg/internal/objectutil 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/log/zap sigs.k8s.io/controller-runtime/pkg/manager sigs.k8s.io/controller-runtime/pkg/manager/signals sigs.k8s.io/controller-runtime/pkg/metrics diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/BUILD.bazel b/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/BUILD.bazel deleted file mode 100644 index 1d9b14ea3..000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/BUILD.bazel +++ /dev/null @@ -1,23 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "zap", - srcs = [ - "flags.go", - "kube_helpers.go", - "zap.go", - ], - importmap = "github.com/konveyor/forklift-controller/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap", - importpath = "sigs.k8s.io/controller-runtime/pkg/log/zap", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/go-logr/logr", - "//vendor/github.com/go-logr/zapr", - "//vendor/go.uber.org/zap", - "//vendor/go.uber.org/zap/buffer", - "//vendor/go.uber.org/zap/zapcore", - "//vendor/k8s.io/apimachinery/pkg/api/meta", - "//vendor/k8s.io/apimachinery/pkg/runtime", - "//vendor/k8s.io/apimachinery/pkg/types", - ], -) diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/flags.go b/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/flags.go deleted file mode 100644 index 333965507..000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/flags.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -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 zap contains helpers for setting up a new logr.Logger instance -// using the Zap logging framework. -package zap - -import ( - "flag" - "fmt" - "strconv" - "strings" - - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -var levelStrings = map[string]zapcore.Level{ - "debug": zap.DebugLevel, - "info": zap.InfoLevel, - "error": zap.ErrorLevel, -} - -var stackLevelStrings = map[string]zapcore.Level{ - "info": zap.InfoLevel, - "error": zap.ErrorLevel, - "panic": zap.PanicLevel, -} - -type encoderFlag struct { - setFunc func(NewEncoderFunc) - value string -} - -var _ flag.Value = &encoderFlag{} - -func (ev *encoderFlag) String() string { - return ev.value -} - -func (ev *encoderFlag) Type() string { - return "encoder" -} - -func (ev *encoderFlag) Set(flagValue string) error { - val := strings.ToLower(flagValue) - switch val { - case "json": - ev.setFunc(newJSONEncoder) - case "console": - ev.setFunc(newConsoleEncoder) - default: - return fmt.Errorf("invalid encoder value \"%s\"", flagValue) - } - ev.value = flagValue - return nil -} - -type levelFlag struct { - setFunc func(zapcore.LevelEnabler) - value string -} - -var _ flag.Value = &levelFlag{} - -func (ev *levelFlag) Set(flagValue string) error { - level, validLevel := levelStrings[strings.ToLower(flagValue)] - if !validLevel { - logLevel, err := strconv.Atoi(flagValue) - if err != nil { - return fmt.Errorf("invalid log level \"%s\"", flagValue) - } - if logLevel > 0 { - intLevel := -1 * logLevel - ev.setFunc(zap.NewAtomicLevelAt(zapcore.Level(int8(intLevel)))) - } else { - return fmt.Errorf("invalid log level \"%s\"", flagValue) - } - } else { - ev.setFunc(zap.NewAtomicLevelAt(level)) - } - ev.value = flagValue - return nil -} - -func (ev *levelFlag) String() string { - return ev.value -} - -func (ev *levelFlag) Type() string { - return "level" -} - -type stackTraceFlag struct { - setFunc func(zapcore.LevelEnabler) - value string -} - -var _ flag.Value = &stackTraceFlag{} - -func (ev *stackTraceFlag) Set(flagValue string) error { - level, validLevel := stackLevelStrings[strings.ToLower(flagValue)] - if !validLevel { - return fmt.Errorf("invalid stacktrace level \"%s\"", flagValue) - } - ev.setFunc(zap.NewAtomicLevelAt(level)) - ev.value = flagValue - return nil -} - -func (ev *stackTraceFlag) String() string { - return ev.value -} - -func (ev *stackTraceFlag) Type() string { - return "level" -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go b/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go deleted file mode 100644 index 765327d62..000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/kube_helpers.go +++ /dev/null @@ -1,127 +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 zap - -import ( - "fmt" - - "go.uber.org/zap/buffer" - "go.uber.org/zap/zapcore" - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" -) - -// KubeAwareEncoder is a Kubernetes-aware Zap Encoder. -// Instead of trying to force Kubernetes objects to implement -// ObjectMarshaller, we just implement a wrapper around a normal -// ObjectMarshaller that checks for Kubernetes objects. -type KubeAwareEncoder struct { - // Encoder is the zapcore.Encoder that this encoder delegates to - zapcore.Encoder - - // Verbose controls whether or not the full object is printed. - // If false, only name, namespace, api version, and kind are printed. - // Otherwise, the full object is logged. - Verbose bool -} - -// namespacedNameWrapper is a zapcore.ObjectMarshaler for Kubernetes NamespacedName. -type namespacedNameWrapper struct { - types.NamespacedName -} - -func (w namespacedNameWrapper) MarshalLogObject(enc zapcore.ObjectEncoder) error { - if w.Namespace != "" { - enc.AddString("namespace", w.Namespace) - } - - enc.AddString("name", w.Name) - - return nil -} - -// kubeObjectWrapper is a zapcore.ObjectMarshaler for Kubernetes objects. -type kubeObjectWrapper struct { - obj runtime.Object -} - -// MarshalLogObject implements zapcore.ObjectMarshaler. -func (w kubeObjectWrapper) MarshalLogObject(enc zapcore.ObjectEncoder) error { - // TODO(directxman12): log kind and apiversion if not set explicitly (common case) - // -- needs an a scheme to convert to the GVK. - if gvk := w.obj.GetObjectKind().GroupVersionKind(); gvk.Version != "" { - enc.AddString("apiVersion", gvk.GroupVersion().String()) - enc.AddString("kind", gvk.Kind) - } - - objMeta, err := meta.Accessor(w.obj) - if err != nil { - return fmt.Errorf("got runtime.Object without object metadata: %v", w.obj) - } - - if ns := objMeta.GetNamespace(); ns != "" { - enc.AddString("namespace", ns) - } - enc.AddString("name", objMeta.GetName()) - - return nil -} - -// NB(directxman12): can't just override AddReflected, since the encoder calls AddReflected on itself directly - -// Clone implements zapcore.Encoder. -func (k *KubeAwareEncoder) Clone() zapcore.Encoder { - return &KubeAwareEncoder{ - Encoder: k.Encoder.Clone(), - } -} - -// EncodeEntry implements zapcore.Encoder. -func (k *KubeAwareEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) { - if k.Verbose { - // Kubernetes objects implement fmt.Stringer, so if we - // want verbose output, just delegate to that. - return k.Encoder.EncodeEntry(entry, fields) - } - - for i, field := range fields { - // intercept stringer fields that happen to be Kubernetes runtime.Object or - // types.NamespacedName values (Kubernetes runtime.Objects commonly - // implement String, apparently). - // *unstructured.Unstructured does NOT implement fmt.Striger interface. - // We have handle it specially. - if field.Type == zapcore.StringerType || field.Type == zapcore.ReflectType { - switch val := field.Interface.(type) { - case runtime.Object: - fields[i] = zapcore.Field{ - Type: zapcore.ObjectMarshalerType, - Key: field.Key, - Interface: kubeObjectWrapper{obj: val}, - } - case types.NamespacedName: - fields[i] = zapcore.Field{ - Type: zapcore.ObjectMarshalerType, - Key: field.Key, - Interface: namespacedNameWrapper{NamespacedName: val}, - } - } - } - } - - return k.Encoder.EncodeEntry(entry, fields) -} diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go b/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go deleted file mode 100644 index 22eb5d771..000000000 --- a/vendor/sigs.k8s.io/controller-runtime/pkg/log/zap/zap.go +++ /dev/null @@ -1,287 +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 zap contains helpers for setting up a new logr.Logger instance -// using the Zap logging framework. -package zap - -import ( - "flag" - "io" - "os" - "time" - - "github.com/go-logr/logr" - "github.com/go-logr/zapr" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// EncoderConfigOption is a function that can modify a `zapcore.EncoderConfig`. -type EncoderConfigOption func(*zapcore.EncoderConfig) - -// NewEncoderFunc is a function that creates an Encoder using the provided EncoderConfigOptions. -type NewEncoderFunc func(...EncoderConfigOption) zapcore.Encoder - -// New returns a brand new Logger configured with Opts. It -// uses KubeAwareEncoder which adds Type information and -// Namespace/Name to the log. -func New(opts ...Opts) logr.Logger { - return zapr.NewLogger(NewRaw(opts...)) -} - -// Opts allows to manipulate Options. -type Opts func(*Options) - -// UseDevMode sets the logger to use (or not use) development mode (more -// human-readable output, extra stack traces and logging information, etc). -// See Options.Development. -func UseDevMode(enabled bool) Opts { - return func(o *Options) { - o.Development = enabled - } -} - -// WriteTo configures the logger to write to the given io.Writer, instead of standard error. -// See Options.DestWriter. -func WriteTo(out io.Writer) Opts { - return func(o *Options) { - o.DestWriter = out - } -} - -// Encoder configures how the logger will encode the output e.g JSON or console. -// See Options.Encoder. -func Encoder(encoder zapcore.Encoder) func(o *Options) { - return func(o *Options) { - o.Encoder = encoder - } -} - -// JSONEncoder configures the logger to use a JSON Encoder. -func JSONEncoder(opts ...EncoderConfigOption) func(o *Options) { - return func(o *Options) { - o.Encoder = newJSONEncoder(opts...) - } -} - -func newJSONEncoder(opts ...EncoderConfigOption) zapcore.Encoder { - encoderConfig := zap.NewProductionEncoderConfig() - for _, opt := range opts { - opt(&encoderConfig) - } - return zapcore.NewJSONEncoder(encoderConfig) -} - -// ConsoleEncoder configures the logger to use a Console encoder. -func ConsoleEncoder(opts ...EncoderConfigOption) func(o *Options) { - return func(o *Options) { - o.Encoder = newConsoleEncoder(opts...) - } -} - -func newConsoleEncoder(opts ...EncoderConfigOption) zapcore.Encoder { - encoderConfig := zap.NewDevelopmentEncoderConfig() - for _, opt := range opts { - opt(&encoderConfig) - } - return zapcore.NewConsoleEncoder(encoderConfig) -} - -// Level sets Options.Level, which configures the the minimum enabled logging level e.g Debug, Info. -// A zap log level should be multiplied by -1 to get the logr verbosity. -// For example, to get logr verbosity of 3, pass zapcore.Level(-3) to this Opts. -// See https://pkg.go.dev/github.com/go-logr/zapr for how zap level relates to logr verbosity. -func Level(level zapcore.LevelEnabler) func(o *Options) { - return func(o *Options) { - o.Level = level - } -} - -// StacktraceLevel sets Options.StacktraceLevel, which configures the logger to record a stack trace -// for all messages at or above a given level. -// See the Level Opts for the relationship of zap log level to logr verbosity. -func StacktraceLevel(stacktraceLevel zapcore.LevelEnabler) func(o *Options) { - return func(o *Options) { - o.StacktraceLevel = stacktraceLevel - } -} - -// RawZapOpts allows appending arbitrary zap.Options to configure the underlying zap logger. -// See Options.ZapOpts. -func RawZapOpts(zapOpts ...zap.Option) func(o *Options) { - return func(o *Options) { - o.ZapOpts = append(o.ZapOpts, zapOpts...) - } -} - -// Options contains all possible settings. -type Options struct { - // Development configures the logger to use a Zap development config - // (stacktraces on warnings, no sampling), otherwise a Zap production - // config will be used (stacktraces on errors, sampling). - Development bool - // Encoder configures how Zap will encode the output. Defaults to - // console when Development is true and JSON otherwise - Encoder zapcore.Encoder - // EncoderConfigOptions can modify the EncoderConfig needed to initialize an Encoder. - // See https://godoc.org/go.uber.org/zap/zapcore#EncoderConfig for the list of options - // that can be configured. - // Note that the EncoderConfigOptions are not applied when the Encoder option is already set. - EncoderConfigOptions []EncoderConfigOption - // NewEncoder configures Encoder using the provided EncoderConfigOptions. - // Note that the NewEncoder function is not used when the Encoder option is already set. - NewEncoder NewEncoderFunc - // DestWriter controls the destination of the log output. Defaults to - // os.Stderr. - DestWriter io.Writer - // DestWritter controls the destination of the log output. Defaults to - // os.Stderr. - // - // Deprecated: Use DestWriter instead - DestWritter io.Writer - // Level configures the verbosity of the logging. - // Defaults to Debug when Development is true and Info otherwise. - // A zap log level should be multiplied by -1 to get the logr verbosity. - // For example, to get logr verbosity of 3, set this field to zapcore.Level(-3). - // See https://pkg.go.dev/github.com/go-logr/zapr for how zap level relates to logr verbosity. - Level zapcore.LevelEnabler - // StacktraceLevel is the level at and above which stacktraces will - // be recorded for all messages. Defaults to Warn when Development - // is true and Error otherwise. - // See Level for the relationship of zap log level to logr verbosity. - StacktraceLevel zapcore.LevelEnabler - // ZapOpts allows passing arbitrary zap.Options to configure on the - // underlying Zap logger. - ZapOpts []zap.Option -} - -// addDefaults adds defaults to the Options. -func (o *Options) addDefaults() { - if o.DestWriter == nil && o.DestWritter == nil { - o.DestWriter = os.Stderr - } else if o.DestWriter == nil && o.DestWritter != nil { - // while misspelled DestWritter is deprecated but still not removed - o.DestWriter = o.DestWritter - } - - if o.Development { - if o.NewEncoder == nil { - o.NewEncoder = newConsoleEncoder - } - if o.Level == nil { - lvl := zap.NewAtomicLevelAt(zap.DebugLevel) - o.Level = &lvl - } - if o.StacktraceLevel == nil { - lvl := zap.NewAtomicLevelAt(zap.WarnLevel) - o.StacktraceLevel = &lvl - } - o.ZapOpts = append(o.ZapOpts, zap.Development()) - } else { - if o.NewEncoder == nil { - o.NewEncoder = newJSONEncoder - } - if o.Level == nil { - lvl := zap.NewAtomicLevelAt(zap.InfoLevel) - o.Level = &lvl - } - if o.StacktraceLevel == nil { - lvl := zap.NewAtomicLevelAt(zap.ErrorLevel) - o.StacktraceLevel = &lvl - } - // Disable sampling for increased Debug levels. Otherwise, this will - // cause index out of bounds errors in the sampling code. - if !o.Level.Enabled(zapcore.Level(-2)) { - o.ZapOpts = append(o.ZapOpts, - zap.WrapCore(func(core zapcore.Core) zapcore.Core { - return zapcore.NewSamplerWithOptions(core, time.Second, 100, 100) - })) - } - } - if o.Encoder == nil { - o.Encoder = o.NewEncoder(o.EncoderConfigOptions...) - } - o.ZapOpts = append(o.ZapOpts, zap.AddStacktrace(o.StacktraceLevel)) -} - -// NewRaw returns a new zap.Logger configured with the passed Opts -// or their defaults. It uses KubeAwareEncoder which adds Type -// information and Namespace/Name to the log. -func NewRaw(opts ...Opts) *zap.Logger { - o := &Options{} - for _, opt := range opts { - opt(o) - } - o.addDefaults() - - // this basically mimics NewConfig, but with a custom sink - sink := zapcore.AddSync(o.DestWriter) - - o.ZapOpts = append(o.ZapOpts, zap.AddCallerSkip(1), zap.ErrorOutput(sink)) - log := zap.New(zapcore.NewCore(&KubeAwareEncoder{Encoder: o.Encoder, Verbose: o.Development}, sink, o.Level)) - log = log.WithOptions(o.ZapOpts...) - return log -} - -// BindFlags will parse the given flagset for zap option flags and set the log options accordingly -// zap-devel: Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn) -// Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) -// zap-encoder: Zap log encoding (one of 'json' or 'console') -// zap-log-level: Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', -// or any integer value > 0 which corresponds to custom debug levels of increasing verbosity") -// zap-stacktrace-level: Zap Level at and above which stacktraces are captured (one of 'info', 'error' or 'panic') -func (o *Options) BindFlags(fs *flag.FlagSet) { - // Set Development mode value - fs.BoolVar(&o.Development, "zap-devel", o.Development, - "Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). "+ - "Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)") - - // Set Encoder value - var encVal encoderFlag - encVal.setFunc = func(fromFlag NewEncoderFunc) { - o.NewEncoder = fromFlag - } - fs.Var(&encVal, "zap-encoder", "Zap log encoding (one of 'json' or 'console')") - - // Set the Log Level - var levelVal levelFlag - levelVal.setFunc = func(fromFlag zapcore.LevelEnabler) { - o.Level = fromFlag - } - fs.Var(&levelVal, "zap-log-level", - "Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', "+ - "or any integer value > 0 which corresponds to custom debug levels of increasing verbosity") - - // Set the StrackTrace Level - var stackVal stackTraceFlag - stackVal.setFunc = func(fromFlag zapcore.LevelEnabler) { - o.StacktraceLevel = fromFlag - } - fs.Var(&stackVal, "zap-stacktrace-level", - "Zap Level at and above which stacktraces are captured (one of 'info', 'error', 'panic').") -} - -// UseFlagOptions configures the logger to use the Options set by parsing zap option flags from the CLI. -// opts := zap.Options{} -// opts.BindFlags(flag.CommandLine) -// flag.Parse() -// log := zap.New(zap.UseFlagOptions(&opts)) -func UseFlagOptions(in *Options) Opts { - return func(o *Options) { - *o = *in - } -}