Upgrade k8s package verison (#5358)

* upgrade k8s package version

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

* Script upgrade and code formatting.

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
hongzhouzi
2022-11-15 14:56:38 +08:00
committed by GitHub
parent 5f91c1663a
commit 44167aa47a
3106 changed files with 321340 additions and 172080 deletions

View File

@@ -0,0 +1,123 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 docker
import (
"os"
"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/credentials"
"github.com/pkg/errors"
"oras.land/oras-go/pkg/auth"
)
// Client provides authentication operations for docker registries.
type Client struct {
configs []*configfile.ConfigFile
}
// NewClient creates a new auth client based on provided config paths.
// If not config path is provided, the default path is used.
// Credentials are read from the first config and fall backs to next.
// All changes will only be written to the first config file.
func NewClient(configPaths ...string) (auth.Client, error) {
if len(configPaths) == 0 {
cfg, err := config.Load(config.Dir())
if err != nil {
return nil, err
}
if !cfg.ContainsAuth() {
cfg.CredentialsStore = credentials.DetectDefaultStore(cfg.CredentialsStore)
}
return &Client{
configs: []*configfile.ConfigFile{cfg},
}, nil
}
var configs []*configfile.ConfigFile
for _, path := range configPaths {
cfg, err := loadConfigFile(path)
if err != nil {
return nil, errors.Wrap(err, path)
}
configs = append(configs, cfg)
}
return &Client{
configs: configs,
}, nil
}
// NewClientWithDockerFallback creates a new auth client
// which falls back on Docker's default config path.
// This allows support for ~/.docker/config.json as a fallback,
// as well as support for the DOCKER_CONFIG environment variable.
func NewClientWithDockerFallback(configPaths ...string) (auth.Client, error) {
if len(configPaths) == 0 {
return NewClient()
}
var configs []*configfile.ConfigFile
for _, path := range configPaths {
cfg, err := loadConfigFile(path)
if err != nil {
return nil, errors.Wrap(err, path)
}
configs = append(configs, cfg)
}
// Add the Docker default config last
dockerFallbackCfg, err := config.Load(config.Dir())
if err != nil {
return nil, err
}
if !dockerFallbackCfg.ContainsAuth() {
dockerFallbackCfg.CredentialsStore = credentials.DetectDefaultStore(dockerFallbackCfg.CredentialsStore)
}
configs = append(configs, dockerFallbackCfg)
return &Client{
configs: configs,
}, nil
}
func (c *Client) primaryCredentialsStore(hostname string) credentials.Store {
return c.configs[0].GetCredentialsStore(hostname)
}
// loadConfigFile reads the configuration files from the given path.
func loadConfigFile(path string) (*configfile.ConfigFile, error) {
cfg := configfile.New(path)
if _, err := os.Stat(path); err == nil {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
if err := cfg.LoadFromReader(file); err != nil {
return nil, err
}
} else if !os.IsNotExist(err) {
return nil, err
}
if !cfg.ContainsAuth() {
cfg.CredentialsStore = credentials.DetectDefaultStore(cfg.CredentialsStore)
}
return cfg, nil
}

View File

@@ -0,0 +1,103 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 docker
import (
"context"
ctypes "github.com/docker/cli/cli/config/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/registry"
iface "oras.land/oras-go/pkg/auth"
)
const IndexHostname = "index.docker.io"
// Login logs in to a docker registry identified by the hostname.
// Deprecated: use LoginWithOpts
func (c *Client) Login(ctx context.Context, hostname, username, secret string, insecure bool) error {
settings := &iface.LoginSettings{
Context: ctx,
Hostname: hostname,
Username: username,
Secret: secret,
Insecure: insecure,
}
return c.login(settings)
}
// LoginWithOpts logs in to a docker registry identified by the hostname with custom options.
func (c *Client) LoginWithOpts(options ...iface.LoginOption) error {
settings := &iface.LoginSettings{}
for _, option := range options {
option(settings)
}
return c.login(settings)
}
func (c *Client) login(settings *iface.LoginSettings) error {
hostname := resolveHostname(settings.Hostname)
cred := types.AuthConfig{
Username: settings.Username,
ServerAddress: hostname,
}
if settings.Username == "" {
cred.IdentityToken = settings.Secret
} else {
cred.Password = settings.Secret
}
opts := registry.ServiceOptions{}
if settings.Insecure {
opts.InsecureRegistries = []string{hostname}
}
// Login to ensure valid credential
remote, err := registry.NewService(opts)
if err != nil {
return err
}
ctx := settings.Context
if ctx == nil {
ctx = context.Background()
}
userAgent := settings.UserAgent
if userAgent == "" {
userAgent = "oras"
}
var token string
if (settings.CertFile != "" && settings.KeyFile != "") || settings.CAFile != "" {
_, token, err = c.loginWithTLS(ctx, remote, settings.CertFile, settings.KeyFile, settings.CAFile, &cred, userAgent)
} else {
_, token, err = remote.Auth(ctx, &cred, userAgent)
}
if err != nil {
return err
}
if token != "" {
cred.Username = ""
cred.Password = ""
cred.IdentityToken = token
}
// Store credential
return c.primaryCredentialsStore(hostname).Store(ctypes.AuthConfig(cred))
}

View File

@@ -0,0 +1,220 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 docker
import (
"context"
"crypto/tls"
"fmt"
"net"
"net/http"
"net/url"
"strings"
"time"
"github.com/docker/distribution/registry/api/errcode"
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/api/types"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/registry"
"github.com/docker/go-connections/tlsconfig"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// The following functions are adapted from github.com/docker/docker/registry
// We need these to support passing in a transport that has custom TLS configuration
// They are not exposed in the docker/registry package that's why they are copied here
type loginCredentialStore struct {
authConfig *types.AuthConfig
}
func (lcs loginCredentialStore) Basic(*url.URL) (string, string) {
return lcs.authConfig.Username, lcs.authConfig.Password
}
func (lcs loginCredentialStore) RefreshToken(*url.URL, string) string {
return lcs.authConfig.IdentityToken
}
func (lcs loginCredentialStore) SetRefreshToken(u *url.URL, service, token string) {
lcs.authConfig.IdentityToken = token
}
// loginWithTLS tries to login to the v2 registry server.
// A custom tls.Config is used to override the default TLS configuration of the different registry endpoints.
// The tls.Config is created using the provided certificate, certificate key and certificate authority.
func (c *Client) loginWithTLS(ctx context.Context, service registry.Service, certFile, keyFile, caFile string, authConfig *types.AuthConfig, userAgent string) (string, string, error) {
tlsConfig, err := tlsconfig.Client(tlsconfig.Options{CAFile: caFile, CertFile: certFile, KeyFile: keyFile})
if err != nil {
return "", "", err
}
endpoints, err := c.getEndpoints(authConfig.ServerAddress, service)
if err != nil {
return "", "", err
}
var status, token string
for _, endpoint := range endpoints {
endpoint.TLSConfig = tlsConfig
status, token, err = loginV2(authConfig, endpoint, userAgent)
if err != nil {
if isNotAuthorizedError(err) {
return "", "", err
}
logrus.WithError(err).Infof("Error logging in to endpoint, trying next endpoint")
continue
}
return status, token, nil
}
return "", "", err
}
// getEndpoints returns the endpoints for the given hostname.
func (c *Client) getEndpoints(address string, service registry.Service) ([]registry.APIEndpoint, error) {
var registryHostName = IndexHostname
if address != "" {
if !strings.HasPrefix(address, "https://") && !strings.HasPrefix(address, "http://") {
address = fmt.Sprintf("https://%s", address)
}
u, err := url.Parse(address)
if err != nil {
return nil, errdefs.InvalidParameter(errors.Wrapf(err, "unable to parse server address"))
}
registryHostName = u.Host
}
// Lookup endpoints for authentication using "LookupPushEndpoints", which
// excludes mirrors to prevent sending credentials of the upstream registry
// to a mirror.
endpoints, err := service.LookupPushEndpoints(registryHostName)
if err != nil {
return nil, errdefs.InvalidParameter(err)
}
return endpoints, nil
}
// loginV2 tries to login to the v2 registry server. The given registry
// endpoint will be pinged to get authorization challenges. These challenges
// will be used to authenticate against the registry to validate credentials.
func loginV2(authConfig *types.AuthConfig, endpoint registry.APIEndpoint, userAgent string) (string, string, error) {
var (
endpointStr = strings.TrimRight(endpoint.URL.String(), "/") + "/v2/"
modifiers = registry.Headers(userAgent, nil)
authTransport = transport.NewTransport(newTransport(endpoint.TLSConfig), modifiers...)
credentialAuthConfig = *authConfig
creds = loginCredentialStore{authConfig: &credentialAuthConfig}
)
logrus.Debugf("attempting v2 login to registry endpoint %s", endpointStr)
loginClient, err := v2AuthHTTPClient(endpoint.URL, authTransport, modifiers, creds, nil)
if err != nil {
return "", "", err
}
req, err := http.NewRequest(http.MethodGet, endpointStr, nil)
if err != nil {
return "", "", err
}
resp, err := loginClient.Do(req)
if err != nil {
err = translateV2AuthError(err)
return "", "", err
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
return "Login Succeeded", credentialAuthConfig.IdentityToken, nil
}
// TODO(dmcgowan): Attempt to further interpret result, status code and error code string
return "", "", errors.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode))
}
// newTransport returns a new HTTP transport. If tlsConfig is nil, it uses the
// default TLS configuration.
func newTransport(tlsConfig *tls.Config) *http.Transport {
if tlsConfig == nil {
tlsConfig = tlsconfig.ServerDefault()
}
direct := &net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: direct.DialContext,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: tlsConfig,
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
DisableKeepAlives: true,
}
}
func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifiers []transport.RequestModifier, creds auth.CredentialStore, scopes []auth.Scope) (*http.Client, error) {
challengeManager, _, err := registry.PingV2Registry(endpoint, authTransport)
if err != nil {
return nil, err
}
tokenHandlerOptions := auth.TokenHandlerOptions{
Transport: authTransport,
Credentials: creds,
OfflineAccess: true,
ClientID: registry.AuthClientID,
Scopes: scopes,
}
tokenHandler := auth.NewTokenHandlerWithOptions(tokenHandlerOptions)
basicHandler := auth.NewBasicHandler(creds)
modifiers = append(modifiers, auth.NewAuthorizer(challengeManager, tokenHandler, basicHandler))
return &http.Client{
Transport: transport.NewTransport(authTransport, modifiers...),
Timeout: 15 * time.Second,
}, nil
}
func translateV2AuthError(err error) error {
switch e := err.(type) {
case *url.Error:
switch e2 := e.Err.(type) {
case errcode.Error:
switch e2.Code {
case errcode.ErrorCodeUnauthorized:
return errdefs.Unauthorized(err)
}
}
}
return err
}
func isNotAuthorizedError(err error) bool {
return strings.Contains(err.Error(), "401 Unauthorized")
}

View File

@@ -0,0 +1,42 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 docker
import (
"context"
"github.com/docker/cli/cli/config/configfile"
"oras.land/oras-go/pkg/auth"
)
// Logout logs out from a docker registry identified by the hostname.
func (c *Client) Logout(_ context.Context, hostname string) error {
hostname = resolveHostname(hostname)
var configs []*configfile.ConfigFile
for _, config := range c.configs {
if _, ok := config.AuthConfigs[hostname]; ok {
configs = append(configs, config)
}
}
if len(configs) == 0 {
return auth.ErrNotLoggedIn
}
// Log out form the primary config only as backups are read-only.
return c.primaryCredentialsStore(hostname).Erase(hostname)
}

View File

@@ -0,0 +1,86 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 docker
import (
"context"
"net/http"
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
ctypes "github.com/docker/cli/cli/config/types"
"github.com/docker/docker/registry"
iface "oras.land/oras-go/pkg/auth"
)
// Resolver returns a new authenticated resolver.
// Deprecated: use ResolverWithOpts
func (c *Client) Resolver(_ context.Context, client *http.Client, plainHTTP bool) (remotes.Resolver, error) {
return docker.NewResolver(docker.ResolverOptions{
Credentials: c.Credential,
Client: client,
PlainHTTP: plainHTTP,
}), nil
}
// ResolverWithOpts returns a new authenticated resolver with custom options.
func (c *Client) ResolverWithOpts(options ...iface.ResolverOption) (remotes.Resolver, error) {
settings := &iface.ResolverSettings{}
for _, option := range options {
option(settings)
}
return docker.NewResolver(docker.ResolverOptions{
Credentials: c.Credential,
Client: settings.Client,
PlainHTTP: settings.PlainHTTP,
Headers: settings.Headers,
}), nil
}
// Credential returns the login credential of the request host.
func (c *Client) Credential(hostname string) (string, string, error) {
hostname = resolveHostname(hostname)
var (
auth ctypes.AuthConfig
err error
)
for _, cfg := range c.configs {
auth, err = cfg.GetAuthConfig(hostname)
if err != nil {
// fall back to next config
continue
}
if auth.IdentityToken != "" {
return "", auth.IdentityToken, nil
}
if auth.Username == "" && auth.Password == "" {
// fall back to next config
continue
}
return auth.Username, auth.Password, nil
}
return "", "", err
}
// resolveHostname resolves Docker specific hostnames
func resolveHostname(hostname string) string {
switch hostname {
case registry.IndexHostname, registry.IndexName, registry.DefaultV2Registry.Host:
return registry.IndexServer
}
return hostname
}